152 lines
4.8 KiB
Python
152 lines
4.8 KiB
Python
# -*- coding: UTF-8 -*-
|
|
import cv2
|
|
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
import pytesseract
|
|
from PIL import Image
|
|
|
|
debug = 1
|
|
|
|
|
|
def preprocess(gray):
|
|
ret, binary = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)
|
|
ele = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 10))
|
|
dilation = cv2.dilate(binary, ele, iterations=1)
|
|
cv2.imwrite("binary.png", binary)
|
|
cv2.imwrite("dilation.png", dilation)
|
|
|
|
return dilation
|
|
|
|
|
|
def findTextRegion(img):
|
|
region = []
|
|
# 1. 查找轮廓
|
|
#image, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
|
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
|
# 2. 筛选那些面积小的
|
|
for i in range(len(contours)):
|
|
cnt = contours[i]
|
|
# 计算该轮廓的面积
|
|
area = cv2.contourArea(cnt)
|
|
|
|
# 面积小的都筛选掉
|
|
if (area < 300):
|
|
continue
|
|
|
|
# 轮廓近似,作用很小
|
|
epsilon = 0.001 * cv2.arcLength(cnt, True)
|
|
approx = cv2.approxPolyDP(cnt, epsilon, True)
|
|
|
|
# 找到最小的矩形,该矩形可能有方向
|
|
rect = cv2.minAreaRect(cnt)
|
|
if debug:
|
|
print("rect is: ", rect)
|
|
|
|
# box是四个点的坐标
|
|
box = cv2.boxPoints(rect)
|
|
box = np.int0(box)
|
|
|
|
# 计算高和宽
|
|
height = abs(box[0][1] - box[2][1])
|
|
width = abs(box[0][0] - box[2][0])
|
|
|
|
# 筛选那些太细的矩形,留下扁的
|
|
if (height > width * 1.2):
|
|
continue
|
|
# 太扁的也不要
|
|
if (height * 18 < width):
|
|
continue
|
|
if (width > img.shape[1] / 2 and height > img.shape[0] / 20):
|
|
region.append(box)
|
|
|
|
return region
|
|
|
|
|
|
def grayImg(img):
|
|
# 转化为灰度图
|
|
gray = cv2.resize(img, (img.shape[1] * 3, img.shape[0] * 3), interpolation=cv2.INTER_CUBIC)
|
|
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
|
|
retval, gray = cv2.threshold(gray, 120, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
|
|
return gray
|
|
|
|
|
|
def detect(img):
|
|
# fastNlMeansDenoisingColored(InputArray src, OutputArray dst, float h=3, float hColor=3, int templateWindowSize=7, int searchWindowSize=21 )
|
|
gray = cv2.fastNlMeansDenoisingColored(img, None, 10, 3, 3, 3)
|
|
coefficients = [0, 1, 1]
|
|
m = np.array(coefficients).reshape((1, 3))
|
|
gray = cv2.transform(gray, m)
|
|
if debug:
|
|
cv2.imwrite("gray.png", gray)
|
|
|
|
# 2. 形态学变换的预处理,得到可以查找矩形的图片
|
|
dilation = preprocess(gray)
|
|
|
|
# 3. 查找和筛选文字区域
|
|
region = findTextRegion(dilation)
|
|
|
|
# 4. 用绿线画出这些找到的轮廓
|
|
ii = 0
|
|
|
|
for box in region:
|
|
h = abs(box[0][1] - box[2][1])
|
|
w = abs(box[0][0] - box[2][0])
|
|
Xs = [i[0] for i in box]
|
|
Ys = [i[1] for i in box]
|
|
x1 = min(Xs)
|
|
y1 = min(Ys)
|
|
cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
|
|
if w > 0 and h > 0 and x1 < gray.shape[1] / 2:
|
|
idImg = grayImg(img[y1:y1 + h, x1:x1 + w])
|
|
cv2.imwrite(str(ii) + ".png", idImg)
|
|
break
|
|
ii += 1
|
|
|
|
if debug:
|
|
# 带轮廓的图片
|
|
cv2.imwrite("contours.png", img)
|
|
return idImg
|
|
|
|
|
|
def crop_image(img, tol=0):
|
|
mask = img < tol
|
|
return img[np.ix_(mask.any(1), mask.any(0))]
|
|
|
|
|
|
def ocrIdCard(imgPath, realId=""):
|
|
import os
|
|
# 获取 TESSDATA_PREFIX 环境变量的值
|
|
tessdata_prefix = os.environ.get('TESSDATA_PREFIX')
|
|
# 打印出 TESSDATA_PREFIX 环境变量的值
|
|
print("TESSDATA_PREFIX:", tessdata_prefix)
|
|
|
|
img = cv2.imread(imgPath, cv2.IMREAD_COLOR)
|
|
img = cv2.resize(img, (428, 270), interpolation=cv2.INTER_CUBIC)
|
|
idImg = detect(img)
|
|
image = Image.fromarray(idImg)
|
|
#tessdata_dir_config = '-c tessedit_char_whitelist=0123456789X --tessdata-dir "./"'
|
|
print("checking")
|
|
print(realId)
|
|
result = pytesseract.image_to_string(img, lang='chi_sim' )
|
|
#result = pytesseract.image_to_string(image, lang='chi_sim' )#ocrb,config=tessdata_dir_config,chi_sim
|
|
print(result)
|
|
# print(pytesseract.image_to_string(image, lang='eng', config=tessdata_dir_config))
|
|
if debug:
|
|
f, axarr = plt.subplots(2, 3)
|
|
axarr[0, 0].imshow(cv2.imread(imgPath))
|
|
axarr[0, 1].imshow(cv2.imread("gray.png"))
|
|
axarr[0, 2].imshow(cv2.imread("binary.png"))
|
|
axarr[1, 0].imshow(cv2.imread("dilation.png"))
|
|
axarr[1, 1].imshow(cv2.imread("contours.png"))
|
|
axarr[1, 2].set_title("exp:" + realId + "\nocr:" + result)
|
|
axarr[1, 2].imshow(cv2.imread("0.png"))
|
|
plt.show()
|
|
|
|
|
|
ocrIdCard("/Users/wangvivi/Desktop/Code/ocrtest/images/id_card.JPG", "11204416541220243X")
|
|
# ocrIdCard("test2.png", "430523197603204314")
|
|
# ocrIdCard("test3.png", "37030519820727311X")
|
|
# ocrIdCard("test4.png", "431023199205297212")
|
|
# ocrIdCard("test0.png", "445281198606095334")
|