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中__name__的使用实例
Apr 14 Python
Python验证企业工商注册码
Oct 25 Python
Python算法之图的遍历
Nov 16 Python
python使用KNN算法手写体识别
Feb 01 Python
解决Python设置函数调用超时,进程卡住的问题
Aug 08 Python
python 消费 kafka 数据教程
Dec 21 Python
python基于event实现线程间通信控制
Jan 13 Python
Python JSON编解码方式原理详解
Jan 20 Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
Jan 20 Python
pytorch实现保证每次运行使用的随机数都相同
Feb 20 Python
python生成并处理uuid的实现方式
Mar 03 Python
python实现手机推送 代码也就10行左右
Apr 12 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中检查PHP文件是否有语法错误的方法
2009/12/23 PHP
关于PHP的相似度计算函数:levenshtein的使用介绍
2013/04/15 PHP
PHP设置一边执行一边输出结果的代码
2013/09/30 PHP
php判断输入是否是纯数字,英文,汉字的方法
2015/03/05 PHP
实例分析PHP中PHPMailer发邮件
2017/12/13 PHP
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
2013/04/17 Javascript
node.js中的fs.link方法使用说明
2014/12/15 Javascript
node.js中的fs.chownSync方法使用说明
2014/12/16 Javascript
AngularJS之依赖注入模拟实现
2016/08/19 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
2016/11/18 Javascript
你可能从未使用过的11+个JavaScript特性(小结)
2020/01/08 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
2021/01/07 Javascript
[00:27]DOTA2战队VP、Secret贺新春
2018/02/11 DOTA
python3批量删除豆瓣分组下的好友的实现代码
2016/06/07 Python
Python实现网络端口转发和重定向的方法
2016/09/19 Python
python基于pyDes库实现des加密的方法
2017/04/29 Python
通过Python 接口使用OpenCV的方法
2018/04/02 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
2018/06/11 Python
Kears+Opencv实现简单人脸识别
2019/08/28 Python
PyTorch 普通卷积和空洞卷积实例
2020/01/07 Python
Python tkinter和exe打包的方法
2020/02/05 Python
Python 安装 virturalenv 虚拟环境的教程详解
2020/02/21 Python
Python参数传递对象的引用原理解析
2020/05/22 Python
css3中的calc函数浅析
2018/07/10 HTML / CSS
澳大利亚票务和娱乐市场领导者:Ticketmaster
2017/03/03 全球购物
美国山地自行车、露营、户外装备和服装购物网站:Aventuron
2018/05/05 全球购物
美国摩托车头盔、零件、齿轮及配件商店:Cycle Gear
2019/06/12 全球购物
Bose英国官方网站:美国知名音响品牌
2020/01/26 全球购物
心得体会范文
2014/01/04 职场文书
写给女朋友的道歉信
2014/01/08 职场文书
少儿节目主持串词
2014/04/02 职场文书
《记金华的双龙洞》教学反思
2014/04/19 职场文书
党员对照检查材料
2014/09/22 职场文书
防汛工作情况汇报
2014/10/28 职场文书
酒店办公室主任岗位职责
2015/04/01 职场文书
2016年春节问候语
2015/11/11 职场文书