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中Genarator函数用法分析
Apr 08 Python
深入理解Python中命名空间的查找规则LEGB
Aug 06 Python
Python递归函数定义与用法示例
Jun 02 Python
Django Admin实现三级联动的示例代码(省市区)
Jun 22 Python
python字典一键多值实例代码分享
Jun 14 Python
Python实现FTP文件传输的实例
Jul 07 Python
python-tornado的接口用swagger进行包装的实例
Aug 29 Python
python Dijkstra算法实现最短路径问题的方法
Sep 19 Python
Pytorch中的variable, tensor与numpy相互转化的方法
Oct 10 Python
简单了解Python读取大文件代码实例
Dec 18 Python
python打开文件的方式有哪些
Jun 29 Python
Python切片列表字符串如何实现切换
Aug 06 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版(5)
2006/10/09 PHP
php基础知识:类与对象(1)
2006/12/13 PHP
PHP引用符&amp;的用法详细解析
2013/08/22 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
2014/12/16 PHP
PHP实现的CURL非阻塞调用类
2018/07/26 PHP
JavaScript 继承详解 第一篇
2009/08/30 Javascript
jQuery Lightbox 图片展示插件使用说明
2010/04/25 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
2010/11/20 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
jquery分隔Url的param方法(推荐)
2016/05/25 Javascript
Angularjs中使用轮播图指令swiper
2017/05/30 Javascript
Angular 向组件传递模板的两种方法
2018/02/23 Javascript
vue下拉菜单组件(含搜索)的实现代码
2018/11/25 Javascript
vue实现移动端悬浮窗效果
2018/12/01 Javascript
node.js学习笔记之koa框架和简单爬虫练习
2018/12/13 Javascript
JS实现计算小于非负数n的素数的数量算法示例
2019/02/26 Javascript
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
Typescript 中的 interface 和 type 到底有什么区别详解
2019/06/18 Javascript
javascript实现简易的计算器
2020/01/17 Javascript
关于angular 8.1使用过程中的一些记录
2020/11/25 Javascript
Python装饰器decorator用法实例
2014/11/10 Python
Django中对通过测试的用户进行限制访问的方法
2015/07/23 Python
python简单实例训练(21~30)
2017/11/15 Python
python 字典中文key处理,读取,比较方法
2018/07/06 Python
Python 输入一个数字判断成绩分数等级的方法
2018/11/15 Python
Keras设定GPU使用内存大小方式(Tensorflow backend)
2020/05/22 Python
html5构建触屏网站之touch事件介绍
2013/01/07 HTML / CSS
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
澳大利亚网上买书:Angus & Robertson
2019/07/21 全球购物
瀑布模型都有哪些优缺点
2014/06/23 面试题
会计专业毕业生推荐信
2013/11/05 职场文书
超市中秋节活动方案
2014/02/12 职场文书
2016寒假假期总结
2015/10/10 职场文书
python 开心网和豆瓣日记爬取的小爬虫
2021/05/29 Python
vue生命周期钩子函数以及触发时机
2022/04/26 Vue.js
Redis配置外网可访问(redis远程连接不上)的方法
2022/12/24 Redis