Python实现投影法分割图像示例(二)


Posted in Python onJanuary 17, 2020

在上篇博客中,我们已经实现了水平投影和垂直投影图的绘制。接下来,我们可以根据获得的投影数据进行图像的分割,该法用于文本分割较多,所以此处依然以上次的图为例。

先把上次的两幅图搬过来,方便讲解。

Python实现投影法分割图像示例(二)

上面两图分别从垂直和水平方向描述了图像中文本的分布。我们想象一下,将两幅图重叠起来(当然这里比例要调整下),那么我们就能得到四个重叠的白块,而这些白块所处的位置正是原图中文本的位置。所以接下来的任务就是,找出这些白块的坐标,此处白块近似矩形,所以我们要求矩形的四个坐标。

下面看代码。

#根据水平投影值选定行分割点
inline = 1
start = 0
j = 0
for i in range(0,height):
  if inline == 1 and z[i] >= 150 : #从空白区进入文字区
    start = i #记录起始行分割点
    print i
    inline = 0
  elif (i - start > 3) and z[i] < 150 and inline == 0 : #从文字区进入空白区
    inline = 1
    hfg[j][0] = start - 2 #保存行分割位置
    hfg[j][1] = i + 2
    j = j + 1

确定行分割点的原理就是判断每一行的像素点数是否足够。我们可以从水平投影图中看出,白块是有文字的地方(原图是黑字白底,只是画投影图时选用白块黑底),即前面几行,灰度值为0的点的个数N很少,所以当遇到文字区时,N会很大,根据这一点,我们确定进入文字区的坐标(A1,B1)。然后,当从文字区出来时,N又变的很小,我们再记下它的坐标(A1,B2)。同理,我们可以确定列分割点。

incol = 1
  start1 = 0
  j1 = 0
  z1 = hfg[p][0]
  z2 = hfg[p][1]
  for i1 in range(0,width):
    if incol == 1 and v[i1] >= 20 : #从空白区进入文字区
      start1 = i1 #记录起始列分割点
      incol = 0
    elif (i1 - start1 > 3) and v[i1] < 20 and incol == 0 : #从文字区进入空白区
      incol = 1
      lfg[j1][0] = start1 - 2  #保存列分割位置
      lfg[j1][1] = i1 + 2
      l1 = start1 - 2
      l2 = i1 + 2
      j1 = j1 + 1

最后根据矩形的坐标将文本在图中框出来。附上完整代码。

import cv2
import numpy
img = cv2.imread('D:/0.jpg',cv2.COLOR_BGR2GRAY)
height, width = img.shape[:2]
#print height, width
#resized = cv2.resize(img, (2*width,2*height), interpolation=cv2.INTER_CUBIC)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(_, thresh) = cv2.threshold(gray, 140, 255, cv2.THRESH_BINARY) 
#使文字增长成块
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))#形态学处理,定义矩形结构
closed = cv2.erode(thresh, None, iterations = 7)
#cv2.imshow('erode',closed)
height, width = closed.shape[:2]
#print height, width
z = [0]*height
v = [0]*width
hfg = [[0 for col in range(2)] for row in range(height)]
lfg = [[0 for col in range(2)] for row in range(width)]
box = [0,0,0,0]
#水平投影
a = 0
emptyImage1 = numpy.zeros((height, width, 3), numpy.uint8) 
for y in range(0, height):
  for x in range(0, width):
    cp = closed[y,x]
    #if np.any(closed[y,x]):
    if cp == 0:
      a = a + 1
    else :
      continue
  z[y] = a
  #print z[y]
  a = 0
#根据水平投影值选定行分割点
inline = 1
start = 0
j = 0
for i in range(0,height):
  if inline == 1 and z[i] >= 150 : #从空白区进入文字区
    start = i #记录起始行分割点
    #print i
    inline = 0
  elif (i - start > 3) and z[i] < 150 and inline == 0 : #从文字区进入空白区
    inline = 1
    hfg[j][0] = start - 2 #保存行分割位置
    hfg[j][1] = i + 2
    j = j + 1
 
#对每一行垂直投影、分割
a = 0
for p in range(0, j):
  for x in range(0, width):
    for y in range(hfg[p][0], hfg[p][1]):
      cp1 = closed[y,x]
      if cp1 == 0:
        a = a + 1
      else :
        continue
    v[x] = a #保存每一列像素值
    a = 0
  #print width
  #垂直分割点
  incol = 1
  start1 = 0
  j1 = 0
  z1 = hfg[p][0]
  z2 = hfg[p][1]
  for i1 in range(0,width):
    if incol == 1 and v[i1] >= 20 : #从空白区进入文字区
      start1 = i1 #记录起始列分割点
      incol = 0
    elif (i1 - start1 > 3) and v[i1] < 20 and incol == 0 : #从文字区进入空白区
      incol = 1
      lfg[j1][0] = start1 - 2  #保存列分割位置
      lfg[j1][1] = i1 + 2
      l1 = start1 - 2
      l2 = i1 + 2
      j1 = j1 + 1
      cv2.rectangle(img, (l1, z1), (l2, z2), (255,0,0), 2)      
cv2.imshow('result', img)
cv2.waitKey(0)

代码中注释掉的一些代码,有的是我做的一些小变动,有的是观察中间值。大家可自行查看。

最后放上结果图。

Python实现投影法分割图像示例(二)

由于文本的坐标已经有了,还可以把这些文本块截取下来,用一下PIL或者OPENCV就好了,此处就不做了。

以上这篇Python实现投影法分割图像示例(二)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python操作json数据的一个简单例子
Apr 17 Python
python实现的一个火车票转让信息采集器
Jul 09 Python
pandas求两个表格不相交的集合方法
Dec 08 Python
python模块导入的细节详解
Dec 10 Python
Python判断telnet通不通的实例
Jan 26 Python
如何使用Python标准库进行性能测试
Jun 25 Python
Python实现二叉树的最小深度的两种方法
Sep 30 Python
python3.x 生成3维随机数组实例
Nov 28 Python
根据tensor的名字获取变量的值方式
Jan 04 Python
浅谈Django中的QueryDict元素为数组的坑
Mar 31 Python
Pycharm中配置远程Docker运行环境的教程图解
Jun 11 Python
python和JavaScript哪个容易上手
Jun 23 Python
Python常用库大全及简要说明
Jan 17 #Python
Python Sphinx使用实例及问题解决
Jan 17 #Python
通过实例了解Python str()和repr()的区别
Jan 17 #Python
python无序链表删除重复项的方法
Jan 17 #Python
Python实现投影法分割图像示例(一)
Jan 17 #Python
np.dot()函数的用法详解
Jan 17 #Python
python使用numpy实现直方图反向投影示例
Jan 17 #Python
You might like
供参考的 php 学习提高路线分享
2011/10/23 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
2014/06/25 PHP
JQuery UI DatePicker中z-index默认为1的解决办法
2010/09/28 Javascript
JQuery之拖拽插件实现代码
2011/04/14 Javascript
禁止IE用右键的JS代码
2013/12/30 Javascript
js点击出现悬浮窗效果不使用JQuery插件
2014/01/20 Javascript
js添加select下默认的option的value和text的方法
2014/10/19 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
浅谈javascript事件取消和阻止冒泡
2015/05/26 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
日常收藏的jquery技巧
2015/12/02 Javascript
探寻JavaScript中this指针指向
2016/04/23 Javascript
jQuery实现订单提交页发送短信功能前端处理方法
2016/07/04 Javascript
mvc中form表单提交的三种方式(推荐)
2016/08/10 Javascript
基于Bootstrap的Metronic框架实现页面链接收藏夹功能
2016/08/29 Javascript
js控制文本框只能输入中文、英文、数字与指定特殊符号的实现代码
2016/09/09 Javascript
基于bootstrap实现多个下拉框同时搜索功能
2017/07/19 Javascript
原生JS实现的双色球功能示例
2018/02/02 Javascript
详解webpack4升级指南以及从webpack3.x迁移
2018/06/12 Javascript
Python3基础之条件与循环控制实例解析
2014/08/13 Python
在Python中使用HTMLParser解析HTML的教程
2015/04/29 Python
使用DataFrame删除行和列的实例讲解
2018/04/08 Python
详解配置Django的Celery异步之路踩坑
2018/11/25 Python
Python实现E-Mail收集插件实例教程
2019/02/06 Python
python实现AES和RSA加解密的方法
2019/03/28 Python
python的几种矩阵相乘的公式详解
2019/07/10 Python
python使用pandas抽样训练数据中某个类别实例
2020/02/28 Python
一波HTML5 Canvas基础绘图实例代码集合
2016/02/28 HTML / CSS
详解html5 postMessage解决跨域通信的问题
2018/08/17 HTML / CSS
优秀团员自我评价范文
2014/04/23 职场文书
圣诞节活动策划方案
2014/06/09 职场文书
女生节标语
2014/06/26 职场文书
运动会广播稿200字(10篇)
2014/10/12 职场文书
小学班主任自我评价
2015/03/11 职场文书
汽车销售助理岗位职责
2015/04/14 职场文书
解决MySQL Varchar 类型尾部空格的问题
2022/04/06 MySQL