最近想做一个关于中文OCR的小系列,也是对之前做的东西的一个总结。作为这个系列的第一篇,我觉得还是有必要说一下关于中文字符图片分割的问题。因为现在开源的OCR代码比较多,相对而言对字符图片的分割的方法提的比较少,尤其是中文字符图片的分割还是有一定困难在里面的。
一、普遍使用的切割方法
现在大部分开源项目上用切割方法还是基于水平、垂直投影字符切割方法。
原理比较简单容易理解,也比较容易实现。先对一个文本图片进行水平投影,得到图片在垂直方向上的像素分布,有像素存在的区域即为文本所在区域;将该行文本切割下来,再对该行文本图片进行垂直投影,得到水平方向的像素分布,同理有像素存在的区域基本字符所在区域。
from PIL import Image
import numpy as np
min_thresh = 2 #字符上最少的像素点
min_range = 5 #字符最小的宽度
def vertical(img_arr):
h,w = img_arr.shape
ver_list = []
for x in range(w):
ver_list.append(h - np.count_nonzero(img_arr[:, x]))
return ver_list
def horizon(img_arr):
h,w = img_arr.shape
hor_list = []
for x in range(h):
hor_list.append(w - np.count_nonzero(img_arr[x, :]))
return hor_list
def OTSU_enhance(img_gray, th_begin=0, th_end=256, th_step=1):
max_g = 0
suitable_th = 0
for threshold in xrange(th_begin, th_end, th_step):
bin_img = img_gray > threshold
bin_img_inv = img_gray max_g:
max_g = g
suitable_th = threshold
return suitable_th
def cut_line(horz, pic):
begin, end = 0, 0
w, h = pic.size
cuts=[]
for i,count in enumerate(horz):
if count >= min_thresh and begin == 0:
begin = i
elif count >= min_thresh and begin != 0:
continue
elif count = 2:
cuts.append((end - begin, begin, end))
begin = 0
end = 0
continue
elif count 1 and cuts[1][0] in range(int(cuts[0][0] * 0.8), cuts[0][0]):
return 0, False
else:
crop_ax = (0, cuts[0][1], w, cuts[0][2])
img_arr = np.array(pic.crop(crop_ax))
return img_arr, True
def simple_cut(vert):
begin, end = 0,0
|