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 相关文章推荐
利用Fn.py库在Python中进行函数式编程
Apr 22 Python
python计算对角线有理函数插值的方法
May 07 Python
python下paramiko模块实现ssh连接登录Linux服务器
Jun 03 Python
用python做一个搜索引擎(Pylucene)的实例代码
Jul 05 Python
Python 文件操作的详解及实例
Sep 18 Python
Python基于递归算法实现的汉诺塔与Fibonacci数列示例
Apr 18 Python
Python调用服务接口的实例
Jan 03 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
Jan 15 Python
Python实现的微信红包提醒功能示例
Aug 22 Python
python的help函数如何使用
Jun 11 Python
基于Python爬取fofa网页端数据过程解析
Jul 13 Python
Python 解析xml文件的示例
Sep 29 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 array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
php+ajax实时刷新简单实例
2015/02/25 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
javascript数组的扩展实现代码集合
2008/06/01 Javascript
Jquery 获得服务器控件值的方法小结
2010/05/11 Javascript
javascript动态加载三
2012/08/22 Javascript
javascript获取select的当前值示例代码(兼容IE/Firefox/Opera/Chrome)
2013/12/17 Javascript
jQuery中removeProp()方法用法实例
2015/01/05 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
向JavaScript的数组中添加元素的方法小结
2015/10/24 Javascript
同步异步动态引入js文件的几种方法总结
2016/09/23 Javascript
js前端日历控件(悬浮、拖拽、自由变形)
2017/03/02 Javascript
nodejs express配置自签名https服务器的方法
2018/05/22 NodeJs
详解angular2如何手动点击特定元素上的点击事件
2018/10/16 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
2019/05/10 Javascript
Node.js Domain 模块实例详解
2020/03/18 Javascript
解决vue项目中出现Invalid Host header的问题
2020/11/17 Javascript
[10:04]国际邀请赛采访专栏:DK.Farseer,mouz.Black^,采访员Josh专访
2013/08/05 DOTA
Python部署web开发程序的几种方法
2017/05/05 Python
Django教程笔记之中间件middleware详解
2018/08/01 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
Python设计模式之命令模式原理与用法实例分析
2019/01/11 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
已安装tensorflow-gpu,但keras无法使用GPU加速的解决
2020/02/07 Python
推荐8款常用的Python GUI图形界面开发框架
2020/02/23 Python
用python写爬虫简单吗
2020/07/28 Python
丝芙兰加拿大官方网站:SEPHORA加拿大
2018/11/20 全球购物
Brasty波兰:香水、化妆品、手表网上商店
2019/04/15 全球购物
党的群众路线教育实践活动动员会主持词
2014/03/20 职场文书
银行竞聘演讲稿范文
2014/04/23 职场文书
电子银行业务授权委托书
2014/10/10 职场文书
再婚婚前财产协议书范本
2014/10/19 职场文书
2015年办公室工作总结范文
2015/03/31 职场文书
浅谈Golang 切片(slice)扩容机制的原理
2021/06/09 Golang
React 并发功能体验(前端的并发模式)
2021/07/01 Javascript
Python采集爬取京东商品信息和评论并存入MySQL
2022/04/12 Python