精华内容
下载资源
问答
  • 听了讲引爆流行3个条件后,虽颇有收获,但总觉得有点高大上,具体落地实操还是有一定难度。一直问自己,有没有比较接地气、让产品火爆流行方法或技巧呢?无巧不成书,恰在此时公司培训部发了封内部邮件...

    听了讲的引爆流行的3个条件后,虽颇有收获,但总觉得有点高大上,具体落地实操还是有一定的难度。一直问自己,有没有比较接地气的、让产品火爆流行的方法或技巧呢?无巧不成书,恰在此时公司培训部发了一封内部邮件,将在公司范围内做了一场关于产品疯传的原则和技巧分享,这下乐坏了。

    产品总不瘟不火?获取用户成本高?用户数增长缓慢?碰到这样的问题,首先要思考一下是否产品出了问题,要知道产品是1,运营是0,这是前提条件。接下来开始产品疯传的7大原则,即STEKPPS原则,S代表Social currency (社交货币),也可以代表Showy(炫耀性);T代表Trigger(刺激诱因);E代表Emotion(情感性);K代表Key figure(意见领袖);P代表Public(公开性);P代表Practical(实用性);S代表Story(故事性)。

    1.社交货币
    现实生活中,金钱货币换来的是商品和服务,而社交货币换来的是存在感。存在感就是让别人知道还有你这样一号人物存在,让别人羡慕嫉妒恨,让别人显示出对你的尊敬和敬仰犹如滔滔江水连绵不绝。让你拥有会当凌绝顶,一览众山小的感觉。同时,是你在别人眼中获得积极的印象。微信朋友圈刷的不是文字、图片、小视频,刷的是存在感。曾经有一个形象的比喻,说每天看朋友圈就像一个皇帝上朝或批阅奏折一样,点赞、发表评论等等。
    存在感说得具体一点就是比别人更聪明、更有钱、更专业、更优秀、更有品位、更有面子、更惨等等。不妨试想一下,用户为什么要分享你的产品?分享你的产品有值得炫耀的资本吗?要让使用你的产品的用户对未使用你的产品的用户产生鄙视的感觉,要让那些未使用你的产品的用户争先恐后、想方设法想变成你的产品的用户。

    2.诱因刺激
    所谓诱因,其实就是刺激用户在某种场景下联想起产品、品牌的线索或者元素,这是用户分享传播的前奏,也就是说需要用户先联想起你的产品或品牌,然后才是用户要不要自发地分享、炫耀和传播。诱因刺激主要包括品牌连接物、寄生虫策略,以及刺激场景、广度、频率和强度:时间,刺激什么样的目标用户群?给顾客的线索越多,连接的强度就会越弱。需要非常清晰非常专一的连接,一看到就想起,诱导效果更明显。比如罗辑思维曾经搞过吃霸王餐的线下活动,很是火爆。粉丝用完餐后,还免费赠送了冈本的安全套。冈本本次赞助的安全套全都换成了红色装,美其名曰幸运套,放在钱包里能够带来好运。这个案例非常经典,“安全套+钱包”的组合不管是在刺激的场景、广度、频率还是强度方面,都具备相当的诱发效应,以后只要用户打开钱包,就会看到幸运套,一看到幸运套就会联想起霸王餐活动,罗辑思维关注的是长久性而非临时性传播。刺激场景、广度、频率和强度的案例还有很多,比如微信群里面的销售接龙、内容型社区里面的UGC接龙、网络流行语XXX文案体的接龙等等。这里有一个比较典型的例子,就是美拍,美拍App做了一个全民社会摇的线上活动(UGC接龙),吸引了100多万用户参与,引爆短视频社交!
    (1).品牌连接物:通过什么物品能够让用户想起你或你的产品。如果这个物品知名度比较高,更加能够让用户联想到你或你的产品,也就是我们常说的抱大腿傍大款。例如51talk在地铁投放的广告,广告中出现的人物是卡通漫画版的关羽,关羽在那学英语口语,广告口号:“在线学英语,到底哪家强?”这个案例的品牌连接物是什么?答案很明显,就是借用在中国家喻户晓的关二爷,抢占用户已有认知,降低认知成本,以后一看到或者想到关羽,就很容易联想起51talk。
    (2).寄生虫策略:利用竞争对手传播自己,这个策略基本上是不讲什么节操的,比如假的开心网利用真的开心网来传播自己,获取用户成本大大降低。这种方法至少是不道德的。这里之所以介绍只是告诉大家有这种方法,笔者极力反对采用这种方法。
    (3).刺激场景、广度、频率和强度:频率指的是多久一次联想到你;强度指的是一次刺激的持续时间长短;广度指的是你覆盖到多少用户群;场景指的是时间、地点、人物和事件。在什么地点,多久一次刺激,每次刺激多长。

    3.情感
    一款产品是否具备魅力或者魔力,很大程度上跟用户的情感有很大的关联。也就是说用户在使用产品或服务的时候,若能触发用户的情感,就能进一步引发用户的情感共鸣并进行分享传播。情感一般包括两种:
    (1).正面情感:敬畏、兴奋、幽默等,敬畏指的是惊讶、神奇和出乎意料,也就是我们常说的超出预期。敬畏之情的确能够增加人们的共享行为,让人敬畏的文章转载率比一般的文章要高出30%;兴奋指的是产品的尖叫点,比如微信的摇一摇;幽默解释起来比较简单,看看微博红人天才小熊猫创作的段子就知道了,而且幽默永远不会过时。
    (2).反面情感:生气、害怕、担忧等,只要我们经常关注一些新闻头条或者微博的热门话题,就不难找出引发用户生气、害怕、担忧的产品或负面事件,比如虐待动物事件、虚假融资事件等,这些事件传播非常快,而且不容易控制,经常需要专业的公关团队来救火。

    4.意见领袖
    纵观整个产品圈,很多产品的成功都离不开意见领袖、明星、大V的分享和传播,从某种程度上来说,得大V者得天下。我们常说的种子用户、达人也是意见领袖的一种。
    (1).1>N:当红明星转发、段子手调侃、意见领袖晒单引爆话题,一个人的一条信息的效果会远远大于多人多条信息。比如前段时间微博平台电商名人及草根大号抛出“双十一等酒”话题,之后某两位当红影星也发出“双十一等酒了”,互动微博名列热门微博榜第一。
    (2).关系链:关注社会传播属性和传播节点,比如“百度手机输入法微信活动,抽现金攒够5288送iPhone 6”,实际上就用到了“关系链+众筹+惊喜”的组合传播策略。

    5.公开性
    公开性指的是让产品公开可见。让产品在频率、强度和场景下获得更多的曝光,由不可见变成公开可见。产品或服务的公共可见性越强,它们对人们行为的激活程度就越高。三度影响力(态度、情绪、行为、观点会影响到朋友的朋友的朋友),容易从众,影响购买决策。
    例如,在微信朋友圈,我们经常看到某些好友发布一条状态,来源信息会显示“北京,来自iPhone 6 plus客户端”,这相当于把朋友使用什么样的手机信息公开可见了。再比如穿戴式设备、消费之后赠送的小礼物、包装等。我们经常看到的明星上门送快递,以及开着宝马、奔驰、特斯拉送产品或服务,这些都是公开性的具体表现。
    公开性是体现用户存在感的最佳途径。比如9158 App,当用户给某个美女主播赠送豪华礼物后,系统将推出一条通知,公开显示在每个聊天室用户都能看到的位置,并以走马灯形式循环展现。

    6.实用性
    实用性指的是更加方便、便宜,体验更好。要么方便、要么便宜,节省接收者的时间和金钱,帮助用户获得更佳体验。目前经常说的一键式功能,采用的就是极简设计,一学就会,都是在强调产品的实用性。若产品过于复杂、难用、体验差,则很难吸引并留住用户。

    7.故事性
    讲故事是一种最原始的娱乐形式。营销人员推送给顾客的事实往往很难让他们信服,但顾客往往会对其他顾客的购物故事深信不疑。人们一般都会关心故事的情节,却很少去思考这个故事本身的真实性。基于此,就可将产品故事化,而故事化经常跟人格化、情感化、游戏化紧密关联。
    (1).人格化:将人的特性赋予产品或服务,比如生鲜电商中每种食材的简历,要做得跟人的简历类似;
    (2).情感化:将产品作为用户的知心、贴心朋友,就像是朋友之间的对话、交互;
    (3).游戏化:产品好玩,史玉柱关于游戏的八字方针,荣耀、目标、互动和惊喜。

    最后,布置了一个作业,检验大家的学习成果。作业就是以火爆的小苹果为例,做一道连线题,即列举推广手段和策略,看对应7大原则中哪几个。推广手段和策略如下:
    A:把歌发给的哥,他们会放给乘客听;
    B:把歌拿到幼儿园,小孩子一学就会;
    C:专门请口音重或五音不全的人到唱吧翻唱;
    D:找网络红人到外滩跳《小苹果》;
    E:做40个视频,花上百万成本;
    F:官方MV中植入亚当、夏娃在伊甸园的故事;
    G:歌曲取名为“小苹果”。

    参加完培训后,就迫不及待地研究题目了,也跟其他产品同事讨论了一下,再综合老师的意见,得出的参考答案是:A对应诱因刺激、公开可见;B对应实用价值;C对应诱因刺激、情感共鸣;D对应意见领袖、公开可见;E对应社交货币、诱因刺激;F对应故事性;G对应诱因刺激。


    7大原则巧记:听老师讲了一个故事,深受刺激启发,决定把对产品的意见和建议公开化,就是主打社交媒体口碑营销,突出产品的实用价值,没想到引起同事们强烈的情感共鸣!

     

    转载于:https://www.cnblogs.com/SanMaoSpace/p/9439155.html

    展开全文
  • 文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。 文本检测不是一件...

    转自:https://www.cnblogs.com/skyfsm/p/9776611.html

    文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。

    文本检测不是一件简单的任务,尤其是复杂场景下的文本检测,非常具有挑战性。自然场景下的文本检测有如下几个难点:

    • 文本存在多种分布,文本排布形式多样;
    • 文本存在多个方向;
    • 多种语言混合。

    我们先从直观上理解文本检测任务。给定一张图片,我们需要找出这张图里文字出现的所有位置位置,那这个任务其实跟目标检测任务差别不大,即找出每个物体在图片中的位置,并标出该包围框里的物体的类别。而文本检测就是,找出每个文本在图片中出现的位置,因为我们的类别只有2个(有文字和没文字),看起来就像一个简单的单类别目标检测的任务,自然而然我们就会想到用经典的目标检测网络来进行文本检测,比如经典的Faster R-CNN。

    Faster RCNN

    Faster RCNN来做文本检测从任务上分析是可行的,毕竟文本说到底还是一个Object。我们回顾一下Faster RCNN做目标检测的关键步骤有哪些:

    1. 基础网络做特征提取;
    2. 特征送入RPN做候选框提取;
    3. 分类层对候选框内物体进行分类,回归层对候选框的(x,y,w,h)进行精细调整。

    Faster RCNN做文本检测感觉问题不大,但是从效果来看,仅套用Faster RCNN来做文本检测效果并不好,原因在于,文本有自己独有的特点,这种通用的文本检测框架并不能很好地解决文本的这些特点。那文本有什么特点呢?我总结如下:

    1. 文本大多数以长矩形形式存在,即长宽比一般较大或较小,这与普通的目标检测中的物体不一样(这些长宽比较接近1)
    2. 普通物体(比如猫)存在明显的闭合边缘轮廓,而文本没有;
    3. 文本中包含多个文字,而文字之间是有间隔的,如果检测做得不好,我们就会把每个字都当成文本行给框出来而非整行作为文本框,这与我们的期望不一样。

    基于以上文本检测的特点,我们必须对Faster RCNN这类通用网络进行改进,设计出适合文本检测的全新网络架构。

    CTPN(2016)

    2016年出了一篇很有名的文本检测的论文:《Detecting Text in Natural Image with
    Connectionist Text Proposal Network》,这个深度神经网络叫做CTPN,直到今天这个网络框架一直是OCR系统中做文本检测的一个常用网络,极大地影响了后面文本检测算法的方向。

    这个算法很有创新,我打算一步一步介绍其闪光点。我们回顾一下Faster RCNN做目标检测的一个缺点就是,没有考虑带文本自身的特点。文本行一般以水平长矩形的形式存在,而且文本行中每个字都有间隔。针对这个特点,CTPN提出一个新奇的想法,我们可以把文本检测的任务拆分,第一步我们检测文本框中的一部分,判断它是不是一个文本的一部分,当对一幅图里所有小文本框都检测之后,我们就将属于同一个文本框的小文本框合并,合并之后就可以得到一个完整的、大的文本框了,也就完成了文本的检测任务。这个想法真的很有创造性,有点像“分治法”,先检测大物体的一小部分,等所有小部分都检测出来,大物体也就可以检测出来了。

    如图所示,左边的图是直接使用Faster RCNN中的RPN来进行候选框提取,可以看出,这种候选框太粗糙了,效果并不好。而右图是利用许多小候选框来合并成一个大文本预测框,可以看出这个算法的效果非常不错,需要说明的是,红色框表示这个小候选框的置信度比较高,而其他颜色的候选框的置信度比较低,我们可以看到,一个大文本的边界都是比较难预测的,那怎么解决这个边界预测不准的问题呢?后面会提到。

    刚提到CTPN的其中一个闪光点,即检测小框代替直接检测大文本框。除了这个新意,CTPN还提出了在文本检测中应加入RNN来进一步提升效果。为什么要用RNN来提升检测效果?文本具有很强的连续字符,其中连续的上下文信息对于做出可靠决策来说很重要。我们知道RNN常用于序列模型,比如事件序列,语言序列等等,那我们CTPN算法中,把一个完整的文本框拆分成多个小文本框集合,其实这也是一个序列模型,可以利用过去或未来的信息来学习和预测,所以同样可以使用RNN模型。而且,在CTPN中,用的还是BiLSTM(双向LSTM),因为一个小文本框,对于它的预测,我们不仅与其左边的小文本框有关系,而且还与其右边的小文本框有关系!这个解释就很有说服力了,如果我们仅仅根据一个文本框的信息区预测该框内含不含有文字其实是很草率的,我们应该多参考这个框的左边和右边的小框的信息后(尤其是与其紧挨着的框)再做预测准确率会大大提升。

    如上图所示,如果我们单纯依靠1号框内的信息来直接预测1号框中否存在文字(或者说是不是文本的一部分),其实难度相当大,因为1号框只包含文字的很小一部分。但是如果我们把2号框和3号框的信息都用上,来预测1号框是否存在文字,那么我们就会有比较大的把握来预测1号框确实有文字。我们还可以看看为什么边缘的文本框的置信度会较中间的低呢?个人认为很大一部分原因就在于因为这些框都位于总文本的边缘,没有办法充分利用左右相邻序列的信息做预测(比如位于最左的文本框丢失了其右边的信息)。这就是双向LSTM的作用,把左右两个方向的序列信息都加入到学习的过程中去。

    我们已经对CTPN这个算法的总体思路有了一点理解,那关键问题来了,我们怎么把这些小文本框准确地检测出来呢?

    CTPN借助了Faster RCNN中anchor回归机制,使得RPN能有效地用单一尺寸的滑动窗口来检测多尺寸的物体。当然CTPN根据文本检测的特点做了比较多的创新。比如RPN中anchor机制是直接回归预测物体的四个参数(x,y,w,h),但是CTPN采取之回归两个参数(y,h),即anchor的纵向偏移以及该anchor的文本框的高度,因为每个候选框的宽度w已经规定为16个像素,不需要再学习,而x坐标直接使用anchor的x坐标,也不用学习,所以CTPN的思路就是只学习y和h这两个参数来完成小候选框的检测!跟RPN相类似,CTPN中对于每个候选框都使用了K个不同的anchors(k在这里默认是10),但是与RPN不同的是,这里的anchors的width是固定的16个像素,而height的高度范围为11~273(每次对输入图像的height除以0.7,一共K个高度)。当然CTPN中还是保留了RPN大多数的思路,比如还是需要预测候选框的分数score(该候选框有文本和无文本的得分)。

    这么多小尺度候选框怎么才能串联成一个完整的文本行呢?

    文本行构建很简单,通过将那些text/no-text score > 0.7的连续的text proposals相连接即可。文本行的构建如下。首先,为一个proposal Bi定义一个邻居(Bj):Bj−>Bi,其中:

    1. Bj在水平距离上离Bi最近
    2. 该距离小于50 pixels
    3. 它们的垂直重叠(vertical overlap) > 0.7

    另外,如果同时满足Bj−>Bi和Bi−>Bj,会将两个proposals被聚集成一个pair。接着,一个文本行会通过连续将具有相同proposal的pairs来进行连接来构建。

    接下来我们就较为细节地学习一下这个CTPN经典网络。

    首先CTPN的基础网络使用了VGG16用于特征提取,在VGG的最后一个卷积层CONV5,CTPN用了3×3的卷积核来对该feature map做卷积,这个CVON5 特征图的尺寸由输入图像来决定,而卷积时的步长却限定为16,感受野被固定为228个像素。卷积后的特征将送入BLSTM继续学习,最后接上一层全连接层FC输出我们要预测的参数:2K个纵向坐标y,2k个分数,k个x的水平偏移量。看到这里大家可能有个疑问,这个x的偏移到底是什么,为什么需要回归这个参数?如果需要X的参数,为什么不在候选框参数回归时直接预测成(x,y,h)三个参数呢,而要多此一举把该参数单独预测?这个X的作用作者提到这也是他们论文的一大亮点,称之为Side-refinement,我理解为文本框边缘优化。我们回顾一下上面提到的一个问题,文本框检测中边缘部分的预测并不准确。那么改咋办,CTPN就是用这个X的偏移量来精修边缘问题。这个X是指文本框在水平方向的左边界和右边界,我们通过回归这个左边界和右边界参数进而可以使得我们对文本框的检测更为精准。在这里想举个例子说明一下回归这个x参数的重要性。

    我们观察下图,第一幅图张我们看到我们有很多小候选框,位于左边的候选框我标记为1、2、3、4号框,1号框和2号框为蓝色,表明得分不高我们不把这两个框合并到大文本框内,对于3号框和4号框那就比较尴尬了,如果取3号框作为文本框的边缘框,那么显然左边边缘留白太多,精准度不够,但如果去掉3号框而使用4号框作为左边缘框,则有些字体区域没有检测出来,同样检测精度不足。这种情况其实非常容易出现,所以CTPN采取了Side-refinement 思路进一步优化边缘位置的预测即引入回归X参数,X参数直接标定了完整文本框的左右边界,做到精确的边界预测。第二幅图中的红色框就是经过Side-refinement后的检测结果,可以看出检测准确率有了很大的提升。 side-refinement确实可以进一步提升位置准确率,在SWT的Multi-Lingual datasets上产生2%的效果提升。

    再看多几幅图,体验一下Side-refinement后的效果。

    最后总结一下CTPN这个流行的文本检测框架的三个闪光点:

    • 将文本检测任务转化为一连串小尺度文本框的检测;
    • 引入RNN提升文本检测效果;
    • Side-refinement(边界优化)提升文本框边界预测精准度。

    当然,CTPN也有一个很明显的缺点:对于非水平的文本的检测效果并不好。CTPN论文中给出的文本检测效果图都是文本位于水平方向的,显然CTPN并没有针对多方向的文本检测有深入的探讨。那对于任意角度的文本检测应该采取什么的算法思路呢?下面的SegLink算法给出了一个新奇的解决方案。

    SegLink(2017)

    CVPR2017的一篇spotlight论文《Detecting Oriented Text in Natural Images by Linking Segments》介绍以一种可以检测任意角度文本的检测算法,我们一般称这个算法为SegLink,这篇论文既融入CTPN小尺度候选框的思路又加入了SSD算法的思路,达到了当时自然场景下文本检测state-of-art的效果。

    现在我想先介绍为什么要针对多方向的文本检测做特定的研究。对于普通目标检测,我们并不需要对其做所谓的多方向目标检测,比如下面这个检测任务,我们直接把单车和狗的位置找出来即可。

    但是对于文本检测任务可不一样,文本的特点就是高宽比特别大或小,而且文本通常存在一定的旋转角度,如果我们对于带角度的文本仍然使用目标检测那个思路回归四个参数(x,y,w,h)来指定一个目标的位置的话(如下图红色框),那显然误差太大了,这个检测效果并不是我们所能接受的。作为对比,下图的绿色框的检测效果才是我们的终极目标。那么怎么基于原来经典的目标检测算法做相应的优化以适应这种检测效果的要求呢?

    一个最直接的思路就是让模型再学习一个参数θ!这个θ表示文本框的旋转角度,也就是我们最终要回归的参数从原来的(x,y,w,h)变成(x,y,w,h,θ)。SegLink确实也采取了这个思路,除此之外,他还提出了Segment和Linking两个重要概念,这个才是这篇CVPR论文的核心创新点。

    什么是segment?segment从中文上理解为文本行的一部分,这一部分可以是一个字符或文本行的任意一部分。如下图示,黄色框表示一个segment,一个完整的文本行中包含多个segment,每个sgment之间通过link(图中的绿色线)连接组合起来。那么Segment做文本检测的思路其实跟CTPN的思路很像,先检测文本行的一部分,再把他们连接起来构成一个完整文本行。

    我们把图片的关键部位放大看看细节:首先每个segment是有一定的重合区域的,然后每两个segment连接的部位是两个segment的中心点。每一个segment和link仅依靠局部图像的纹理信息即可完成检测,而无需整张图像的信息。

    接下来我们通过分析SegLink的网络架构进一步理解SegLink如何做到高效的多角度文本检测。下图是SegLink的网络架构,显然这个架构采取了SSD的思路,首先使用VGG16作为backbone进行特征提取,其中VGG16的全连接层(fc6,fc7)替换成卷积层(conv6,conv7),再接卷积层conv8到conv11。值得说明的是,conv4~conv11之间的尺寸依次减少(每一层是前一层的1/2)。这个做法是为了做多尺度下的目标检测,即大的feature map擅长做小物体的检测,而小的feature map则擅长检测大物体。借助多个不同尺度的feature map,从6个feature layer上检测segment和link,我们就可以检测出不同尺寸的文本行了。

    观察后面的卷积层可以发现,对不同层的feature map使用3×3的卷积层产生最终的输出(包括segment和link),不同特征层输出的维度是不一样的,因为除了conv4_3层外,其它层存在跨层的link。这里segment是text的带方向bbox信息(它可能是个单词,也可能是几个字符,总之是文本行的部分),link是不同segment的连接信息(文章将其也增加到网络中自动学习)。

    当所有segments都被检测出来后,我们就可以通过融合规则(combining segments),将各个feature map的segment的box信息和link信息进行融合,得到最终的文本行。

    SegLink所使用的目标函数由三个部分构成,是否是text的二类分类的softmax损失,box的smooth L1 regression损失,是否link的二类的softmax损失。λ1和λ2控制权重,最后都设为1。

    现在计算一下每个feature map输出的参数有哪些呢?

    • segment的位置信息:(x,y,w,h,θ),一共5个参数
    • 每个segment内的分类分数,即判断框内有字符还是无字符的分数(2分类),共2个参数
    • 同层(within-layer)的每个segment的link的分数,表示该方向有link还是没link(2分类问题),而一个segment有八邻域所以有八个方向,参数一共有2×8=16
    • 相邻层(cross-layer)之间也存在link,同样是该方向有link还是没link(2分类问题),而link的个数是4个,所以参数总数为2×4=8

    下图很清楚地表示出每个feature map输出的参数有多少个,输出参数总数为(2+5+16+8=31)。假设当前的feature map的尺度为(w,h),那么该层卷积后输出为w×h×31。

    这里想再谈谈Within-Layer Link和Cross-Layer Link的作用。

    within-layer link表示在同一层feature layer里,每个Segment与8邻域内的segment的连接状况,如下图(a)所示。且每个link有2维,一维是正分,表示两个segment属于同一文本,一维是负分,表示两个segment不属于同一文本。所以,每个predictor输出16(8×2)维向量。

    cross-layer link:在不同的feature layer上有可能会检测到同一文本的segments,造成冗余,cross-layer link的提出就是为了解决这个问题。cross-layer link连接了两个相邻feature layer上的segments,如图(b)所示。需要注意的是,由于下采样使后一层为前一层scale的1/2,定义一个segment的cross-layer邻居为前一层4邻域更小的segment,即前一层是后一层的邻居,但后一层不是前一层的邻居,所以conv4_3的feature layer没有cross-layer邻居。图中所示的黄框为当前层的segment,蓝框为上一层更小更细的segment,绿色的线代表cross-layer link有连接,属于同一文本,在后续的combine算法中会将他们融合,即去除了冗余。

    读到这里我们已经知道如何获取segment和相应的link了,那接下来要做的就是怎么把这些link和segment合并成一个完整的文本行。先贴一下论文中使用到的合并算法:

    看起来真的是头都大,其实思想很简单,我尝试用中文解释一下:

    1. 假设我们有一个集合B,里面有很多相关联的segment待合并;
    2. 每一个segment都有自己的角度θ,那我们求集合B中所有segment角度的平均值θb;
    3. 求一条直线L使得所有segment的中心到这条直线的距离最小,也就是最小二乘法线性回归啦;
    4. 每个segment的中心往直线L做垂直投影;
    5. 从所有投影点中选出相距最远的两个点,记做(xp,yp)和(xq,yq);
    6. 最终合并好的文本框的位置参数记为(xb,yb,wb,hb,θb)那么xb:=1/2(xp+xq),yb:=1/2(yp+yq)y
    7. 文本行的宽度wb就是两个最远点的距离(即(xp,yp)和(xq,yq))再加上最远两个点所处的segment的宽度的一半(Wp和Wq)。
    8. 文本行高度hb就是所有segment高度求平均值

    我画了下图辅助理解合并算法,橙色直线是拟合出的最佳直线,红色点表示segment的中心,黄点表示红点在直线上的投影,绿框就是合并后的完整本文框。

    这样子我们就求解完一个完整文本框的所有参数,也就完成了segment合并成文本行的任务。

    SegLink算法对于各种角度的文本检测具有很强的鲁棒性。

    SegLink论文中并没有提到该算法能不能检测弯曲的文本,从理论上解读,SegLink是可以做到的。比如下图,只是合并算法要做一些改变而已。

    EAST(2017)

    对于以上把完整文本行先分割检测再合并的思路,有人提出质疑,觉得这种做法比较麻烦,把文本检测切割成多个阶段来进行,这无疑增大了文本检测精度的损失和时间的消耗,对于文本检测任务上中间处理越多可能效果越差。所以有篇CVPR2017的文章提出,我们有一种方法能优雅且简洁地完成多角度文本检测,这个算法叫做EAST,论文为《EAST: An Efficient and Accurate Scene Text Detector》。

    通过下图我们知道,一个文本检测有多个阶段,就以region proposals系的检测算法为例,他们通常包含候选框提取、候选框过滤、bouding box回归、候选框合并等阶段,EAST的作者认为,一个文本检测算法被拆分成多个阶段其实并没有太多好处,实现真正端到端的文本检测网络才是正确之举。所以EAST的pipeline相当优雅,只分为FCN生成文本行参数阶段和局部感知NMS阶段,网络的简洁是的检测的准确性和速度都有了进一步的提高。

    我们从网络架构来理解EAST做文本检测的优势。首先EAST采取了FCN的思路,一开始我以为EAST是一个通过语义分割来解决文本检测的难题,深入阅读后才发现并不是,而只是借助了FCN的架构做特征提取和学习,最终还是一个回归问题,在EAST最后预测出相应的文本行参数。

    EAST网络分为特征提取层+特征融合层+输出层三大部分。

    特征提取层: backbone采取PVANet来做特征提取,接下来送入卷积层,而且后面的卷积层的尺寸依次递减(size变为上一层的一半),而且卷积核的数量依次递增(是前一层的2倍)。抽取不同level的feature map,这样可以得到不同尺度的特征图,目的是解决文本行尺度变换剧烈的问题,size大的层可用于预测小的文本行,size小的层可用于预测大的文本行。

    特征合并层,将抽取的特征进行merge.这里合并的规则采用了U-net的方法,合并规则:从特征提取网络的顶部特征按照相应的规则向下进行合并,这里描述可能不太好理解,具体参见下述的网络结构图。

    网络输出层:网络的最终输出有5大部分,他们分别是:

    • score map:一个参数,表示这个预测框的置信度;
    • text boxes: 4个参数,(x,y,w,h),跟普通目标检测任务的bounding box参数一样,表示一个物体的位置;
    • text rotation angle: 1个参数,表示text boxe的旋转角度;
    • text quadrangle coordinates:8个参数,表示任意四边形的四个顶点坐标,即(x1,y1),(x2,y2),(x3,y3),(x4,y4)。

    所以从整体看来,EAST就是借助FCN架构直接回归出文本行的(x,y,w,h,θ)+置信度+四边形的四个坐标!非常简洁!但是看到这里或许会有个问题,为什么要生成四边形的四个坐标呢?(x,y,w,h,θ)这个参数不足以解决文本行定位问题?还真不能,看看下面这个图片。

    对于这种带放射变换的文本行(可能还有的是透视变换),呈现出来的形状是平行四边形(黄色虚线为ground true),如果我们以(x,y,w,h,θ)来表示这个文本的位置,就是粉色框所示,显然不合适。所以对于这种场合,直接预测四边形的四个顶点坐标才是正确之举。

    EAST目标函数分两部分,如下,第一部分是分类误差,第二部分是几何误差,文中权衡重要性,λg=1。

    Ls称为分类误差函数
    ,采用 class-balanced cross-entropy,这样做可以很实用的处理正负样本不均衡的问题。

    其中β=反例样本数量/总样本数量 (balance factor)

    Lg为几何误差函数

    对于RBOX,采用IoU loss

    角度误差则为:

    对于QUAD采用smoothed L1 loss
    CQ={x1,y1,x2,y2,x3,y3,x4,y4},NQ*指的是四边形最短边的长度

    下面看看EAST文本检测的效果,注意观察一些带放射变换or透视变换的文本行的检测效果。

    总结

    文本介绍了我一直关注且实验效果都相当不错的三个经典的文本检测算法,他们都是基于深度学习,可以这么说,现在做文本检测都是深度学习的天下了。当然深度学习流派做文本检测远不止以上几个思路,比如基于语义分割的思路做文本检测的、基于角点检测做文本检测、各种方法混合的文本检测的论文也非常多,同时也取得非常不错的效果。可以说,现在基于深度学习的文本检测论文可谓百花齐放。

     

    展开全文
  • 3.3 持续集成的前提条件 46 3.3.1 频繁提交 46 3.3.2 创建全面的自动化测试 套件 47 3.3.3 保持较短的构建和测试 过程 47 3.3.4 管理开发工作区 49 3.4 使用持续集成软件 49 3.4.1 基本操作 49 ...
  • 持续交付-发布可靠软件系统方法

    热门讨论 2014-03-02 01:32:14
    3.3 持续集成的前提条件 46 3.3.1 频繁提交 46 3.3.2 创建全面的自动化测试套件 47 3.3.3 保持较短的构建和测试过程 47 3.3.4 管理开发工作区 49 3.4 使用持续集成软件 49 3.4.1 基本操作 49 3.4.2 铃声和...
  • 最大权闭合图

    2019-09-27 23:45:53
    一件事件x发生需要一个条件: 1. y事件已经发生 2. z事件已经发生 对于这样依赖关系 , 我们可以用闭合来来描述或者解决 有向图闭合图(closure)(来源于 胡伯涛《最小割模型在信息学竞赛中应用》 论文 ...

    前置芝士:最大流最小割

    一. 啥是闭合图

    一件事件x发生需要一个条件:

    1. y事件已经发生

    2. z事件已经发生

    对于这样的依赖关系 , 我们可以用闭合来来描述或者解决

    有向图的闭合图(closure)(来源于 胡伯涛《最小割模型在信息学竞赛中的应用》 论文 )

    物理意义:事物间依赖关系:一个事件要发生 , 她需要的所有前提也都一定发生

    最大权闭合图是点权最大的闭合图

    例题:[NOI2006]最大获利

     一道求最大权闭合图的题

    构图:

    建源点S, 汇点T

    将源点S与正权点连边 , 容量是点权

    将汇点T与负权点连边 , 容量是点权

    将题目描述的边连上 , 容量是无限大

     

    解决:

    闭合图的权为所有正权点减去该图中割的容量

    那么 , 很显然割越小答案越大

    所以就要去求最小鸽 , 也就是最大流

     这样 , 那道NOI题也就好做了

      1 #include<cstdio>
      2 #include<queue>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<iostream>
      6 #include<algorithm>
      7 #define APART puts("----------------------")
      8 #define debug 1
      9 #define FILETEST 0
     10 #define inf 120010
     11 #define ll long long
     12 #define ha 998244353
     13 #define INF 0x7fffffff
     14 #define INF_T 9223372036854775807
     15 #define DEBUG printf("%s %d\n",__FUNCTION__,__LINE__)
     16 
     17 namespace chino{
     18 
     19 inline void setting(){
     20 #if FILETEST
     21     freopen("test.in", "r", stdin);
     22     freopen("test.me.out", "w", stdout);
     23 #endif
     24     return;
     25 }
     26 
     27 inline int read(){
     28     char c = getchar(), up = c; int num = 0;
     29     for(; c < '0' || c > '9'; up = c, c = getchar());
     30     for(; c >= '0' && c <= '9'; num = (num << 3) + (num << 1) + (c ^ '0'), c = getchar());
     31     return  up == '-' ? -num : num;
     32 }
     33 
     34 int n, m;
     35 int S, T;
     36 int maxflow, anssum;
     37 int cntE = -1;
     38 int head[inf];
     39 int cur[inf];
     40 int dep[inf];
     41 struct Edge{
     42     int to;
     43     int flow;
     44     int next;
     45 }e[inf << 1];
     46 std::queue <int> Q;
     47 
     48 inline void AddEdge(int from, int to, int flow){
     49     ++cntE;
     50     e[cntE].to = to;
     51     e[cntE].flow = flow;
     52     e[cntE].next = head[from];
     53     head[from] = cntE;
     54     return;
     55 }
     56 
     57 inline bool BFS(int s, int t){
     58     memset(dep, -1, sizeof dep);
     59     memcpy(cur, head, sizeof cur);
     60     while(!Q.empty())
     61         Q.pop();
     62     Q.push(s);
     63     dep[s] = 0;
     64     while(!Q.empty()){
     65         int x = Q.front();
     66         Q.pop();
     67         for(int i = head[x]; i ^ -1; i = e[i].next){
     68             int y = e[i].to;
     69             if(dep[y] == -1 && e[i].flow){
     70                 dep[y] = dep[x] + 1;
     71                 Q.push(y);
     72             }
     73         }
     74     }
     75     return dep[t] ^ -1;
     76 }
     77 
     78 int DFS(int s, int limit){
     79     if(limit == 0 || s == T)
     80         return limit;
     81     int flow = 0;
     82     int f = 0;
     83     for(int i = cur[s]; i ^ -1; i = e[i].next){
     84         cur[s] = i;
     85         int to = e[i].to;
     86         int Min = std::min(limit, e[i].flow);
     87         if(dep[to] == dep[s] + 1 && (f = DFS(to, Min))){
     88             flow += f;
     89             limit -= f;
     90             e[i].flow -= f;
     91             e[i ^ 1].flow += f;
     92             if(limit == 0)
     93                 break;
     94         }
     95     }
     96     return flow;
     97 }
     98 
     99 inline void dinic(int s, int t){
    100     while(BFS(s, t))
    101         maxflow += DFS(s, INF);
    102     return;
    103 }
    104 
    105 inline int main(){
    106     memset(head, -1, sizeof head);
    107     n = read();
    108     m = read();
    109     S = n + m + 1;
    110     T = n + m + 2;
    111     for(int i = 1; i <= n; i++){
    112         int tmp = read();
    113         AddEdge(i + m, T, tmp);
    114         AddEdge(T, i + m, 0);
    115     }
    116     for(int i = 1; i <= m; i++){
    117         int a = read();
    118         int b = read();
    119         int v = read();
    120         anssum += v;
    121         AddEdge(i, a + m, INF >> 1);
    122         AddEdge(a + m, i, 0);
    123         
    124         AddEdge(i, b + m, INF >> 1);
    125         AddEdge(b + m, i, 0);
    126         
    127         AddEdge(S, i, v);
    128         AddEdge(i, S, 0);
    129     }
    130     dinic(S, T);
    131     printf("%d\n", anssum - maxflow);
    132     return 0;
    133 }
    134 
    135 }//namespace chino
    136 
    137 int main(){return chino::main();}

     例题2:luogu太空飞行计划问题

    题意重点:每个仪器在购买后可以用无限次

    并不是说一个实验收入是负数就不要做这个实验

    如题目样例

    有些实验可能是给后面的实验买仪器 , 可能这个实验不赚钱 , 但是后面的实验不需要买仪器了 , 那这个方案可能更优\

     

    不难看出也是一道最大权闭合图题 , 所以建图就是如之前一样了

    那么怎么样输出方案呐

    因为最小鸽C[S,T]将图G分成没有交的两个点集S和T

    而答案就是集合S里所有的点

    为什么?

    因为这张图中间的边的边权是无限大 , 所以这些边永远不会在鸽里面

    所以其实鸽就是在选择剩下的两种边----S连向实验 和 仪器连向T

    选择连接实验的边就等于说不选这个实验

    而选择仪器的边就等于说选这个实验

    另外怎么样去判断在S集合的点呐?

    再搜一遍?

    dinic的BFS返回false的条件就是无法遍历到T , 所以最后一遍BFS后dep不是初始值的点就是与S联通的

      1 #include<cmath>
      2 #include<queue>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<iostream>
      7 #include<algorithm>
      8 #define APART puts("----------------------")
      9 #define debug 1
     10 #define FILETEST 0
     11 #define inf 1010
     12 #define ll long long
     13 #define ha 998244353
     14 #define INF 0x7fffffff
     15 #define INF_T 9223372036854775807
     16 #define DEBUG printf("%s %d\n",__FUNCTION__,__LINE__)
     17 
     18 namespace chino{
     19 
     20 inline void setting(){
     21 #if FILETEST
     22     freopen("test.in", "r", stdin);
     23     freopen("test.me.out", "w", stdout);
     24 #endif
     25     return;
     26 }
     27 
     28 inline int read(int &num){
     29     num = 0; char c = getchar(), up = c;
     30     for(; c < '0' || c > '9'; up = c, c = getchar());
     31     for(; c >= '0' && c <= '9'; num = (num << 3) + (num << 1) + (c ^ '0'), c = getchar());
     32     if(up == '-') num = -num;
     33     return c == '\r' || c == '\n';
     34 }
     35 
     36 int n, m;
     37 int cntE = -1;
     38 int S, T;
     39 int maxflow, anssum;
     40 int head[inf];
     41 int cur[inf];
     42 int dep[inf];
     43 struct Edge{
     44     int to;
     45     int flow;
     46     int next;
     47 }e[inf << 1];
     48 std::queue <int> Q;
     49 
     50 inline void AddEdge(int from, int to, int val){
     51 //    printf("AddEdge: x = %d, y = %d, val = %d\n", from, to, val);
     52     ++cntE;
     53     e[cntE].to = to;
     54     e[cntE].flow = val;
     55     e[cntE].next = head[from];
     56     head[from] = cntE;
     57     return;
     58 }
     59 
     60 inline bool BFS(int s, int t){
     61     memset(dep, -1, sizeof dep);
     62     memcpy(cur, head, sizeof cur);
     63     while(!Q.empty())
     64         Q.pop();
     65     dep[s] = 0;
     66     Q.push(s);
     67     while(!Q.empty()){
     68         int x = Q.front();
     69         Q.pop();
     70         for(int i = head[x]; i ^ -1; i = e[i].next){
     71             int y = e[i].to;
     72             if(dep[y] == -1 && e[i].flow){
     73                 dep[y] = dep[x] + 1;
     74                 Q.push(y);
     75             }
     76         }
     77     }
     78     return dep[t] ^ -1;
     79 }
     80 
     81 int DFS(int s, int limit){
     82     if(limit == 0 || s == T)
     83         return limit;
     84     int flow = 0;
     85     int f = 0;
     86     for(int i = cur[s]; i ^ -1; i = e[i].next){
     87         int to = e[i].to;
     88         int Min = std::min(limit, e[i].flow);
     89         cur[s] = i;
     90         if(dep[s] == dep[to] - 1 && (f = DFS(to, Min))){
     91             flow += f;
     92             limit -= f;
     93             e[i].flow -= f;
     94             e[i ^ 1].flow += f;
     95             if(limit == 0)
     96                 break;
     97         }
     98     }
     99     return flow;
    100 }
    101 
    102 inline void dinic(int s, int t){
    103     while(BFS(s, t))
    104         maxflow += DFS(s, INF);
    105     return;
    106 }
    107 
    108 inline int main(){
    109     memset(head, -1, sizeof head);
    110     read(n);
    111     read(m);
    112     S = n + m + 1;
    113     T = n + m + 2; 
    114     for(int i = 1; i <= n; i++){
    115         int val;
    116         if(read(val)){
    117             anssum += val;
    118             AddEdge(S, i, val);
    119             AddEdge(i, S, 0);
    120             continue;
    121         }
    122         anssum += val;
    123         AddEdge(S, i, val);
    124         AddEdge(i, S, 0);
    125         while(read(val) == 0){
    126             AddEdge(i, val + n, INF >> 1);
    127             AddEdge(val + n, i, 0);
    128         }
    129         AddEdge(i, val + n, INF >> 1);
    130         AddEdge(val + n, i, 0);
    131     }
    132     for(int i = 1; i <= m; i++){
    133         int tmp;
    134         read(tmp);
    135         AddEdge(i + n, T, tmp);
    136         AddEdge(T, i + n, 0);
    137     }
    138     dinic(S, T);
    139     for(int i = 1; i <= n; i++){
    140         if(dep[i] ^ -1)
    141             printf("%d ", i);
    142     } puts("");
    143     for(int i = n + 1; i <= n + m; i++){
    144         if(dep[i] ^ -1)
    145             printf("%d ", i - n);
    146     } puts("");
    147     printf("%d\n", anssum - maxflow);
    148     return 0;
    149 }
    150 
    151 }//namespace chino
    152 
    153 int main(){return chino::main();}

     

    转载于:https://www.cnblogs.com/chiarochinoful/p/algorithm-closure.html

    展开全文
  • 文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。 文本检测不是一件...

    文章转载自:https://www.cnblogs.com/skyfsm/p/9776611.html

    前言

    文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。

    文本检测不是一件简单的任务,尤其是复杂场景下的文本检测,非常具有挑战性。自然场景下的文本检测有如下几个难点:

    • 文本存在多种分布,文本排布形式多样;
    • 文本存在多个方向;
    • 多种语言混合。
      在这里插入图片描述

    我们先从直观上理解文本检测任务。给定一张图片,我们需要找出这张图里文字出现的所有位置位置,那这个任务其实跟目标检测任务差别不大,即找出每个物体在图片中的位置,并标出该包围框里的物体的类别。而文本检测就是,找出每个文本在图片中出现的位置,因为我们的类别只有2个(有文字和没文字),看起来就像一个简单的单类别目标检测的任务,自然而然我们就会想到用经典的目标检测网络来进行文本检测,比如经典的Faster R-CNN。
    在这里插入图片描述

    Faster RCNN

    Faster RCNN来做文本检测从任务上分析是可行的,毕竟文本说到底还是一个Object。我们回顾一下Faster RCNN做目标检测的关键步骤有哪些:

    1. 基础网络做特征提取;
    2. 特征送入RPN做候选框提取;
    3. 分类层对候选框内物体进行分类,回归层对候选框的(x,y,w,h)进行精细调整。

    Faster RCNN做文本检测感觉问题不大,但是从效果来看,仅套用Faster RCNN来做文本检测效果并不好,原因在于,文本有自己独有的特点,这种通用的文本检测框架并不能很好地解决文本的这些特点。那文本有什么特点呢?我总结如下:

    1. 文本大多数以长矩形形式存在,即长宽比一般较大或较小,这与普通的目标检测中的物体不一样(这些长宽比较接近1)
    2. 普通物体(比如猫)存在明显的闭合边缘轮廓,而文本没有;
    3. 文本中包含多个文字,而文字之间是有间隔的,如果检测做得不好,我们就会把每个字都当成文本行给框出来而非整行作为文本框,这与我们的期望不一样。
      基于以上文本检测的特点,我们必须对Faster RCNN这类通用网络进行改进,设计出适合文本检测的全新网络架构。

    CTPN(2016)

    2016年出了一篇很有名的文本检测的论文:《Detecting Text in Natural Image with
    Connectionist Text Proposal Network》,这个深度神经网络叫做CTPN,直到今天这个网络框架一直是OCR系统中做文本检测的一个常用网络,极大地影响了后面文本检测算法的方向。

    这个算法很有创新,我打算一步一步介绍其闪光点。我们回顾一下Faster RCNN做目标检测的一个缺点就是,没有考虑带文本自身的特点。文本行一般以水平长矩形的形式存在,而且文本行中每个字都有间隔。针对这个特点,CTPN剔除一个新奇的想法,我们可以把文本检测的任务拆分,第一步我们检测文本框中的一部分,判断它是不是一个文本的一部分,当对一幅图里所有小文本框都检测之后,我们就将属于同一个文本框的小文本框合并,合并之后就可以得到一个完整的、大的文本框了,也就完成了文本的检测任务。这个想法真的很有创造性,有点像“分治法”,先检测大物体的一小部分,等所有小部分都检测出来,大物体也就可以检测出来了。
    在这里插入图片描述
    如图所示,左边的图是直接使用Faster RCNN中的RPN来进行候选框提取,可以看出,这种候选框太粗糙了,效果并不好。而右图是利用许多小候选框来合并成一个大文本预测框,可以看出这个算法的效果非常不错,需要说明的是,红色框表示这个小候选框的置信度比较高,而其他颜色的候选框的置信度比较低,我们可以看到,一个大文本的边界都是比较难预测的,那怎么解决这个边界预测不准的问题呢?后面会提到。

    刚提到CTPN的其中一个闪光点,即检测小框代替直接检测大文本框。除了这个新意,CTPN还提出了在文本检测中应加入RNN来进一步提升效果。为什么要用RNN来提升检测效果?文本具有很强的连续字符,其中连续的上下文信息对于做出可靠决策来说很重要。我们知道RNN常用于序列模型,比如事件序列,语言序列等等,那我们CTPN算法中,把一个完整的文本框拆分成多个小文本框集合,其实这也是一个序列模型,可以利用过去或未来的信息来学习和预测,所以同样可以使用RNN模型。而且,在CTPN中,用的还是BiLSTM(双向LSTM),因为一个小文本框,对于它的预测,我们不仅与其左边的小文本框有关系,而且还与其右边的小文本框有关系!这个解释就很有说服力了,如果我们仅仅根据一个文本框的信息区预测该框内含不含有文字其实是很草率的,我们应该多参考这个框的左边和右边的小框的信息后(尤其是与其紧挨着的框)再做预测准确率会大大提升。
    在这里插入图片描述
    如上图所示,如果我们单纯依靠1号框内的信息来直接预测1号框中否存在文字(或者说是不是文本的一部分),其实难度相当大,因为1号框只包含文字的很小一部分。但是如果我们把2号框和3号框的信息都用上,来预测1号框是否存在文字,那么我们就会有比较大的把握来预测1号框确实有文字。我们还可以看看为什么边缘的文本框的置信度会较中间的低呢?个人认为很大一部分原因就在于因为这些框都位于总文本的边缘,没有办法充分利用左右相邻序列的信息做预测(比如位于最左的文本框丢失了其右边的信息)。这就是双向LSTM的作用,把左右两个方向的序列信息都加入到学习的过程中去。
    在这里插入图片描述
    我们已经对CTPN这个算法的总体思路有了一点理解,那关键问题来了,我们怎么把这些小文本框准确地检测出来呢?

    CTPN借助了Faster RCNN中anchor回归机制,使得RPN能有效地用单一尺寸的滑动窗口来检测多尺寸的物体。当然CTPN根据文本检测的特点做了比较多的创新。比如RPN中anchor机制是直接回归预测物体的四个参数(x,y,w,h),但是CTPN采取之回归两个参数(y,h),即anchor的纵向偏移以及该anchor的文本框的高度,因为每个候选框的宽度w已经规定为16个像素,不需要再学习,而x坐标直接使用anchor的x坐标,也不用学习,所以CTPN的思路就是只学习y和h这两个参数来完成小候选框的检测!跟RPN相类似,CTPN中对于每个候选框都使用了K个不同的anchors(k在这里默认是10),但是与RPN不同的是,这里的anchors的width是固定的16个像素,而height的高度范围为11~273(每次对输入图像的height除以0.7,一共K个高度)。当然CTPN中还是保留了RPN大多数的思路,比如还是需要预测候选框的分数score(该候选框有文本和无文本的得分)。

    这么多小尺度候选框怎么才能串联成一个完整的文本行呢?

    文本行构建很简单,通过将那些text/no-text score > 0.7的连续的text proposals相连接即可。文本行的构建如下。首先,为一个proposal Bi定义一个邻居(Bj):Bj−>Bi,其中:

    1. Bj在水平距离上离Bi最近
    2. 该距离小于50 pixels
    3. 它们的垂直重叠(vertical overlap) > 0.7

    另外,如果同时满足Bj−>Bi和Bi−>Bj,会将两个proposals被聚集成一个pair。接着,一个文本行会通过连续将具有相同proposal的pairs来进行连接来构建。

    接下来我们就较为细节地学习一下这个CTPN经典网络。
    在这里插入图片描述
    首先CTPN的基础网络使用了VGG16用于特征提取,在VGG的最后一个卷积层CONV5,CTPN用了3×3的卷积核来对该feature map做卷积,这个CVON5 特征图的尺寸由输入图像来决定,而卷积时的步长却限定为16,感受野被固定为228个像素。卷积后的特征将送入BLSTM继续学习,最后接上一层全连接层FC输出我们要预测的参数:2K个纵向坐标y,2k个分数,k个x的水平偏移量。看到这里大家可能有个疑问,这个x的偏移到底是什么,为什么需要回归这个参数?如果需要X的参数,为什么不在候选框参数回归时直接预测成(x,y,h)三个参数呢,而要多此一举把该参数单独预测?这个X的作用作者提到这也是他们论文的一大亮点,称之为Side-refinement,我理解为文本框边缘优化。我们回顾一下上面提到的一个问题,文本框检测中边缘部分的预测并不准确。那么改咋办,CTPN就是用这个X的偏移量来精修边缘问题。这个X是指文本框在水平方向的左边界和右边界,我们通过回归这个左边界和右边界参数进而可以使得我们对文本框的检测更为精准。在这里想举个例子说明一下回归这个x参数的重要性。

    我们观察下图,第一幅图张我们看到我们有很多小候选框,位于左边的候选框我标记为1、2、3、4号框,1号框和2号框为蓝色,表明得分不高我们不把这两个框合并到大文本框内,对于3号框和4号框那就比较尴尬了,如果取3号框作为文本框的边缘框,那么显然左边边缘留白太多,精准度不够,但如果去掉3号框而使用4号框作为左边缘框,则有些字体区域没有检测出来,同样检测精度不足。这种情况其实非常容易出现,所以CTPN采取了Side-refinement 思路进一步优化边缘位置的预测即引入回归X参数,X参数直接标定了完整文本框的左右边界,做到精确的边界预测。第二幅图中的红色框就是经过Side-refinement后的检测结果,可以看出检测准确率有了很大的提升。 side-refinement确实可以进一步提升位置准确率,在SWT的Multi-Lingual datasets上产生2%的效果提升。
    在这里插入图片描述
    再看多几幅图,体验一下Side-refinement后的效果。
    在这里插入图片描述
    最后总结一下CTPN这个流行的文本检测框架的三个闪光点:

    1. 将文本检测任务转化为一连串小尺度文本框的检测;
    2. 引入RNN提升文本检测效果;
    3. Side-refinement(边界优化)提升文本框边界预测精准度。
      在这里插入图片描述

    当然,CTPN也有一个很明显的缺点:对于非水平的文本的检测效果并不好。CTPN论文中给出的文本检测效果图都是文本位于水平方向的,显然CTPN并没有针对多方向的文本检测有深入的探讨。那对于任意角度的文本检测应该采取什么的算法思路呢?下面的SegLink算法给出了一个新奇的解决方案。

    SegLink(2017)

    CVPR2017的一篇spotlight论文《Detecting Oriented Text in Natural Images by Linking Segments》介绍以一种可以检测任意角度文本的检测算法,我们一般称这个算法为SegLink,这篇论文既融入CTPN小尺度候选框的思路又加入了SSD算法的思路,达到了当时自然场景下文本检测state-of-art的效果。

    现在我想先介绍为什么要针对多方向的文本检测做特定的研究。对于普通目标检测,我们并不需要对其做所谓的多方向目标检测,比如下面这个检测任务,我们直接把单车和狗的位置找出来即可。
    在这里插入图片描述
    但是对于文本检测任务可不一样,文本的特点就是高宽比特别大或小,而且文本通常存在一定的旋转角度,如果我们对于带角度的文本仍然使用目标检测那个思路回归四个参数(x,y,w,h)来指定一个目标的位置的话(如下图红色框),那显然误差太大了,这个检测效果并不是我们所能接受的。作为对比,下图的绿色框的检测效果才是我们的终极目标。那么怎么基于原来经典的目标检测算法做相应的优化以适应这种检测效果的要求呢?
    在这里插入图片描述
    一个最直接的思路就是让模型再学习一个参数θ!这个θ表示文本框的旋转角度,也就是我们最终要回归的参数从原来的(x,y,w,h)变成(x,y,w,h,θ)。SegLink确实也采取了这个思路,除此之外,他还提出了Segment和Linking两个重要概念,这个才是这篇CVPR论文的核心创新点。

    什么是segment?segment从中文上理解为文本行的一部分,这一部分可以是一个字符或文本行的任意一部分。如下图示,黄色框表示一个segment,一个完整的文本行中包含多个segment,每个sgment之间通过link(图中的绿色线)连接组合起来。那么Segment做文本检测的思路其实跟CTPN的思路很像,先检测文本行的一部分,再把他们连接起来构成一个完整文本行。
    在这里插入图片描述
    我们把图片的关键部位放大看看细节:首先每个segment是有一定的重合区域的,然后每两个segment连接的部位是两个segment的中心点。每一个segment和link仅依靠局部图像的纹理信息即可完成检测,而无需整张图像的信息。
    在这里插入图片描述
    接下来我们通过分析SegLink的网络架构进一步理解SegLink如何做到高效的多角度文本检测。下图是SegLink的网络架构,显然这个架构采取了SSD的思路,首先使用VGG16作为backbone进行特征提取,其中VGG16的全连接层(fc6,fc7)替换成卷积层(conv6,conv7),再接卷积层conv8到conv11。值得说明的是,conv4~conv11之间的尺寸依次减少(每一层是前一层的1/2)。这个做法是为了做多尺度下的目标检测,即大的feature map擅长做小物体的检测,而小的feature map则擅长检测大物体。借助多个不同尺度的feature map,从6个feature layer上检测segment和link,我们就可以检测出不同尺寸的文本行了。
    在这里插入图片描述
    观察后面的卷积层可以发现,对不同层的feature map使用3×3的卷积层产生最终的输出(包括segment和link),不同特征层输出的维度是不一样的,因为除了conv4_3层外,其它层存在跨层的link。这里segment是text的带方向bbox信息(它可能是个单词,也可能是几个字符,总之是文本行的部分),link是不同segment的连接信息(文章将其也增加到网络中自动学习)。

    当所有segments都被检测出来后,我们就可以通过融合规则(combining segments),将各个feature map的segment的box信息和link信息进行融合,得到最终的文本行。

    SegLink所使用的目标函数由三个部分构成,是否是text的二类分类的softmax损失,box的smooth L1 regression损失,是否link的二类的softmax损失。λ1和λ2控制权重,最后都设为1。
    在这里插入图片描述
    现在计算一下每个feature map输出的参数有哪些呢?

    • segment的位置信息:(x,y,w,h,θ),一共5个参数
    • 每个segment内的分类分数,即判断框内有字符还是无字符的分数(2分类),共2个参数
    • 同层(within-layer)的每个segment的link的分数,表示该方向有link还是没link(2分类问题),而一个segment有八邻域所以有八个方向,参数一共有2×8=16
    • 相邻层(cross-layer)之间也存在link,同样是该方向有link还是没link(2分类问题),而link的个数是4个,所以参数总数为2×4=8

    下图很清楚地表示出每个feature map输出的参数有多少个,输出参数总数为(2+5+16+8=31)。假设当前的feature map的尺度为(w,h),那么该层卷积后输出为w×h×31。
    在这里插入图片描述
    这里想再谈谈Within-Layer Link和Cross-Layer Link的作用。

    within-layer link表示在同一层feature layer里,每个Segment与8邻域内的segment的连接状况,如下图(a)所示。且每个link有2维,一维是正分,表示两个segment属于同一文本,一维是负分,表示两个segment不属于同一文本。所以,每个predictor输出16(8×2)维向量。
      
    cross-layer link:在不同的feature layer上有可能会检测到同一文本的segments,造成冗余,cross-layer link的提出就是为了解决这个问题。cross-layer link连接了两个相邻feature layer上的segments,如图(b)所示。需要注意的是,由于下采样使后一层为前一层scale的1/2,定义一个segment的cross-layer邻居为前一层4邻域更小的segment,即前一层是后一层的邻居,但后一层不是前一层的邻居,所以conv4_3的feature layer没有cross-layer邻居。图中所示的黄框为当前层的segment,蓝框为上一层更小更细的segment,绿色的线代表cross-layer link有连接,属于同一文本,在后续的combine算法中会将他们融合,即去除了冗余。

    在这里插入图片描述

    读到这里我们已经知道如何获取segment和相应的link了,那接下来要做的就是怎么把这些link和segment合并成一个完整的文本行。先贴一下论文中使用到的合并算法:
    在这里插入图片描述
    看起来真的是头都大,其实思想很简单,我尝试用中文解释一下:

    1. 假设我们有一个集合B,里面有很多相关联的segment待合并;
    2. 每一个segment都有自己的角度θ,那我们求集合B中所有segment角度的平均值θb;
    3. 求一条直线L使得所有segment的中心到这条直线的距离最小,也就是最小二乘法线性回归啦;
    4. 每个segment的中心往直线L做垂直投影;
    5. 从所有投影点中选出相距最远的两个点,记做(xp,yp)和(xq,yq);
    6. 最终合并好的文本框的位置参数记为(xb,yb,wb,hb,θb)那么xb:=1/2(xp+xq,yb:=1/2(yp+yq)
    7. 文本行的宽度wb就是两个最远点的距离(即(xp,yp)和(xq,yq))再加上最远两个点所处的segment的宽度的一半(Wp和Wq)。
    8. 文本行高度hb就是所有segment高度求平均值

    我画了下图辅助理解合并算法,橙色直线是拟合出的最佳直线,红色点表示segment的中心,黄点表示红点在直线上的投影,绿框就是合并后的完整本文框。
    在这里插入图片描述

    这样子我们就求解完一个完整文本框的所有参数,也就完成了segment合并成文本行的任务。

    SegLink算法对于各种角度的文本检测具有很强的鲁棒性。
    在这里插入图片描述

    SegLink论文中并没有提到该算法能不能检测弯曲的文本,从理论上解读,SegLink是可以做到的。比如下图,只是合并算法要做一些改变而已。
    在这里插入图片描述

    EAST(2017)

    对于以上把完整文本行先分割检测再合并的思路,有人提出质疑,觉得这种做法比较麻烦,把文本检测切割成多个阶段来进行,这无疑增大了文本检测精度的损失和时间的消耗,对于文本检测任务上中间处理越多可能效果越差。所以有篇CVPR2017的文章提出,我们有一种方法能优雅且简洁地完成多角度文本检测,这个算法叫做EAST,论文为《EAST: An Efficient and Accurate Scene Text Detector》。

    通过下图我们知道,一个文本检测有多个阶段,就以region proposals系的检测算法为例,他们通常包含候选框提取、候选框过滤、bouding box回归、候选框合并等阶段,EAST的作者认为,一个文本检测算法被拆分成多个阶段其实并没有太多好处,实现真正端到端的文本检测网络才是正确之举。所以EAST的pipeline相当优雅,只分为FCN生成文本行参数阶段和局部感知NMS阶段,网络的简洁是的检测的准确性和速度都有了进一步的提高。

    在这里插入图片描述

    我们从网络架构来理解EAST做文本检测的优势。首先EAST采取了FCN的思路,一开始我以为EAST是一个通过语义分割来解决文本检测的难题,深入阅读后才发现并不是,而只是借助了FCN的架构做特征提取和学习,最终还是一个回归问题,在EAST最后预测出相应的文本行参数。

    EAST网络分为特征提取层+特征融合层+输出层三大部分。

    特征提取层: backbone采取PVANet来做特征提取,接下来送入卷积层,而且后面的卷积层的尺寸依次递减(size变为上一层的一半),而且卷积核的数量依次递增(是前一层的2倍)。抽取不同level的feature map,这样可以得到不同尺度的特征图,目的是解决文本行尺度变换剧烈的问题,size大的层可用于预测小的文本行,size小的层可用于预测大的文本行。

    特征合并层,将抽取的特征进行merge.这里合并的规则采用了U-net的方法,合并规则:从特征提取网络的顶部特征按照相应的规则向下进行合并,这里描述可能不太好理解,具体参见下述的网络结构图。

    网络输出层:网络的最终输出有5大部分,他们分别是:

    • score map:一个参数,表示这个预测框的置信度;
    • text boxes: 4个参数,(x,y,w,h),跟普通目标检测任务的bounding box参数一样,表示一个物体的位置;
    • text rotation angle: 1个参数,表示text boxe的旋转角度;
    • text quadrangle coordinates:8个参数,表示任意四边形的四个顶点坐标,即(x1,y1),(x2,y2),(x3,y3),(x4,y4)。
      在这里插入图片描述
      所以从整体看来,EAST就是借助FCN架构直接回归出文本行的(x,y,w,h,θ)+置信度+四边形的四个坐标!非常简洁!但是看到这里或许会有个问题,为什么要生成四边形的四个坐标呢?(x,y,w,h,θ)这个参数不足以解决文本行定位问题?还真不能,看看下面这个图片。
      在这里插入图片描述
      对于这种带放射变换的文本行(可能还有的是透视变换),呈现出来的形状是平行四边形(黄色虚线为ground true),如果我们以(x,y,w,h,θ)来表示这个文本的位置,就是粉色框所示,显然不合适。所以对于这种场合,直接预测四边形的四个顶点坐标才是正确之举。

    EAST目标函数分两部分,如下,第一部分是分类误差,第二部分是几何误差,文中权衡重要性,λg=1。
    在这里插入图片描述
    Ls称为分类误差函数,采用 class-balanced cross-entropy,这样做可以很实用的处理正负样本不均衡的问题。
    在这里插入图片描述
    其中β=反例样本数量/总样本数量 (balance factor)
    在这里插入图片描述
    Lg为几何误差函数
    在这里插入图片描述
    对于RBOX,采用IoU loss
    在这里插入图片描述
    角度误差则为:
    在这里插入图片描述
    对于QUAD采用smoothed L1 loss
    CQ={x1,y1,x2,y2,x3,y3,x4,y4},NQ*指的是四边形最短边的长度
    在这里插入图片描述
    下面看看EAST文本检测的效果,注意观察一些带放射变换or透视变换的文本行的检测效果。
    在这里插入图片描述
    总结
    文本介绍了我一直关注且实验效果都相当不错的三个经典的文本检测算法,他们都是基于深度学习,可以这么说,现在做文本检测都是深度学习的天下了。当然深度学习流派做文本检测远不止以上几个思路,比如基于语义分割的思路做文本检测的、基于角点检测做文本检测、各种方法混合的文本检测的论文也非常多,同时也取得非常不错的效果。可以说,现在基于深度学习的文本检测论文可谓百花齐放。
    在这里插入图片描述

    展开全文
  • 文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。 文本检测不是一件...
  • 文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。 文本检测不是一件...
  • 文字识别分为两个具体步骤:文字的检测和文字的识别,两者缺一不可,尤其是文字检测,是识别的前提条件,若文字都找不到,那何谈文字识别。今天我们首先来谈一下当今流行的文字检测技术有哪些。 文本检测不是一件...
  • 晶振两边电容:晶振标称值在测试时有个“负载电容”的条件,在工 作时满足这个条件,振荡频率才与标称值一致。一般来讲,有低负载电容(串 联谐振晶体),高负载电容(并联谐振晶体)之分。在电路上特征为:...
  • 在固体相似材料研究基础上,利用"固-"耦合相似理论,得出适用于煤岩瓦斯"固-气"耦合相似条件。选用砂子为骨料,石蜡和油为胶结剂,研制出种适用于开展"固-气"耦合模拟实验材料。通过大量实验,对相似材料抗压...
  • C#微软培训教材(高清PDF)

    千次下载 热门讨论 2009-07-30 08:51:17
    C#--微软.NET语言 本书着重介绍语言本身,比较少涉及应用,不错入门书,从头讲起,不怕不明白。 <<page 1>> page begin==================== 目 目目 目 录 录录 录 第部分 C#语言概述.4 ...
  • C#微软培训资料

    2014-01-22 14:10:17
    <<page 1>> page begin==================== 目 目目 目 录 录录 ... 2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得纪念的一天 这天 微软公司正式推出了其下一代...
  • (16) 数据图用于抽象描述个软件逻辑模型,数据图由一些特定图符构成。下列图符名标识图符不属于数据图合法图符是(A) 注:P67 A. 控制 B. 加工 C. 数据存储 D. 源和潭 (17) 软件需求分析阶段工作...
  • iPhone开发秘籍(第2版)--详细书签版

    热门讨论 2012-12-11 13:42:25
    iPhone开发秘籍:第2版(iphone开发必备佳作,在第基础上进行了全面修订和大量扩充) 基本信息 原书名: The iPhone Developer's Cookbook: Building Applications with the iPhone 3.0 SDK (2nd Edition) 原...
  • iPhone开发秘籍(第2版)--源代码

    热门讨论 2012-12-11 13:51:22
    iPhone开发秘籍:第2版(iphone开发必备佳作,在第基础上进行了全面修订和大量扩充) 基本信息 原书名: The iPhone Developer's Cookbook: Building Applications with the iPhone 3.0 SDK (2nd Edition) 原...
  • 百为软路由

    2012-11-09 11:34:58
    在保证性能的前提下,要有个合理的价格,具有优异的性能价格比。 因此对个有一定规模的网吧来说,他们更倾向于使用硬路由,使用硬件路由器则带来更大的优势,如成型设备,次调试不用维护,没有零部件维护的...
  • 注塑成型技术

    2012-05-02 10:48:54
    括号内温度建议作为基本设定值,行程利用率为35%和65%,模件长与壁厚之比为50:1到100:1 熔料温度 220~280℃ 料筒恒温 220℃ 模具温度 20~60℃ 注射压力 具有很好流动性能,避免采用过高注射压力80~...
  • 二十三种设计模式【PDF版】

    热门讨论 2011-05-30 14:13:49
    汽车由车轮 方向盘 发动机很多部件组成,同时,将这些部件组装成汽车也是一件复杂工作,Builder 模式就是将这两 种情况分开进行。 设计模式之 Prototype(原型) 用原型实例指定创建对象种类,并且通过拷贝这些...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    答:对于复杂而开发时间紧项目时,可以采用C语言,但前提是要求对该MCU系统C语言和C编译器非常熟悉,特别要注意该C编译系统所能支持数据类型和算法。虽然C语言是最普遍的一种高级语言,但不同MCU厂家其...
  • [Oracle.11g权威指南(第2版)].谷长勇.扫描版.pdf

    千次下载 热门讨论 2013-06-23 21:16:09
    本章详细讲述了Oracle数据库安装、启动、关闭整个过程,以及如何使用DBCA创建个数据库。对数据库管理员而言,这些操作都是最基本。 3.1 在Windows环境下安装软硬件要求 25 3.2 在Windows环境下安装Oracle ...

空空如也

空空如也

1 2
收藏数 31
精华内容 12
关键字:

一件流的前提条件