国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

OpenCV-Python身份證信息識(shí)別

這篇具有很好參考價(jià)值的文章主要介紹了OpenCV-Python身份證信息識(shí)別。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

OpenCV-Python身份證信息識(shí)別

本篇文章使用OpenCV-Python和CnOcr來實(shí)現(xiàn)身份證信息識(shí)別的案例。想要識(shí)別身份證中的文本信息,總共分為三大步驟:一、通過預(yù)處理身份證區(qū)域檢測(cè)查找;二、身份證文本信息提?。蝗?、身份證文本信息識(shí)別。下面來看一下識(shí)別的具體過程CnOcr官網(wǎng)。識(shí)別過程視頻

前置環(huán)境

這里的環(huán)境需要安裝OpenCV-Python,Numpy和CnOcr。本篇文章使用的Python版本為3.6,OpenCV-Python版本為3.4.1.15,如果是4.x版本的同學(xué),可能會(huì)有一些Api操作不同。這些依賴的安裝和介紹,我就不在這里贅述了,均是使用Pip進(jìn)行安裝。

識(shí)別過程

首先,導(dǎo)入所需要的依賴cv2,numpy,cnocr并創(chuàng)建一個(gè)show圖像的函數(shù),方便后面使用:

import cv2
import numpy as np
from cnocr import CnOcr


def show(image, window_name):
    cv2.namedWindow(window_name, 0)
    cv2.imshow(window_name, image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
# 加載CnOcr的模型
ocr = CnOcr(model_name='densenet_lite_136-gru')

身份證區(qū)域查找

通過對(duì)加載圖像的灰度處理–>濾波處理–>二值處理–>邊緣檢測(cè)–>膨脹處理–>輪廓查找–>透視變換(校正)–>圖像旋轉(zhuǎn)–>固定圖像大小一系列處理之后,我們便可以清晰的裁剪出身份證的具體區(qū)域。

原始圖像

使用OpenCV的imread方法讀取本地圖片。

image = cv2.imread('card.png')
show(image, "image")

OpenCV-Python身份證信息識(shí)別

灰度處理

將三通道BGR圖像轉(zhuǎn)化為灰度圖像,因?yàn)橐幌翺penCV操作都是需要基于灰度圖像進(jìn)行的。

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
show(gray, "gray")

OpenCV-Python身份證信息識(shí)別

中值濾波

使用濾波處理,也就是模糊處理,這樣可以減少一些不需要的噪點(diǎn)。

blur = cv2.medianBlur(gray, 7)
show(blur, "blur")

OpenCV-Python身份證信息識(shí)別

二值處理

二值處理,非黑即白。這里通過cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU,使用OpenCV的大津法二值化,對(duì)圖像進(jìn)行處理,經(jīng)過處理后的圖像,更加清晰的分辨出了背景和身份證的區(qū)域。

threshold = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
show(threshold, "threshold")

OpenCV-Python身份證信息識(shí)別

邊緣檢測(cè)

使用OpenCV中最常用的邊緣檢測(cè)方法,Canny,檢測(cè)出圖像中的邊緣。

canny = cv2.Canny(threshold, 100, 150)
show(canny, "canny")

OpenCV-Python身份證信息識(shí)別

邊緣膨脹

為了使上一步邊緣檢測(cè)的邊緣更加連貫,使用膨脹處理,對(duì)白色的邊緣膨脹,即邊緣線條變得更加粗一些。

kernel = np.ones((3, 3), np.uint8)
dilate = cv2.dilate(canny, kernel, iterations=5)
show(dilate, "dilate")

OpenCV-Python身份證信息識(shí)別

輪廓檢測(cè)

使用findContours對(duì)邊緣膨脹過的圖片進(jìn)行輪廓檢測(cè),可以清晰的看到背景部分還是有很多噪點(diǎn)的,所需要識(shí)別的身份證部分也被輪廓圈了起來。

binary, contours, hierarchy = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
image_copy = image.copy()
res = cv2.drawContours(image_copy, contours, -1, (255, 0, 0), 20)
show(res, "res")

OpenCV-Python身份證信息識(shí)別

輪廓排序

經(jīng)過對(duì)輪廓的面積排序,我們可以準(zhǔn)確的提取出身份證的輪廓。

contours = sorted(contours, key=cv2.contourArea, reverse=True)[0]
image_copy = image.copy()
res = cv2.drawContours(image_copy, contours, -1, (255, 0, 0), 20)
show(res, "contours")

OpenCV-Python身份證信息識(shí)別

透視變換

通過對(duì)輪廓近似提取出輪廓的四個(gè)頂點(diǎn),并按順序進(jìn)行排序,之后通過warpPerspective對(duì)所選圖像區(qū)域進(jìn)行透視變換,也就是對(duì)所選的圖像進(jìn)行校正處理。

epsilon = 0.02 * cv2.arcLength(contours, True)
approx = cv2.approxPolyDP(contours, epsilon, True)
n = []
for x, y in zip(approx[:, 0, 0], approx[:, 0, 1]):
    n.append((x, y))
n = sorted(n)
sort_point = []
n_point1 = n[:2]
n_point1.sort(key=lambda x: x[1])
sort_point.extend(n_point1)
n_point2 = n[2:4]
n_point2.sort(key=lambda x: x[1])
n_point2.reverse()
sort_point.extend(n_point2)
p1 = np.array(sort_point, dtype=np.float32)
h = sort_point[1][1] - sort_point[0][1]
w = sort_point[2][0] - sort_point[1][0]
pts2 = np.array([[0, 0], [0, h], [w, h], [w, 0]], dtype=np.float32)

# 生成變換矩陣
M = cv2.getPerspectiveTransform(p1, pts2)
# 進(jìn)行透視變換
dst = cv2.warpPerspective(image, M, (w, h))
# print(dst.shape)
show(dst, "dst")

OpenCV-Python身份證信息識(shí)別

固定圖像大小

將圖像變正,通過對(duì)圖像的寬高進(jìn)行判斷,如果寬<高,就將圖像旋轉(zhuǎn)90°。并將圖像resize到指定大小。方便之后對(duì)圖像進(jìn)行處理。

if w < h:
    dst = np.rot90(dst)
resize = cv2.resize(dst, (1084, 669), interpolation=cv2.INTER_AREA)
show(resize, "resize")

OpenCV-Python身份證信息識(shí)別

檢測(cè)身份證文本位置

經(jīng)過灰度,二值濾波和開閉運(yùn)算后,將圖像中的文本區(qū)域主鍵顯現(xiàn)出來。

temp_image = resize.copy()
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
show(gray, "gray")
threshold = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
show(threshold, "threshold")
blur = cv2.medianBlur(threshold, 5)
show(blur, "blur")
kernel = np.ones((3, 3), np.uint8)
morph_open = cv2.morphologyEx(blur, cv2.MORPH_OPEN, kernel)
show(morph_open, "morph_open")

OpenCV-Python身份證信息識(shí)別

極度膨脹

給定一個(gè)比較大的卷積盒,進(jìn)行膨脹處理,使白色的區(qū)域加深加大。更加顯現(xiàn)出文本的區(qū)域。

kernel = np.ones((7, 7), np.uint8)
dilate = cv2.dilate(morph_open, kernel, iterations=6)
show(dilate, "dilate")

OpenCV-Python身份證信息識(shí)別

輪廓查找文本區(qū)域

使用輪廓查找,將白色塊狀區(qū)域查找出來。

binary, contours, hierarchy = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
resize_copy = resize.copy()
res = cv2.drawContours(resize_copy, contours, -1, (255, 0, 0), 2)
show(res, "res")

OpenCV-Python身份證信息識(shí)別

篩選出文本區(qū)域

經(jīng)過上一步輪廓檢測(cè),我們發(fā)現(xiàn),選中的輪廓中有一些噪點(diǎn),通過對(duì)圖像的觀察,使用近似輪廓,然后用以下邏輯篩選出文本區(qū)域。并定義文本描述信息,將文本區(qū)域位置信息加入到指定集合中。到這一步,可以清晰的看到,所需要的文本區(qū)域統(tǒng)統(tǒng)都被提取了出來。

labels = ['姓名', '性別', '民族', '出生年', '出生月', '出生日', '住址', '公民身份證號(hào)碼']
positions = []
data_areas = {}
resize_copy = resize.copy()
for contour in contours:
    epsilon = 0.002 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)
    x, y, w, h = cv2.boundingRect(approx)
    if h > 50 and x < 670:
        res = cv2.rectangle(resize_copy, (x, y), (x + w, y + h), (0, 255, 0), 2)
        area = gray[y:(y + h), x:(x + w)]
        blur = cv2.medianBlur(area, 3)
        data_area = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
        positions.append((x, y))
        data_areas['{}-{}'.format(x, y)] = data_area

show(res, "res")

OpenCV-Python身份證信息識(shí)別

對(duì)文本區(qū)域進(jìn)行排序

發(fā)現(xiàn)文本的區(qū)域是由下到上的順序,并且x軸從左到右的的區(qū)域是無序的,所以使用以下邏輯,對(duì)文本區(qū)域進(jìn)行排序

positions.sort(key=lambda p: p[1])
result = []
index = 0
while index < len(positions) - 1:
    if positions[index + 1][1] - positions[index][1] < 10:
        temp_list = [positions[index + 1], positions[index]]
        for i in range(index + 1, len(positions)):
            if positions[i + 1][1] - positions[i][1] < 10:
                temp_list.append(positions[i + 1])
            else:
                break
        temp_list.sort(key=lambda p: p[0])
        positions[index:(index + len(temp_list))] = temp_list
        index = index + len(temp_list) - 1
    else:
        index += 1
識(shí)別文本

對(duì)文本區(qū)域使用CnOcr一一進(jìn)行識(shí)別,最后將識(shí)別結(jié)果進(jìn)行輸出。

for index in range(len(positions)):
    position = positions[index]
    data_area = data_areas['{}-{}'.format(position[0], position[1])]
    ocr_data = ocr.ocr(data_area)
    ocr_result = ''.join([''.join(result[0]) for result in ocr_data]).replace(' ', '')
    # print('{}:{}'.format(labels[index], ocr_result))
    result.append('{}:{}'.format(labels[index], ocr_result))
    show(data_area, "data_area")

for item in result:
    print(item)
show(res, "res")

OpenCV-Python身份證信息識(shí)別

結(jié)語

通過以上的步驟,便成功的將身份證信息進(jìn)行了提取,過程中的一些數(shù)字參數(shù),可能會(huì)在不同的場(chǎng)景中有些許的調(diào)整。
以下放上所有的代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-443287.html

代碼

import cv2
import numpy as np
from cnocr import CnOcr

def show(image, window_name):
    cv2.namedWindow(window_name, 0)
    cv2.imshow(window_name, image)
    # 0任意鍵終止窗口
    cv2.waitKey(0)
    cv2.destroyAllWindows()


ocr = CnOcr(model_name='densenet_lite_136-gru')

image = cv2.imread('card.png')
show(image, "image")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
show(gray, "gray")
blur = cv2.medianBlur(gray, 7)
show(blur, "blur")
threshold = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
show(threshold, "threshold")
canny = cv2.Canny(threshold, 100, 150)
show(canny, "canny")
kernel = np.ones((3, 3), np.uint8)
dilate = cv2.dilate(canny, kernel, iterations=5)
show(dilate, "dilate")
binary, contours, hierarchy = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
image_copy = image.copy()
res = cv2.drawContours(image_copy, contours, -1, (255, 0, 0), 20)
show(res, "res")
contours = sorted(contours, key=cv2.contourArea, reverse=True)[0]
image_copy = image.copy()
res = cv2.drawContours(image_copy, contours, -1, (255, 0, 0), 20)
show(res, "contours")
epsilon = 0.02 * cv2.arcLength(contours, True)
approx = cv2.approxPolyDP(contours, epsilon, True)
n = []
for x, y in zip(approx[:, 0, 0], approx[:, 0, 1]):
    n.append((x, y))
n = sorted(n)
sort_point = []
n_point1 = n[:2]
n_point1.sort(key=lambda x: x[1])
sort_point.extend(n_point1)
n_point2 = n[2:4]
n_point2.sort(key=lambda x: x[1])
n_point2.reverse()
sort_point.extend(n_point2)
p1 = np.array(sort_point, dtype=np.float32)
h = sort_point[1][1] - sort_point[0][1]
w = sort_point[2][0] - sort_point[1][0]
pts2 = np.array([[0, 0], [0, h], [w, h], [w, 0]], dtype=np.float32)

M = cv2.getPerspectiveTransform(p1, pts2)
dst = cv2.warpPerspective(image, M, (w, h))
# print(dst.shape)
show(dst, "dst")
if w < h:
    dst = np.rot90(dst)
resize = cv2.resize(dst, (1084, 669), interpolation=cv2.INTER_AREA)
show(resize, "resize")
temp_image = resize.copy()
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
show(gray, "gray")
threshold = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
show(threshold, "threshold")
blur = cv2.medianBlur(threshold, 5)
show(blur, "blur")
kernel = np.ones((3, 3), np.uint8)
morph_open = cv2.morphologyEx(blur, cv2.MORPH_OPEN, kernel)
show(morph_open, "morph_open")
kernel = np.ones((7, 7), np.uint8)
dilate = cv2.dilate(morph_open, kernel, iterations=6)
show(dilate, "dilate")
binary, contours, hierarchy = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
resize_copy = resize.copy()
res = cv2.drawContours(resize_copy, contours, -1, (255, 0, 0), 2)
show(res, "res")
labels = ['姓名', '性別', '民族', '出生年', '出生月', '出生日', '住址', '公民身份證號(hào)碼']
positions = []
data_areas = {}
resize_copy = resize.copy()
for contour in contours:
    epsilon = 0.002 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, True)
    x, y, w, h = cv2.boundingRect(approx)
    if h > 50 and x < 670:
        res = cv2.rectangle(resize_copy, (x, y), (x + w, y + h), (0, 255, 0), 2)
        area = gray[y:(y + h), x:(x + w)]
        blur = cv2.medianBlur(area, 3)
        data_area = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
        positions.append((x, y))
        data_areas['{}-{}'.format(x, y)] = data_area

show(res, "res")

positions.sort(key=lambda p: p[1])
result = []
index = 0
while index < len(positions) - 1:
    if positions[index + 1][1] - positions[index][1] < 10:
        temp_list = [positions[index + 1], positions[index]]
        for i in range(index + 1, len(positions)):
            if positions[i + 1][1] - positions[i][1] < 10:
                temp_list.append(positions[i + 1])
            else:
                break
        temp_list.sort(key=lambda p: p[0])
        positions[index:(index + len(temp_list))] = temp_list
        index = index + len(temp_list) - 1
    else:
        index += 1
for index in range(len(positions)):
    position = positions[index]
    data_area = data_areas['{}-{}'.format(position[0], position[1])]
    ocr_data = ocr.ocr(data_area)
    ocr_result = ''.join([''.join(result[0]) for result in ocr_data]).replace(' ', '')
    # print('{}:{}'.format(labels[index], ocr_result))
    result.append('{}:{}'.format(labels[index], ocr_result))
    show(data_area, "data_area")

for item in result:
    print(item)
show(res, "res")

到了這里,關(guān)于OpenCV-Python身份證信息識(shí)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Python使用阿里API進(jìn)行身份證識(shí)別

    Python使用阿里API進(jìn)行身份證識(shí)別

    孟莉蘋,女,西安工程大學(xué)電子信息學(xué)院,2021級(jí)碩士研究生,張宏偉人工智能課題組 研究方向:機(jī)器視覺與人工智能 電子郵件:2425613875@qq.com 憑借領(lǐng)先的人工智能與知識(shí)圖譜技術(shù),對(duì)身份證正反面自動(dòng)識(shí)別,并提取姓名、出生日期、身份證號(hào)、住址、性別、民族、發(fā)證機(jī)關(guān)

    2024年02月07日
    瀏覽(23)
  • 用python從身份證中提取生日信息(切片計(jì)算)
  • 身份證識(shí)別ocr、身份證實(shí)名認(rèn)證接口文檔

    每一次驗(yàn)證背后,都是對(duì)用戶數(shù)據(jù)安全的承諾,對(duì)平臺(tái)信譽(yù)的堅(jiān)守。翔云身份證實(shí)名認(rèn)證API,通過身份證識(shí)別接口僅需一鍵上傳身份證圖片即可快速識(shí)別身份證信息,翔云實(shí)名認(rèn)證接口實(shí)時(shí)聯(lián)網(wǎng)查驗(yàn)證件信息的真?zhèn)巍??PHP身份證實(shí)名認(rèn)證接口文檔代碼如下:

    2024年04月17日
    瀏覽(116)
  • 小程序OCR身份證識(shí)別

    使用兩種OCR識(shí)別:小程序和騰訊云 1.基于微信小程序OCR插件實(shí)現(xiàn)身份證拍照、上傳并OCR識(shí)別的示例: 首先,在小程序中添加身份證拍照的功能,可以使用wx.chooseImage()選擇照片并使用wx.uploadFile()上傳,代碼如下: 將上傳的照片傳到服務(wù)器端后,使用小程序OCR插件進(jìn)行身份證識(shí)

    2024年02月07日
    瀏覽(96)
  • 調(diào)用移動(dòng)云OCR識(shí)別身份證

    調(diào)用移動(dòng)云OCR識(shí)別身份證

    在下面這個(gè)網(wǎng)址開通免費(fèi)服務(wù),,每個(gè)賬號(hào)可免費(fèi)使用500次,先要實(shí)名認(rèn)證。? 通用文字識(shí)別 (10086.cn) https://ecloud.10086.cn/home/product-introduction/Generalverify 有兩種方式: 這里選擇第二種?。 Python_SDK下載 (10086.cn) https://ecloud.10086.cn/op-help-center/doc/article/40776 然后在pycharm中打開上面下

    2024年02月01日
    瀏覽(89)
  • 調(diào)用華為API實(shí)現(xiàn)身份證識(shí)別

    調(diào)用華為API實(shí)現(xiàn)身份證識(shí)別

    雷千龍,男,西安工程大學(xué)電子信息學(xué)院,2022級(jí)研究生 研究方向:機(jī)器視覺與人工智能 電子郵件:2387360343@qq.com 張思怡,女,西安工程大學(xué)電子信息學(xué)院,2022級(jí)研究生,張宏偉人工智能課題組 研究方向:機(jī)器視覺與人工智能 電子郵件:981664791@qq.com 2.1.1OCR簡(jiǎn)介 OCR (Optica

    2024年02月06日
    瀏覽(35)
  • uniapp小程序引入身份證識(shí)別、營(yíng)業(yè)執(zhí)照識(shí)別

    uniapp小程序引入身份證識(shí)別、營(yíng)業(yè)執(zhí)照識(shí)別

    首先去微信服務(wù)市場(chǎng)? 下滑 找到微信證件OCR識(shí)別 點(diǎn)擊購買 ? 選擇你的小程序 可以在我的訂單 -- 開發(fā)者資源 -- 使用中 看到 然后直接copy代碼? 就大功告成! 想了解參數(shù)意思? 看文檔 ? 請(qǐng)注意---- 我們是直接調(diào)用微信OcrAllInOne接口,而不是使用微信Ocr插件,因此像其他文章,

    2024年03月18日
    瀏覽(21)
  • 微信小程序?qū)崿F(xiàn)身份證識(shí)別-ocr

    微信小程序?qū)崿F(xiàn)身份證識(shí)別-ocr

    ? ? 項(xiàng)目中有一個(gè)識(shí)別身份證的需求,經(jīng)過調(diào)研,最后決定使用微信小程序ocr插件進(jìn)行開發(fā)。 一:首先登錄小程序公眾平臺(tái)。 1:進(jìn)入設(shè)置 第三方設(shè)置。 ? 2:添加ocr插件。 3:添加完后,需要領(lǐng)取免費(fèi)額度,100次/天。? https://fuwu.weixin.qq.com/service/detail/000ce4cec24ca026d37900ed551415 ?注意

    2024年01月16日
    瀏覽(87)
  • Java集成騰訊云OCR身份證識(shí)別接口

    Java集成騰訊云OCR身份證識(shí)別接口

    ? ? ? ? 項(xiàng)目用到身份證識(shí)別獲取人員信息的功能,于是想到了騰訊云提供這樣的API。在整合代碼過程都很順利,利用騰訊云官方SDK很快集成進(jìn)來。但是在上測(cè)試環(huán)境部署時(shí)有了新的問題,通過Nginx代理后的環(huán)境無法訪問到目標(biāo)騰訊云接口,遂有了如下的改造過程。 ? ? ? ?

    2024年02月08日
    瀏覽(96)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包