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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Python+opencv实现图⽚⽂字的分割的⽅法⽰例
实现步骤:
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)
通过上⾯的⽔平投影,根据其⽩⾊⼩⼭峰的起始位置就可以界定出每⼀⾏的起始位置,从⽽把每⼀⾏分割出来。

获得每⼀⾏图像之后,可以对其进⾏垂直投影
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_
通过垂直投影可以获得每⼀个字符左右的起始位置,这样也就可以获得到每⼀个字符的具体坐标位置,即⼀个矩形框的位置。

下⾯是实现的全部代码:
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)
从分割的结果上看,基本上实现了图⽚中⽂字的分割。

但由于中⽂结构复杂性,对于⼀些⽂字的分割并不理想,⽐如“叶”、“桃”等字会出现过度分割现象;对于有粘连的两个字会出现分割不够的现象,⽐如上图中的“念想”。

不过可以从图像预处理(腐蚀),边界判断阈值的调整等⽅⾯进⾏优化。

以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档