基于opencv的身份证识别(KNN与OCR两种算法)

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为标准身份证照片

基于opencv的身份证识别(KNN与OCR两种算法)

position1.jpg

基于opencv的身份证识别(KNN与OCR两种算法)

trainum.png

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年3月16日 下午12:30
下一篇 2022年3月16日 下午12:42

相关推荐