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进程间通信之命名管道
Aug 28 Python
TensorFlow变量管理详解
Mar 10 Python
python 接口返回的json字符串实例
Mar 27 Python
Python实现ping指定IP的示例
Jun 04 Python
python 正确保留多位小数的实例
Jul 16 Python
Python操作Excel插入删除行的方法
Dec 10 Python
详解python深浅拷贝区别
Jun 24 Python
linux环境下Django的安装配置详解
Jul 22 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
Jun 02 Python
Python模块zipfile原理及使用方法详解
Aug 04 Python
django使用多个数据库的方法实例
Mar 04 Python
Python入门之基础语法详解
May 11 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编程最快明白》第四讲:日期、表单接收、session、cookie
2010/11/01 PHP
Yii2中Restful API原理实例分析
2016/07/25 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
有关JavaScript的10个怪癖和秘密分享
2011/08/28 Javascript
js的Prototype属性解释及常用方法
2014/05/08 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
2015/08/27 Javascript
javascript学习指南之回调问题
2016/04/23 Javascript
jQuery中弹出iframe内嵌页面元素到父页面并全屏化的实例代码
2016/12/27 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
vue下跨域设置的相关介绍
2017/08/26 Javascript
ES6中字符串string常用的新增方法小结
2017/11/07 Javascript
基于Vue实现电商SKU组合算法问题
2019/05/29 Javascript
Node 使用express-http-proxy 做api网关的实现
2020/10/15 Javascript
[01:25]DOTA2超级联赛专访iG 将调整状态找回自己
2013/06/05 DOTA
[02:32]DOTA2亚洲邀请赛 C9战队出场宣传片
2015/02/07 DOTA
python numpy和list查询其中某个数的个数及定位方法
2018/06/27 Python
python获取服务器响应cookie的实例
2018/12/28 Python
python 实现得到当前时间偏移day天后的日期方法
2018/12/31 Python
python for 循环获取index索引的方法
2019/02/01 Python
Python多进程fork()函数详解
2019/02/22 Python
python实现PID算法及测试的例子
2019/08/08 Python
Python列表切片常用操作实例解析
2019/12/16 Python
python+adb+monkey实现Rom稳定性测试详解
2020/04/23 Python
Python工程师必考的6个经典面试题
2020/06/28 Python
HTML5移动端开发中的Viewport标签及相关CSS用法解析
2016/04/15 HTML / CSS
FC-Moto英国:欧洲最大的摩托车服装和头盔商店之一
2019/08/25 全球购物
类、抽象类、接口的差异
2016/06/13 面试题
数控机械专业个人的自我评价
2014/01/02 职场文书
如何写好优秀的创业计划书
2014/01/30 职场文书
小学信息技术教学反思
2014/02/10 职场文书
优秀员工演讲稿
2014/05/19 职场文书
会计求职简历自我评价
2015/03/10 职场文书
护士求职自荐信
2015/03/25 职场文书
感恩的心主题班会
2015/08/12 职场文书
赞美教师的句子
2019/09/02 职场文书