Python+opencv 实现图片文字的分割的方法示例


Posted in Python onJuly 04, 2019

实现步骤:

1、通过水平投影对图形进行水平分割,获取每一行的图像;

2、通过垂直投影对分割的每一行图像进行垂直分割,最终确定每一个字符的坐标位置,分割出每一个字符;

先简单介绍一下投影法:分别在水平和垂直方向对预处理(二值化)的图像某一种像素进行统计,对于二值化图像非黑即白,我们通过对其中的白点或者黑点进行统计,根据统计结果就可以判断出每一行的上下边界以及每一列的左右边界,从而实现分割的目的。

下面通过Python+opencv来实现该功能

首先来实现水平投影:

import cv2

import numpy as np

 

'''水平投影'''

def getHProjection(image):

 hProjection = np.zeros(image.shape,np.uint8)

 #图像高与宽

 (h,w)=image.shape 

 #长度与图像高度一致的数组

 h_ = [0]*h

 #循环统计每一行白色像素的个数

 for y in range(h):

  for x in range(w):

   if image[y,x] == 255:

    h_[y]+=1

 #绘制水平投影图像

 for y in range(h):

  for x in range(h_[y]):

   hProjection[y,x] = 255

 cv2.imshow('hProjection2',hProjection)

 

 return h_

 

if __name__ == "__main__":

 #读入原始图像

 origineImage = cv2.imread('test.jpg')

 # 图像灰度化 

 #image = cv2.imread('test.jpg',0)

 image = cv2.cvtColor(origineImage,cv2.COLOR_BGR2GRAY)

 cv2.imshow('gray',image)

 # 将图片二值化

 retval, img = cv2.threshold(image,127,255,cv2.THRESH_BINARY_INV)

 cv2.imshow('binary',img)

 #水平投影

 H = getHProjection(img)

Python+opencv 实现图片文字的分割的方法示例

通过上面的水平投影,根据其白色小山峰的起始位置就可以界定出每一行的起始位置,从而把每一行分割出来。

Python+opencv 实现图片文字的分割的方法示例

获得每一行图像之后,可以对其进行垂直投影

def getVProjection(image):

 vProjection = np.zeros(image.shape,np.uint8);

 #图像高与宽

 (h,w) = image.shape

 #长度与图像宽度一致的数组

 w_ = [0]*w

 #循环统计每一列白色像素的个数

 for x in range(w):

  for y in range(h):

   if image[y,x] == 255:

    w_[x]+=1

 #绘制垂直平投影图像

 for x in range(w):

  for y in range(h-w_[x],h):

   vProjection[y,x] = 255

 cv2.imshow('vProjection',vProjection)

 return w_

Python+opencv 实现图片文字的分割的方法示例

通过垂直投影可以获得每一个字符左右的起始位置,这样也就可以获得到每一个字符的具体坐标位置,即一个矩形框的位置。

下面是实现的全部代码:

import cv2

import numpy as np

 

'''水平投影'''

def getHProjection(image):

 hProjection = np.zeros(image.shape,np.uint8)

 #图像高与宽

 (h,w)=image.shape 

 #长度与图像高度一致的数组

 h_ = [0]*h

 #循环统计每一行白色像素的个数

 for y in range(h):

  for x in range(w):

   if image[y,x] == 255:

    h_[y]+=1

 #绘制水平投影图像

 for y in range(h):

  for x in range(h_[y]):

   hProjection[y,x] = 255

 cv2.imshow('hProjection2',hProjection)

 

 return h_

 

def getVProjection(image):

 vProjection = np.zeros(image.shape,np.uint8);

 #图像高与宽

 (h,w) = image.shape

 #长度与图像宽度一致的数组

 w_ = [0]*w

 #循环统计每一列白色像素的个数

 for x in range(w):

  for y in range(h):

   if image[y,x] == 255:

    w_[x]+=1

 #绘制垂直平投影图像

 for x in range(w):

  for y in range(h-w_[x],h):

   vProjection[y,x] = 255

 #cv2.imshow('vProjection',vProjection)

 return w_

 

if __name__ == "__main__":

 #读入原始图像

 origineImage = cv2.imread('test.jpg')

 # 图像灰度化 

 #image = cv2.imread('test.jpg',0)

 image = cv2.cvtColor(origineImage,cv2.COLOR_BGR2GRAY)

 cv2.imshow('gray',image)

 # 将图片二值化

 retval, img = cv2.threshold(image,127,255,cv2.THRESH_BINARY_INV)

 cv2.imshow('binary',img)

 #图像高与宽

 (h,w)=img.shape 

 Position = []

 #水平投影

 H = getHProjection(img)

 

 start = 0

 H_Start = []

 H_End = []

 #根据水平投影获取垂直分割位置

 for i in range(len(H)):

  if H[i] > 0 and start ==0:

   H_Start.append(i)

   start = 1

  if H[i] <= 0 and start == 1:

   H_End.append(i)

   start = 0

 #分割行,分割之后再进行列分割并保存分割位置

 for i in range(len(H_Start)):

  #获取行图像

  cropImg = img[H_Start[i]:H_End[i], 0:w]

  #cv2.imshow('cropImg',cropImg)

  #对行图像进行垂直投影

  W = getVProjection(cropImg)

  Wstart = 0

  Wend = 0

  W_Start = 0

  W_End = 0

  for j in range(len(W)):

   if W[j] > 0 and Wstart ==0:

    W_Start =j

    Wstart = 1

    Wend=0

   if W[j] <= 0 and Wstart == 1:

    W_End =j

    Wstart = 0

    Wend=1

   if Wend == 1:

    Position.append([W_Start,H_Start[i],W_End,H_End[i]])

    Wend =0

 #根据确定的位置分割字符

 for m in range(len(Position)):

  cv2.rectangle(origineImage, (Position[m][0],Position[m][1]), (Position[m][2],Position[m][3]), (0 ,229 ,238), 1)

 cv2.imshow('image',origineImage)

 cv2.waitKey(0)

Python+opencv 实现图片文字的分割的方法示例

从分割的结果上看,基本上实现了图片中文字的分割。但由于中文结构复杂性,对于一些文字的分割并不理想,比如“叶”、“桃”等字会出现过度分割现象;对于有粘连的两个字会出现分割不够的现象,比如上图中的“念想”。不过可以从图像预处理(腐蚀),边界判断阈值的调整等方面进行优化。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python函数缺省值与引用学习笔记分享
Feb 10 Python
python获取糗百图片代码实例
Dec 18 Python
Python中用pycurl监控http响应时间脚本分享
Feb 02 Python
Python下载指定页面上图片的方法
May 12 Python
Python编程实现从字典中提取子集的方法分析
Feb 09 Python
python将回车作为输入内容的实例
Jun 23 Python
python中的字符串内部换行方法
Jul 19 Python
Python+Pandas 获取数据库并加入DataFrame的实例
Jul 25 Python
python随机数分布random测试
Aug 27 Python
用pycharm开发django项目示例代码
Jun 13 Python
python模块和包的应用BASE_PATH使用解析
Dec 14 Python
Python实现自动签到脚本功能
Aug 20 Python
pandas 使用均值填充缺失值列的小技巧分享
Jul 04 #Python
Python使用sklearn库实现的各种分类算法简单应用小结
Jul 04 #Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
Jul 04 #Python
pandas取出重复数据的方法
Jul 04 #Python
Python使用sklearn实现的各种回归算法示例
Jul 04 #Python
python SQLAlchemy的Mapping与Declarative详解
Jul 04 #Python
pandas分区间,算频率的实例
Jul 04 #Python
You might like
PHP中最容易忘记的一些知识点总结
2013/04/28 PHP
Apache实现Web Server负载均衡详解(不考虑Session版)
2013/07/05 PHP
jquery 页面全选框实践代码
2010/04/02 Javascript
jQuery学习笔记(4)--Jquery中获取table中某列值的具体思路
2013/04/10 Javascript
JS实现黑色风格的网页TAB选项卡效果代码
2015/10/09 Javascript
jquery中live()方法和bind()方法区别分析
2016/06/23 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件的方法
2017/02/08 Javascript
vue router自动判断左右翻页转场动画效果
2017/10/10 Javascript
vue--点击当前增加class,其他删除class的方法
2018/09/15 Javascript
js序列化和反序列化的使用讲解
2019/01/19 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
vue 自定义右键样式的实例代码
2019/11/06 Javascript
JavaScript实现tab栏切换效果
2020/03/16 Javascript
Vue的全局过滤器和私有过滤器的实现
2020/04/20 Javascript
浅析Python中signal包的使用
2015/11/13 Python
python中异常捕获方法详解
2017/03/03 Python
Python实现excel转sqlite的方法
2017/07/17 Python
Python实现简单的HttpServer服务器示例
2017/09/25 Python
python多进程中的内存复制(实例讲解)
2018/01/05 Python
完美解决安装完tensorflow后pip无法使用的问题
2018/06/11 Python
Python3 关于pycharm自动导入包快捷设置的方法
2019/01/16 Python
python实现批量视频分帧、保存视频帧
2019/05/31 Python
tensorflow 报错unitialized value的解决方法
2020/02/06 Python
通过代码实例了解Python3编程技巧
2020/10/13 Python
Python和Bash结合在一起的方法
2020/11/13 Python
HTML5中的Article和Section元素认识及使用
2013/03/22 HTML / CSS
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
人事文员岗位职责
2014/02/16 职场文书
技校学生个人职业生涯规划范文
2014/03/03 职场文书
中学生纪念九一八事变演讲稿
2014/09/14 职场文书
2014年林业工作总结
2014/12/05 职场文书
2015年护理工作总结范文
2015/04/03 职场文书
电力培训学习心得体会
2016/01/11 职场文书
再次探讨go实现无限 buffer 的 channel方法
2021/06/13 Golang
聊聊Lombok中的@Builder注解使用教程
2021/11/17 Java/Android