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实现JAVA源代码从ANSI到UTF-8的批量转换方法
Aug 10 Python
Python数据类型详解(一)字符串
May 08 Python
Python实现一个转存纯真IP数据库的脚本分享
May 21 Python
Python利用itchat对微信中好友数据实现简单分析的方法
Nov 21 Python
从头学Python之编写可执行的.py文件
Nov 28 Python
Python lambda函数基本用法实例分析
Mar 16 Python
图解Python变量与赋值
Apr 03 Python
使用python画个小猪佩奇的示例代码
Jun 06 Python
pybind11和numpy进行交互的方法
Jul 04 Python
PyCharm 2019.3发布增加了新功能一览
Dec 08 Python
windows10 pycharm下安装pyltp库和加载模型实现语义角色标注的示例代码
May 07 Python
python基于tkinter制作m3u8视频下载工具
Apr 24 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代码DOS造成用光网络带宽
2011/03/01 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
Yii 2中的load()和save()示例详解
2017/08/03 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
2019/10/08 PHP
PHP+Mysql分布式事务与解决方案深入理解
2021/02/27 PHP
Alliance vs AM BO3 第二场2.13
2021/03/10 DOTA
msn上的tab功能Firefox对childNodes处理的一个BUG
2008/01/21 Javascript
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
7个JS基础知识总结
2014/03/05 Javascript
浅谈利用JavaScript进行的DDoS攻击原理与防御
2015/06/04 Javascript
vue.js+boostrap项目实践(案例详解)
2016/09/21 Javascript
jQuery中的select操作详解
2016/11/29 Javascript
JS实现的tab切换选项卡效果示例
2017/02/28 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
JavaScript函数中的this四种绑定形式
2017/08/15 Javascript
在Vue组件化中利用axios处理ajax请求的使用方法
2017/08/25 Javascript
Vue起步(无cli)的啊教程详解
2019/04/11 Javascript
angular 表单验证器验证的同时限制输入的实现
2019/04/11 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
2019/10/11 Javascript
Python StringIO模块实现在内存缓冲区中读写数据
2015/04/08 Python
Python BS4库的安装与使用详解
2018/08/08 Python
Django REST框架创建一个简单的Api实例讲解
2019/11/05 Python
美国设计师精美珠宝购物网:Netaya
2016/08/28 全球购物
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
WiFi云数码相框:Nixplay
2018/07/05 全球购物
eBay奥地利站:eBay.at
2019/07/24 全球购物
Farfetch阿联酋:奢侈品牌时尚购物平台
2019/07/26 全球购物
如何进行有效的自我评价
2013/09/27 职场文书
学校大课间活动方案
2014/01/30 职场文书
授权委托书怎么写
2014/04/03 职场文书
学校地质灾害防治方案
2014/06/10 职场文书
个人工作能力自我评价
2015/03/05 职场文书
技术转让协议书
2016/03/19 职场文书
解决vue $http的get和post请求跨域问题
2021/06/07 Vue.js
MySQL普通表如何转换成分区表
2022/05/30 MySQL