实现步骤:

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)

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

Python + opencv 实现图片文字的分割的更多相关文章

  1. Python+OpenCV竖版古籍文字分割

    在做图片文字分割的时候,常用的方法有两种.一种是投影法,适用于排版工整,字间距行间距比较宽裕的图像:还有一种是用OpenCV的轮廓检测,适用于文字不规则排列的图像. 1. 思路 一开始想偷个懒,直接用 ...

  2. python opencv show图片,debug技巧

    debug的时候可以直接把图片画出来debug. imshow函数就是python opencv的展示图片的函数,第一个是你要起的图片名,第二个是图片本身.waitKey函数是用来展示图片多久的,默认 ...

  3. Python图像处理之图片文字识别(OCR)

    OCR与Tesseract介绍   将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR).可以实现OCR 的底层库并不多,目前很多库都是使用共同 ...

  4. python实现中文图片文字识别--OCR about chinese text--tesseract

    0.我的环境: win7 32bits python 3.5 pycharm 5.0 1.相关库 安装pillow: pip install pillow 安装tesseract: tesseract ...

  5. python opencv 读取图片 返回图片某像素点的b,g,r值

    转载:https://blog.csdn.net/weixin_41799483/article/details/80884682 #coding=utf-8   #读取图片 返回图片某像素点的b,g ...

  6. Python opencv resize图片并保存原有的图像比例

    参考链接:https://www.jianshu.com/p/3092835eab61 现有的图像是高瘦高瘦的,所以直接resize成矩形不合适.改变了整个结构. 所以采用的是先resize再padd ...

  7. Python OpenCV 显示图片,图片分类

    def divide_image(path,g_path1,g_path0): img_lst = os.listdir(path) for i in img_lst: print('类别1,类别0' ...

  8. 用 Python 和 OpenCV 检测图片上的条形码

      用 Python 和 OpenCV 检测图片上的的条形码 这篇博文的目的是应用计算机视觉和图像处理技术,展示一个条形码检测的基本实现.我所实现的算法本质上基于StackOverflow 上的这个问 ...

  9. Python人工智能之图片识别,Python3一行代码实现图片文字识别

    1.Python人工智能之图片识别,Python3一行代码实现图片文字识别 2.tesseract-ocr安装包和中文语言包 注意:

随机推荐

  1. 剑指Offer(二十五):复杂链表的复制

    剑指Offer(二十五):复杂链表的复制 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/bai ...

  2. 「每日五分钟,玩转JVM」:对象从哪来

    面向对象 众所周知,Java是一门面向对象的高级编程语言,那么现在问题来了,对象从哪来呢?有些人会说通过new关键字来创建一个对象,说的很好,本篇我们就来解密在new一个对象的过程中,JVM都给我们做 ...

  3. 关于turtle画蟒蛇小实例

    import turtle turtle.setup(800,600) turtle.pensize(25) turtle.pencolor('blue') turtle.penup() #抬笔 tu ...

  4. mysql登录的root密码问题

    先说下场景:官网上下载mysql-5.7.18-winx64包,解压,设置环境变量完毕,执行install等命令安装完毕,一切正常,并未发现有什么问题. 然后使用客户端连接数据库时,死活报错:ERRO ...

  5. safari打不开该网页,因为网址无效

    Safari打开导航时,提示:safari打不开该网页 因为网址无效 解决方法:安装百度地图

  6. CF - 652F Ants on a Circle

    题目传送门 题解: 先观察蚂蚁相撞, 可以发现, 如果我们将相撞的2个蚂蚁互换位置的话,蚂蚁相当于没有碰撞体积,直接穿过去了.所以我们可以直接计算出最终哪些位置上会有蚂蚁. 接下来就需要知道蚂蚁们的最 ...

  7. hdu 5945 Fxx and game(dp+单调队列! bc#89)

    Young theoretical computer scientist Fxx designed a game for his students. In each game, you will ge ...

  8. Codeforces 734C. Anton and Making Potions(二分)

    Anton is playing a very interesting computer game, but now he is stuck at one of the levels. To pass ...

  9. Gym 101964 题解

    B:Broken Watch (别问,问就是队友写的) 代码: import java.awt.List; import java.io.BufferedInputStream; import jav ...

  10. Elasticsearch(5) --- Query查询和Filter查询

    Elasticsearch(5) --- Query查询和Filter查询 这篇博客主要分为 :Query查询和Filter查询.有关复合查询.聚合查询也会单独写篇博客. 一.概念 1.概念 一个查询 ...