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判断端口是否打开的实现代码
Feb 10 Python
python使用三角迭代计算圆周率PI的方法
Mar 20 Python
使用Python实现BT种子和磁力链接的相互转换
Nov 09 Python
Python标准模块--ContextManager上下文管理器的具体用法
Nov 27 Python
用python实现将数组元素按从小到大的顺序排列方法
Jul 02 Python
详解python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案
Dec 02 Python
python 寻找离散序列极值点的方法
Jul 10 Python
python处理大日志文件
Jul 23 Python
django实现将修改好的新模型写入数据库
Mar 31 Python
用python打开摄像头并把图像传回qq邮箱(Pyinstaller打包)
May 17 Python
解决TensorFlow训练模型及保存数量限制的问题
Mar 03 Python
Elasticsearch 聚合查询和排序
Apr 19 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获取远程图片体积大小的实例
2013/11/12 PHP
PHP附件下载中文名称乱码的解决方法
2015/12/17 PHP
php+mysql实现简单登录注册修改密码网页
2016/11/30 PHP
php-beanstalkd消息队列类实例分享
2017/07/19 PHP
JavaScript 乱码问题
2009/08/06 Javascript
window.returnValue使用方法示例介绍
2014/07/03 Javascript
JavaScript 事件入门知识
2015/04/13 Javascript
jQuery 1.9.1源码分析系列(十四)之常用jQuery工具
2015/12/02 Javascript
js 截取或者替换字符串中的数字实现方法
2016/06/13 Javascript
jQuery实现的兼容性浮动层示例
2016/08/02 Javascript
js+css3实现旋转效果
2017/01/20 Javascript
Angular开发者指南之入门介绍
2017/03/05 Javascript
node.js操作mongodb简单示例分享
2017/05/25 Javascript
Angular resolve基础用法详解
2018/10/03 Javascript
vue插件mescroll.js实现移动端上拉加载和下拉刷新
2019/03/07 Javascript
微信小程序HTTP接口请求封装代码实例
2019/09/05 Javascript
Vue3.x源码调试的实现方法
2019/10/13 Javascript
jquery绑定事件 bind和on的用法与区别分析
2020/05/22 jQuery
Vue.extend 登录注册模态框的实现
2020/12/29 Vue.js
[01:01:52]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第二场 1月9日
2021/03/11 DOTA
python机器学习实战之K均值聚类
2017/12/20 Python
Python实现OpenCV的安装与使用示例
2018/03/30 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
深入理解python中sort()与sorted()的区别
2018/08/29 Python
Python sorted函数详解(高级篇)
2018/09/18 Python
Python自定义函数计算给定日期是该年第几天的方法示例
2019/05/30 Python
Django stark组件使用及原理详解
2019/08/22 Python
解决c++调用python中文乱码问题
2020/07/29 Python
Scrapy爬虫文件批量运行的实现
2020/09/30 Python
美国高端寝具品牌:Coyuchi
2017/02/08 全球购物
Daisy London官网:英国最大的首饰集团IBB旗下
2019/02/28 全球购物
Vertbaudet西班牙网上商店:婴儿服装、童装、母婴用品和儿童家具
2019/10/16 全球购物
俄罗斯达美乐比萨外送服务:Domino’s Pizza
2020/12/18 全球购物
如何写出高性能的JSP和Servlet
2013/01/22 面试题
行政人事岗位职责
2014/03/17 职场文书
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python