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的re模块正则表达式操作
May 25 Python
Pycharm技巧之代码跳转该如何回退
Jul 16 Python
详解Python 模拟实现生产者消费者模式的实例
Aug 10 Python
python模块之time模块(实例讲解)
Sep 13 Python
python中is与双等于号“==”的区别示例详解
Nov 21 Python
使用python将时间转换为指定的格式方法
Nov 12 Python
Pycharm连接远程服务器并实现远程调试的实现
Aug 02 Python
PyTorch笔记之scatter()函数的使用
Feb 12 Python
python excel多行合并的方法
Dec 09 Python
使用Python获取爱奇艺电视剧弹幕数据的示例代码
Jan 12 Python
python入门学习关于for else的特殊特性讲解
Nov 20 Python
Python的property属性详细讲解
Apr 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
PHPMyadmin 配置文件详解(配置)
2009/12/03 PHP
通过修改配置真正解决php文件上传大小限制问题(nginx+php)
2015/09/23 PHP
jQuery操作checkbox选择(list/table)
2013/04/07 Javascript
[JSF]使用DataModel处理表行事件的实例代码
2013/08/05 Javascript
让网页跳转到指定位置的jquery代码非书签
2013/09/06 Javascript
jQuery Ajax()方法使用指南
2014/11/19 Javascript
javascript抽象工厂模式详细说明
2014/12/16 Javascript
基于javascript、ajax、memcache和PHP实现的简易在线聊天室
2015/02/03 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
javascript实现根据时间段显示问候语的方法
2015/06/18 Javascript
javascript实现连续赋值
2015/08/10 Javascript
Bootstrap每天必学之媒体对象
2015/11/30 Javascript
AngularJs实现ng1.3+表单验证
2015/12/10 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
纯js实现手风琴效果代码
2020/04/17 Javascript
微信小程序 input表单与redio及下拉列表的使用实例
2017/09/20 Javascript
Vue-cropper 图片裁剪的基本原理及思路讲解
2018/04/17 Javascript
使用淘宝镜像cnpm安装Vue.js的图文教程
2018/05/17 Javascript
JavaScript简单实现动态改变HTML内容的方法示例
2018/12/25 Javascript
vue实现的仿淘宝购物车功能详解
2019/01/27 Javascript
BootstrapValidator实现表单验证功能
2019/11/08 Javascript
解决echarts图表使用v-show控制图表显示不全的问题
2020/07/19 Javascript
OpenLayers实现图层切换控件
2020/09/25 Javascript
[01:19:54]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#1Alliance VS EHOME
2016/03/03 DOTA
[01:13:17]Secret vs NB 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
跟老齐学Python之关于类的初步认识
2014/10/11 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
2017/02/16 Python
python绘制热力图heatmap
2020/03/23 Python
python实现人机五子棋
2020/03/25 Python
详解Python中如何将数据存储为json格式的文件
2020/11/18 Python
深入解析HTML5中的Blob对象的使用
2015/09/08 HTML / CSS
留学自荐信的技巧
2013/10/17 职场文书
《梅花魂》教学反思
2014/04/30 职场文书
教师拔河比赛广播稿
2014/10/14 职场文书
培训后的感想
2015/08/07 职场文书
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
2022/06/21 Golang