python 进行图片识别,首先需要安装相应的Python库文件和识别引擎tesseract-ocr。
库文件:
1、pytesseract 图片识别库
2、numpy 矩阵库
3、PIL 图像处理库(仅支持到Python2.7)
4、Pillow 图像处理库(支持Python3.0以上)
一、Python 库文件安装方法:
1、命令行安装
pip install pytesseract
pip install Pillow
2、使用pycharm编辑器安装,具体步骤省略,大家可以百度一下。
二、图片识别引擎tesseract-ocr安装
软件名称:tesseract-ocr-setup-4.00.00dev.exe
下载地址:https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe
1、Tesseract是开源的OCR引擎。Tesseract最初设计用于英文识别,经过改进引擎和训练系统,它能够处理其它语言和UTF-8字符。Tesseract 3.0能够处理任何Unicode字符,但并非在所有语言上都工作得很好。Tesseract在庞大字符集语言(比如中文)上较慢,但是工作良好。
2、默认不支持中文,在软件安装时一定要选择chi_sim(简体中文),安装成后,可以在
定义字符集,引入相应的类库
# --- coding:UTF-8 ---
from skimage import io, data, morphology, segmentation
import numpy as np
from PIL import Image
import pytesseract
import os
# pytesser3.tesseract_exe_name="C:/Program Files (x86)/Tesseract-OCR/tesseract.exe"
#识别图片中的文字
def img_to_txt(file):
if os.path.exists(file):
image = Image.open(file)
# 英文
# vcode = pytesseract.image_to_string(image,"eng")
# txt = pytesser3.image_to_string(image, "chi_sim")
txt = pytesseract.image_to_string(image, "chi_sim")
print("{}识别内容:{}".format(file,txt))
for i in range(16):
img_file = r"img/pic_{}.jpg".format(i)
img_to_txt(img_file)
img_to_txt(r"img/abc.png")
img = io.imread("test.jpg",True) # as_grey=true 灰度图片
#二值化
bi_th=0.81
img[img<=bi_th]=0
img[img>bi_th]=1
io.imsave("gray.jpg",img)
膨胀腐蚀操作
def dil2ero(img,selem):
img=morphology.dilation(img,selem) # 膨胀
imgres=morphology.erosion(img,selem) # 腐蚀
return imgres
求图像中的横线和竖线
rows,cols=img.shape
scale=10 #这个值越大,检测到的直线越多,图片中字体越大,值应设置越小。需要灵活调整该参数。
col_selem=morphology.rectangle(cols//scale,1)
img_cols=dil2ero(img,col_selem)
row_selem=morphology.rectangle(1,rows//scale)
img_rows=dil2ero(img,row_selem)
线图
img_line=img_cols*img_rows
io.imsave("table.jpg",img_line)
点图
img_dot=img_cols+img_rows
img_dot[img_dot>0]=1
io.imsave("table_dot.jpg",img_dot)
收缩点团为单像素点(3×3)
def isolate(imgdot):
idx=np.argwhere(imgdot<1) # img值小于1的索引数组
rows,cols=imgdot.shape
for i in range(idx.shape[0]):
c_row=idx[i,0]
c_col=idx[i,1]
if c_col+1<cols and c_row+1<rows:
imgdot[c_row,c_col+1]=1
imgdot[c_row+1,c_col]=1
imgdot[c_row+1,c_col+1]=1
if c_col+2<cols and c_row+2<rows:
imgdot[c_row+1,c_col+2]=1
imgdot[c_row+2,c_col]=1
imgdot[c_row,c_col+2]=1
imgdot[c_row+2,c_col+1]=1
imgdot[c_row+2,c_col+2]=1
return imgdot
img_dot=isolate(img_dot)
io.imsave("table_dot_del.jpg",img_dot)
print(img_dot.shape) #显示尺寸
print(img_dot.shape[0]) #图片高度
print(img_dot.shape[1]) #图片宽度
# 表格点图
def get_dot(self):
self.img_dot2 = self.isolate(self.img_dot)
io.imsave("table_dot_del.jpg", self.img_dot2)
return self.img_dot2
# 分析表格
def fenxi_dots(self):
self.dot_idxs=np.argwhere(self.img_dot<1) # img_dot值等于0的索引数组
self.table_cols = [] #记录每行有几个单元格
table_rows = 1
table_row_index = self.dot_idxs[0][0] #第一行点图y值坐标
colu_dot = 0 # 单元格数量
for n,indx in enumerate(self.dot_idxs):
if indx[0] == table_row_index : # 如果点图y值坐标相同则为同一行
colu_dot = colu_dot + 1
print(indx,end=" ")
else :
if n < len(self.dot_idxs):
self.table_cols.append(colu_dot-1) # 将行单元格数量加入table_cols列表
# table_row_index = self.dot_idxs[n+1][0] #记录下一行位置索引
table_row_index = indx[0] # 点图y值坐标
colu_dot = 1 # 清0后,换行记录单元格数量
print("",end="\n")
print(indx, end=" ")
print("")
for n,v in enumerate(self.table_cols):
print("row{}:{}".format(n,v))
self.row_num = len(self.table_cols)
self.max_row = max(self.table_cols)
self.min_row = min(self.table_cols)
self.cell_nums = sum(self.table_cols)
print("这个表格一共{}行".format(self.row_num))
print("这个表格最多行单元格数:{}".format(self.max_row))
print("这个表格最少行单元格数:{}".format(self.min_row))
print("这个表格一共{}个单元格".format(self.cell_nums))
# go = input("表格分析是否正确?")
#
# if go == "no" :
# exit(0)
return self.dot_idxs,self.table_cols
# 开始识别单元格,分割表格图片
def split_table_pic(self):
# a_dots =[] #记录已经处理过的A点坐标
# cells = [] # 记录单元格的A点和D点坐标 [[a11,a12,d11,d12][a21,a22,d21,d22]]]
# cell_num = 0
#
# cell_a = []
# cell_b = []
# cell_c = []
# cell_d = []
cell_a_x = 0
cell_b_x = 0
cell_c_y = 0
if self.max_row == self.min_row : # 标准表格 n*m
for n,v in enumerate(self.table_cols):
print("row{}:".format(n),end= " ")
for i in range(v):
row_dot_num = v + 1
cell_num = n * row_dot_num
cell_a_index = cell_num + i
cell_b_index = cell_a_index + 1
cell_c_index = cell_a_index + row_dot_num
cell_d_index = cell_c_index +1
print("cell[{}]:a{} b{} c{} d{}".format(cell_num+i,self.dot_idxs[cell_a_index],
self.dot_idxs[cell_b_index],self.dot_idxs[cell_c_index],self.dot_idxs[cell_d_index]),end= " ")
x1=self.dot_idxs[cell_a_index][1]+1 # 加1去除列边框线
x2=self.dot_idxs[cell_b_index][1]
y1=self.dot_idxs[cell_a_index][0]+1 # 加1去除行边框线
y2=self.dot_idxs[cell_c_index][0]
#print(x1,x2,y1,y2)
roi=self.img2[y1:y2,x1:x2] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
# 分割原图并保存至img文件夹里,建议将图片保存为png格式,因为JPG不支持透明度
io.imsave("img/{}_{}.png".format(self.filename[:-4],cell_num+i),roi)
print("", end="\n")
else: # 非标准表格
for n,v in enumerate(self.table_cols):
print("row{}:".format(n),end= " ")
for i in range(v):
row_dot_num = v + 1
cell_num = n * row_dot_num
cell_a_index = cell_num + i
cell_b_index = cell_a_index + 1
cell_a_x = self.dot_idxs[cell_a_index][1]
cell_b_x = self.dot_idxs[cell_a_index][1]
cell_c_index = cell_a_index + row_dot_num
cell_d_index = cell_c_index +1
print("cell[{}]:a{} b{} c{} d{}".format(cell_num+i,self.dot_idxs[cell_a_index],
self.dot_idxs[cell_b_index],self.dot_idxs[cell_c_index],self.dot_idxs[cell_d_index]),end= " ")
x1=self.dot_idxs[cell_a_index][1]+1 # 加1去除列边框线
x2=self.dot_idxs[cell_b_index][1]
y1=self.dot_idxs[cell_a_index][0]+1 # 加1去除行边框线
y2=self.dot_idxs[cell_c_index][0]
#print(x1,x2,y1,y2)
roi=self.img2[y1:y2,x1:x2] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
# 分割原图并保存至img文件夹里,建议将图片保存为png格式,因为JPG不支持透明度
io.imsave("img/{}_{}.png".format(self.filename[:-4],cell_num+i),roi)
print("", end="\n")
识别分割后图片内容并写入EXCEL中
def write_excel(self,img_ocr_sel):
wbk = xlwt.Workbook()
sheet = wbk.add_sheet('sheet 1')
if img_ocr_sel == "BaiDu OCR":
for n, v in enumerate(self.table_cols):
for i in range(v):
# 当前行单元格数量
cur_row_cells = v + 1
# 图片序号
img_num = n * cur_row_cells + i
img_file = r"img/{}_{}.png".format(self.filename[:-4],img_num)
txt = self.baidu_img_to_txt(img_file) # 百度文字识别
if txt =="" : txt = "0"
sheet.write(n, i, txt) # 第n行第i列写入内容
else:
for n, v in enumerate(self.table_cols):
for i in range(v):
# 当前行单元格数量
cur_row_cells = v + 1
# 图片序号
img_num = n * cur_row_cells + i
img_file = r"img/{}_{}.png".format(self.filename[:-4],img_num)
txt = self.img_to_txt(img_file) #OCR 文字识别
if txt =="" : txt = "0"
sheet.write(n, i, txt) # 第n行第i列写入内容
wbk.save('{}.xls'.format(self.filename[:-4]))
print("success!")
self.msg.insert(self.mark, "\n\nsuccess!")
self.msg.see(self.see_end)
self.msg.update()