详解SWT算法+python代码链接与实现

详解SWT算法+python代码链接与实现


SWT Stroke Width Transform开山之作是Boris Epshtein,etc.Detecting Text in Natural Scenes with Stroke Width Transform,本文主要围绕这篇文章进行分析。巅峰之作[1]是Cong Yao, etc. Detecting texts of arbitrary orientation in natural images,主要是针对原始SWT算法对于倾斜文本效果不佳进行改进。

1.计算笔画宽度

文中定义了笔画宽度值Stroke Width,比如图(a)中即为典型的笔画,可以看出,同一笔画宽度相近。图(b)中p是笔画边缘的像素点,按p的梯度方向进行搜索,可找到同一笔画下对应像素p。图©中射线经过的像素使用当前最小值和笔画宽度进行分配。
在这里插入图片描述
笔画宽度初始值皆设为无穷大,首先使用Canny算子计算图片边缘,Canny算子可以参考这篇文章[2]。经过计算,每个像素点p有对应梯度方向dp,如果p笔画边界点,沿着射线r=p+n*dp,n>0直到找到另一个边界像素点q,如果dq与dp几乎相反【判断条件如下图】
在这里插入图片描述

则SWT输出segment,segment[p,q]段内像素取通过该像素点的宽度最小值,笔画宽度为
在这里插入图片描述

如果未找到对应像素点q,或者dq与dp不符合相反条件,则丢弃这条射线。
在这里插入图片描述

针对上图这种角点处笔画宽度不准的情况,遍历每条射线,求得其笔画宽度值中位数m,将射线中所有比m高的值设为m

2.寻找字母备选

第二步是将笔画宽度相近的像素值组成字母备选。这一步是通过修改经典的Connected Component algorithm[3],将连接规则从binary mask改为比较相邻像素SWT值。作者发现简单的比较效果足够,如果两个相邻像素SWT比不超过3.0则将他们组在一起。为了抵御黑底白字或者白底黑字,在dp方向和-dp方向分别进行计算。

为了区分可能含有字母的components,文中使用ICDAR2003数据训练集进行一系列相对宽松规则的学习。

第一步是计算每个连通分量内方差,删除方差较大的分量。此步骤是针对自然场景中树叶等干扰物的影响。学到的参数是连通分量中平均笔画宽度的一半。

第二步针对可能会生成长且窄的分量问题,limit the ratio between the diameter of the connected component and its median stroke width to be a value less than 10【?】。

第三个问题是针对连通分量包含文本的问题,比如广告牌。文中通过限制ground truth两个连通量不互相包含来解决。

最后,对连通分量的大小进行限制,将字体限制在10到300像素内。

特别地,在训练前,使用Otsu的自适应二值化对训练集进行处理。通过微调,99%连通分量可被检测出来。

3.连字成词

At the next step of the algorithm, the candidate pairs determined above are clustered together into chains. Initially, each chain consists of a single pair of letter candidates. Two chains can be merged together if they share one end and have similar direction. The process ends when no chains can be merged. Each produced chain of sufficient length (at least 3 letters in our experiments) is considered to be a text line.

Finally, text lines are broken into separate words, using a heuristic that computes a histogram of horizontal distances between consecutive letters and estimates the distance threshold that separates intra-word letter distances from inter-word letter distances. While the problem in general does not require this step, we do it in order to compare our results with the ones in ICDAR 2003 database [8]. In the results shown for our database [26] we do not employ this step, as we have marked whole text lines.

代码实现:
https://github.com/marrrcin/swt-python
第一步,按readme中步骤编译库
第二步,将图片目标路径复制到/yourpath/*.jpg,运行程序,即可得到文件夹中所有图片的检测结果画图版,结果为原图加上_result后缀。

// An highlighted block
import ccvwrapper
import numpy as np
import cv2
import glob
import sys 

green = (0,255,0)

def get_swt_image(img):
#    image_name = "path"
    bb = open(img,"rb").read()
    swt_result_raw = ccvwrapper.swt(bb,len(bb),1024,1360)
    swt_result = np.reshape(swt_result_raw,(len(swt_result_raw)/4,4))
    image = cv2.imread(img)
    for x, y, width, height in swt_result:
        cv2.rectangle(image,(x,y),(x+width,y+height),green)
    cv2.imwrite(img.split('.')[0]+"_result.jpg", image)

def main(argv=None):
    if argv is None:
        argv = sys.argv
    for img in glob.glob("/yourpath/*.jpg"):
            get_swt_image(img)

if __name__=="__main__":
    main(sys.argv)

[1] : https://blog.csdn.net/segoold_chou/article/details/34174053
[2] : http://www.aishack.in/tutorials/canny-edge-detector/
[3] : B. K. P. Horn, “Robot Vision”, McGraw-Hill Book Company, New York, 1986.
[4] : N. Otsu, “A threshold selection method from gray-level histograms”. IEEE Trans. Sys., Man., Cyber. 9: 62–66 (1979)
[5] : https://github.com/marrrcin/swt-python

猜你喜欢

转载自blog.csdn.net/weixin_38388903/article/details/86082066