KNN算法主程序
# -*-coding:utf-8-*-
# @Author: Phantom
# @编译环境:windows 10 + python3.8
# @IDE:Pycharm2021.1.3
import cv2.cv2 as cv
import numpy as np
import pytesseract
# 读取图片和身份证号位置模板
idimg = cv.imread("0033.jpg")
idimg = cv.resize(idimg, (509, 321), interpolation=cv.INTER_CUBIC)
idimgok = idimg.copy()
template = cv.imread("position1.jpg", 1)
cv.imshow("idimg", idimg)
# 转灰度图
gray = cv.cvtColor(idimg, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
# 黑帽运算闭运算的卷积核
kernel1 = np.ones((15, 15), np.uint8)
# kernel2 = np.ones((1,1),np.uint8)
# 黑帽运算
cvblackhat = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel1)
cv.imshow("black", cvblackhat)
# 闭运算
cvclose1 = cv.morphologyEx(cvblackhat, cv.MORPH_CLOSE, kernel1)
cv.imshow("cvclose", cvclose1)
# 原图像二值化
ref = cv.threshold(cvclose1, 0, 255, cv.THRESH_OTSU)[1]
# 身份证号码区域二值化
twoimg = cv.threshold(cvblackhat, 0, 255, cv.THRESH_OTSU)[1]
cv.imshow("ref", ref)
# 为了模板匹配
cv.imwrite("ref.jpg", ref)
ref = cv.imread("ref.jpg", 1)
# 获取模板高和宽
h, w = template.shape[:2]
# 模板匹配(相关匹配)找身份证号码位置
res = cv.matchTemplate(ref, template, cv.TM_CCORR)
# 获得最匹配地方的左上角坐标
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
top_left = max_loc
# 计算最匹配地方的右下角坐标
bottom_right = (top_left[0] + w, top_left[1] + h)
# 框出身份证号区域并展示
cv.rectangle(idimg, top_left, bottom_right, (0, 255, 0), 2)
cv.imshow("idimgOK", idimg)
# 展示身份证号码的二值图像
rectangleid = cv.resize(idimgok[top_left[1] - 2:bottom_right[1] + 2, top_left[0] - 2:bottom_right[0] + 2], (436, 36),
interpolation=cv.INTER_CUBIC)
# rectangleid = cv.erode(rectangleid,kernel2)
cv.imshow("rectangleid", rectangleid)
text = pytesseract.image_to_string(rectangleid)
print(text)
cv.waitKey(0)
KNN train训练程序:
# -*-coding:utf-8-*-
# @Author: Phantom
# @编译环境:windows 10 + python3.8
# @IDE:Pycharm2021.1.3
import cv2.cv2 as cv
import numpy as np
def KNN():
train = cv.imread("trainum.png", 0)
# 24*32
trainimgs = [train]
# 腐蚀和膨胀,增强训练集
for i in range(1,3):
kernel = np.ones((i, i), np.uint8)
j = cv.erode(train, kernel)
trainimgs.append(j)
r = cv.dilate(train, kernel)
trainimgs.append(r)
# 生成knn对象
knn = cv.ml.KNearest_create()
#训练knn模型
for trainimg in trainimgs:
cells = [np.hsplit(row, 30) for row in np.vsplit(trainimg, 11)]
x = np.array(cells)
# print(x[1][1])
trn = x[:, :].reshape(-1,768).astype(np.float32)
k = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
train_label = np.repeat(k,30)
knn.train(trn,cv.ml.ROW_SAMPLE,train_label)
cell = [np.hsplit(row, 30) for row in np.vsplit(train, 11)]
x = np.array(cell)
# print(x[1][1])
train = x[:, :].reshape(-1, 768).astype(np.float32)
t = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
train_label = np.repeat(t, 30)
return knn # ,train,train_label
def main():
knn ,train,train_label= KNN()
test = train.copy()
test_label = train_label.copy()
ret, result, neighbours, dist = knn.findNearest(test, 3)
right = 0
for i in range(330):
if result[i] == test_label[i]:
right+=1
# print(f'{len(test):}个测试数据识别正确{right:}个')
#计算正确率
ac = right/result.size
print(f'正确率{ac*100:.2f}%')
if __name__ == '__main__':
main()
cv.waitKey(0)
OCR算法主程序
# -*-coding:utf-8-*-
# @Author: Phantom
# @编译环境:windows 10 + python3.8
# @IDE:Pycharm2021.1.3
import cv2.cv2 as cv
import numpy as np
import pytesseract
# 读取图片和身份证号位置模板
idimg = cv.imread("0033.jpg")
idimg = cv.resize(idimg, (509, 321), interpolation=cv.INTER_CUBIC)
idimgok = idimg.copy()
template = cv.imread("position1.jpg", 1)
cv.imshow("idimg", idimg)
# 转灰度图
gray = cv.cvtColor(idimg, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
# 黑帽运算闭运算的卷积核
kernel1 = np.ones((15, 15), np.uint8)
# kernel2 = np.ones((1,1),np.uint8)
# 黑帽运算
cvblackhat = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel1)
cv.imshow("black", cvblackhat)
# 闭运算
cvclose1 = cv.morphologyEx(cvblackhat, cv.MORPH_CLOSE, kernel1)
cv.imshow("cvclose", cvclose1)
# 原图像二值化
ref = cv.threshold(cvclose1, 0, 255, cv.THRESH_OTSU)[1]
# 身份证号码区域二值化
twoimg = cv.threshold(cvblackhat, 0, 255, cv.THRESH_OTSU)[1]
cv.imshow("ref", ref)
# 为了模板匹配
cv.imwrite("ref.jpg", ref)
ref = cv.imread("ref.jpg", 1)
# 获取模板高和宽
h, w = template.shape[:2]
# 模板匹配(相关匹配)找身份证号码位置
res = cv.matchTemplate(ref, template, cv.TM_CCORR)
# 获得最匹配地方的左上角坐标
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
top_left = max_loc
# 计算最匹配地方的右下角坐标
bottom_right = (top_left[0] + w, top_left[1] + h)
# 框出身份证号区域并展示
cv.rectangle(idimg, top_left, bottom_right, (0, 255, 0), 2)
cv.imshow("idimgOK", idimg)
# 展示身份证号码的二值图像
rectangleid = cv.resize(idimgok[top_left[1] - 2:bottom_right[1] + 2, top_left[0] - 2:bottom_right[0] + 2], (436, 36),
interpolation=cv.INTER_CUBIC)
# rectangleid = cv.erode(rectangleid,kernel2)
cv.imshow("rectangleid", rectangleid)
text = pytesseract.image_to_string(rectangleid)
print(text)
cv.waitKey(0)
程序中所用到的图片
0033.jpg为标准身份证照片
position1.jpg
trainum.png