記錄第一次用OpenCV做內容抓取
將抓取的結果拿出疑似身份證字號欄位的資訊用Tesseract做文字判讀
Source Code來源:Python+opencv+pytesseract实现身份证号码识别
對象為台灣身份證(但聽說要改版成晶片的了)
搜尋身份證辨識,有許多內地的公民證會出現,單一面就能顯示所有資訊實在非常便利
意指,未來台灣身份證將不會一面就一目了然,實在...(看錯重點XD)
但回到現行的身份證識別做一個記錄
主要以OpenCV抓台灣身份證上的身份證字號做練習
流程大概會是:
影像讀取 -- 調整圖像大小 -- 影像去噪 -- 圖像閾值處理 -- 膨脹框出圖像中的內容的輪廓 --尋找與身份證字號相似的大小輪廓 -- Tesseract文字辨識
用到的工具:PIL、pytesseract、cv2、numpy
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实现身份证号码识别