在上篇博客中,我们已经实现了水平投影和垂直投影图的绘制。接下来,我们可以根据获得的投影数据进行图像的分割,该法用于文本分割较多,所以此处依然以上次的图为例。
先把上次的两幅图搬过来,方便讲解。
上面两图分别从垂直和水平方向描述了图像中文本的分布。我们想象一下,将两幅图重叠起来(当然这里比例要调整下),那么我们就能得到四个重叠的白块,而这些白块所处的位置正是原图中文本的位置,所以接下来的任务就是,找出这些白块的坐标,此处白块近似矩形,所以我们要求矩形的四个坐标。
下面看代码。
#根据水平投影值选定行分割点 内联=1=0开始 j=0 因为我在范围(0,高度): 如果内联==1和z[我]祝辞=150:#从空白区进入文字区 开始=我#记录起始行分割点 我打印 内联=0 elif (i -开始的在3)和z[我]& lt;150和内联==0:#从文字区进入空白区 内联=1 hfg [j][0]=开始- 2 #保存行分割位置 hfg [j][1]=我+ 2 j=+ 1
确定行分割点的原理就是判断每一行的像素点数是否足够。我们可以从水平投影图中看出,白块是有文字的地方(原图是黑字白底,只是画投影图时选用白块黑底),即前面几行,灰度值为0的点的个数N很少,所以当遇到文字区时,N会很大,根据这一点,我们确定进入文字区的坐标(A1, B1),然后,当从文字区出来时,N又变的很小,我们再记下它的坐标(A1, B2)。同理,我们可以确定列分割点。
incol=1 start1=0 j - 1=0 z1=hfg [p] [0] z2=hfg [p] [1] i1的范围(0,宽度): 如果incol==1和v (i1)祝辞=20:#从空白区进入文字区 start1=i1 #记录起始列分割点 incol=0 elif (i1 - start1祝辞3)和v (i1) & lt;20和incol==0: #从文字区进入空白区 incol=1 释放[j - 1] [0]=start1 - 2 #保存列分割位置 寻求组队[j - 1] [1]=i1 + 2 l1=start1 - 2 l2=i1 + 2 j - 1=j - 1 + 1
最后根据矩形的坐标将文本在图中框出来。附上完整代码。
进口cv2 进口numpy img=cv2.imread (D:/0. jpg, cv2.COLOR_BGR2GRAY) 高度、宽度=img.shape (2): #印刷高度、宽度 #大?cv2。调整(img(2 * 2 *加强筋的宽度和高度)、插值=cv2.INTER_CUBIC) 灰色=cv2。cv2.COLOR_BGR2GRAY cvtColor (img) 打(_)=cv2。阈值(灰色,140年,255年,cv2.THRESH_BINARY) #使文字增长成块 内核=cv2.getStructuringElement (cv2。(2,2)MORPH_RECT) #形态学处理,定义矩形结构=cv2关闭。侵蚀(打,没有一个迭代=7) # cv2.imshow(“侵蚀”,关闭) 高度、宽度=closed.shape (2): #印刷高度、宽度 z=[0] *高度 v=[0] *宽度 hfg=[[0坳的范围(2)]的行范围(高度) 抽=[[0坳的范围(2)]的行范围(宽度) 盒=(0,0,0,0) #水平投影 一个=0 emptyImage1=numpy。0((高度、宽度、3),numpy.uint8) y的范围(0,高度): x的范围(0,宽度): cp=关闭[y、x] #如果np.any(关闭[y、x]): 如果cp==0:=+ 1 其他: 继续 z [y]=#打印z [y] 一个=0 #根据水平投影值选定行分割点 内联=1=0开始 j=0 因为我在范围(0,高度): 如果内联==1和z[我]祝辞=150:#从空白区进入文字区 开始=我#记录起始行分割点 #我打印 内联=0 elif (i -开始的在3)和z[我]& lt;150和内联==0:#从文字区进入空白区 内联=1 hfg [j][0]=开始- 2 #保存行分割位置 hfg [j][1]=我+ 2 j=+ 1 #对每一行垂直投影,分割 一个=0 p的范围(0,j): x的范围(0,宽度): y的范围(hfg [p] [0], hfg [p] [1]): cp1=关闭[y、x] 如果cp1==0:=+ 1 其他: 继续 v [x]=#保存每一列像素值 一个=0 #打印宽度 #垂直分割点 incol=1 start1=0 j - 1=0 z1=hfg [p] [0] z2=hfg [p] [1] i1的范围(0,宽度): 如果incol==1和v (i1)祝辞=20:#从空白区进入文字区 start1=i1 #记录起始列分割点 incol=0 elif (i1 - start1祝辞3)和v (i1) & lt;20和incol==0: #从文字区进入空白区 incol=1 释放[j - 1] [0]=start1 - 2 #保存列分割位置 寻求组队[j - 1] [1]=i1 + 2 l1=start1 - 2 l2=i1 + 2 j - 1 + 1的j - 1=cv2。矩形(img, (l1, z1), (l2 (z2) (255, 0, 0), 2) cv2。imshow(“结果”,img) cv2.waitKey (0)Python实现投影法分割图像示例(二)