[Python] OpenCV & Tesseract 辨識身份證

記錄第一次用OpenCV做內容抓取

將抓取的結果拿出疑似身份證字號欄位的資訊用Tesseract做文字判讀

Source Code來源:Python+opencv+pytesseract实现身份证号码识别 

對象為台灣身份證(但聽說要改版成晶片的了)

搜尋身份證辨識,有許多內地的公民證會出現,單一面就能顯示所有資訊實在非常便利

意指,未來台灣身份證將不會一面就一目了然,實在...(看錯重點XD)

但回到現行的身份證識別做一個記錄

主要以OpenCV抓台灣身份證上的身份證字號做練習

流程大概會是:

影像讀取 -- 調整圖像大小 -- 影像去噪 -- 圖像閾值處理 -- 膨脹框出圖像中的內容的輪廓 --尋找與身份證字號相似的大小輪廓 -- Tesseract文字辨識

用到的工具:PILpytesseractcv2numpy

from PIL import Image #version 3.2.0
import pytesseract as ocr #version 0.2.5
import cv2 #version 3.4.5
import numpy as np #version 1.15.2

1.影像讀取

這裡把影片讀取進來格式以預設「IMREAD_COLOR」
IMREAD_COLOR:讀入RGB三個波段格式
IMREAD_GRAYSCALE:讀入灰階格式
IMREAD_UNCHANGED:讀入原始圖片格式

#1.讀取影像
imgPath="image2.jpg"
img = cv2.imread(imgPath, cv2.IMREAD_COLOR)

2.調整圖像大小

改變尺吋:interpolation內插方式
CV_INTER_NEAREST :最鄰近插點法。
CV_INTER_LINEAR :雙線性插補(預設)。
CV_INTER_AREA :臨域像素再取樣插補。縮小用
CV_INTER_CUBIC :雙立方插補,4×4大小的補點。放大用
CV_INTER_LANCZOS4 :Lanczos插補,8×8大小的補點。

#2.調整圖像大小
img = cv2.resize(img, (428, 270), interpolation=cv2.INTER_CUBIC)

3.影像去噪

彩色圖片的噪點去除,並且拍照時可能會有歪歪斜斜的可能,需要轉正圖片

#3.影像去噪
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)

4.圖像閾值處理

閾值處理產生二值化圖片,框出文字區域,讓後面做形態轉變(澎脹或是腐蝕...)

#4.閾值 180  maxval:255
ret, binary = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)
ele = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 10))

5.膨脹文字區域

給二值化後的圖片與文字框們,將它們一一做膨脹處理

#5.膨脹操作
dilation = cv2.dilate(binary, ele, iterations=1)

6.尋找與身份證字號相似的大小輪廓

尋找之外,也把所找到的文子區域在原圖中框出來

#6.尋找與身份證字號相似的大小輪廓(contours)
image, contours, hierarchy = cv2.findContours(dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for box in contours:  
        i_index+=1
        h = abs(box[0][1] - box[2][1])
        w = abs(box[0][0] - box[2][0])
        max_point=box[3][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)
        img_gray=img[y1:y1 + h, x1:x1+w]
        # 取得每一個小輪廓二值化圖片
        idImg = cv2.resize(img_gray, (img_gray.shape[1] * 3, img_gray.shape[0] * 3), interpolation=cv2.INTER_CUBIC)
        idImg = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
        #otsu二值化操作
        retval, idImg = cv2.threshold(idImg , 120, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
        
        print("index:",str(i_index),"tag:",box,"high:",h,"width:",w)
        #抓到哪些輪廓
        cv2.imwrite("data\idImg_"+str(i_index)+".png", idImg)
        cv2.imwrite("data\contours.png", img)    
        #x軸在最右邊,且輪廓大於4倍視為身份證字號位置
        if (max_point>max_item and w//h>=4.0):
            max_item=max_point
            max_index=i_index

7.Tesseract文字辨識

事先要安裝Tesseract利用pytesseract去call exe起來跑

Tesseract可以自已訓練data,所以可以附在config 中去讀取

#圖片存在
if(idImg is not None):
        image = Image.fromarray(idImg)
        ocr.pytesseract.tesseract_cmd = r'Tesseract-OCR/tesseract.exe' 
        tessdata_dir_config = '--tessdata-dir "Tesseract-OCR\\tessdata"'
        result = ocr.image_to_string(image,config=tessdata_dir_config)
        if(result==""):
            print("don't know")
        else:
            print('the detect result is '+result)
        f, axarr = plt.subplots(2, 3)
        #open cv讀照片
        axarr[0, 0].imshow(cv2.imread(imgPath))
        axarr[0, 1].imshow(cv2.imread("data\gray.png"))
        axarr[0, 2].imshow(cv2.imread("data/binary.png"))
        axarr[1, 0].imshow(cv2.imread("data\dilation.png"))
        axarr[1, 1].imshow(cv2.imread("data\contours.png"))
        axarr[1, 2].imshow(cv2.imread("data\idImg_"+str(max_index)+".png"))
        plt.show()
    else:
        print('not found id')

 

參考來源:

Python+opencv+pytesseract实现身份证号码识别

Morphological Transformations