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函数式编程指南(四):生成器详解
Jun 24 Python
Python设计模式之抽象工厂模式
Aug 25 Python
python写一个md5解密器示例
Feb 23 Python
python列表list保留顺序去重的实例
Dec 14 Python
opencv实现静态手势识别 opencv实现剪刀石头布游戏
Jan 22 Python
Flask配置Cors跨域的实现
Jul 12 Python
Python识别快递条形码及Tesseract-OCR使用详解
Jul 15 Python
Python实现性能自动化测试竟然如此简单
Jul 30 Python
解决Mac下使用python的坑
Aug 13 Python
PyTorch: Softmax多分类实战操作
Jul 07 Python
用python-webdriver实现自动填表的示例代码
Jan 13 Python
用python批量解压带密码的压缩包
May 31 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
php5.3中连接sqlserver2000的两种方法(com与ODBC)
2012/12/29 PHP
php获取参数的几种方法总结
2014/02/18 PHP
php读取富文本的时p标签会出现红线是怎么回事
2014/05/13 PHP
ThinkPHP 3.2 数据分页代码分享
2014/10/14 PHP
php天翼开放平台短信发送接口实现方法
2014/12/22 PHP
php 生成签名及验证签名详解
2016/10/26 PHP
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
2007/01/09 Javascript
javascript中比较字符串是否相等的方法
2013/07/23 Javascript
artDialog双击会关闭对话框的修改过程分享
2013/08/05 Javascript
IE网页js语法错误2行字符1、FF中正常的解决方法
2013/09/09 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
js中直接声明一个对象的方法
2014/08/10 Javascript
了解Javascript的模块化开发
2015/03/02 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
解决JS无法调用Controller问题的方法
2015/12/31 Javascript
使用nodeJs来安装less及编译less文件为css文件的方法
2017/11/20 NodeJs
JavaScript中的一些隐式转换和总结(推荐)
2017/12/22 Javascript
vue操作下拉选择器获取选择的数据的id方法
2018/08/24 Javascript
Golang与python线程详解及简单实例
2017/04/27 Python
python简单线程和协程学习心得(分享)
2017/06/14 Python
Python3爬虫爬取英雄联盟高清桌面壁纸功能示例【基于Scrapy框架】
2018/12/05 Python
Python调用百度根据经纬度查询地址的示例代码
2019/07/07 Python
解决Python对齐文本字符串问题
2019/08/28 Python
python mqtt 客户端的实现代码实例
2019/09/25 Python
记一次Django响应超慢的解决过程
2020/09/17 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
递归计算如下递归函数的值(斐波拉契)
2012/02/04 面试题
写给女朋友的道歉信
2014/01/08 职场文书
公司庆典邀请函范文
2014/01/13 职场文书
晚宴邀请函范文
2014/01/15 职场文书
法制宣传月活动总结
2014/04/29 职场文书
年度优秀员工获奖感言
2014/08/15 职场文书
2014年勤工助学工作总结
2014/11/24 职场文书
高考升学宴主持词
2019/06/21 职场文书
使用vue-element-admin框架从后端动态获取菜单功能的实现
2021/04/29 Vue.js