%matplotlib inline
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 画像読込
img = cv2.imread("Figs/Matched_P.jpg")
# グレイスケール化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二値化
ret,th1 = cv2.threshold(gray,200,255,cv2.THRESH_BINARY)
# 輪郭抽出
image, contours, hierarchy = cv2.findContours(th1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 面積の大きいもののみ選別
areas = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 10000:
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
areas.append(approx)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
print(areas)
cv2.drawContours(img,areas,-1,(0,255,0),3)
plt.imshow(img)
plt.show()
dst = []
pts1 = np.float32(areas[0])
pts2 = np.float32([[600,300],[600,0],[0,0],[0,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(600,300))
plt.imshow(dst)
plt.show()
pyocr というOCRモジュールを使えば、画像から文字を読み取れるそうなので、試してみる
import pyocr
from PIL import Image
tools = pyocr.get_available_tools()
tool = tools[0]
print(tool.image_to_string(Image.fromarray(dst), lang="jpn"))
注意: デフォルトの環境では pyocrとそれを動かす環境ができていないので、以下をみて構築する。 なお、pip install pyocr は成功するが、それだけではダメ(tesseract-ocr tesseract-ocr-jpn* のinstallが必要) https://github.com/tesseract-ocr/tesseract/wiki
参考: http://73spica.tech/blog/tesseract_for_python/
解像度が低い文字画像だと認識上手くいかない
Image.fromarray(dst)
help(tool)
# 拡大してももとの画像が精度が低ければダメ
import pyocr
from PIL import Image
tools = pyocr.get_available_tools()
tool = tools[0]
size=dst.shape[:2]
im = cv2.resize(dst,(size[1]*2, size[0]*2),cv2.INTER_LANCZOS4)
print(tool.image_to_string(Image.fromarray(dst), lang="jpn"))
plt.imshow(im)
plt.show()
免許証(ぽいもの)で試す:画像はGoogle検索から拾ったもの
%matplotlib inline
import matplotlib.pyplot as plt
import cv2
img=cv2.imread("Figs/DriversCard2.jpg")
plt.imshow(img)
二値化に工夫が必要でしょう。Otsuか適応的な二値化が必要(免許証の場合背景が色付きですから、それも考慮して)なので、試す
import numpy as np
img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
plt.figure(figsize=(15,5))
for i in range(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
for i in range(4):
print('-'*50)
print(tool.image_to_string(Image.fromarray(images[i]), lang="jpn"))
print('-'*50)
どれもダメ。。。(適応的二値化処理ではパラメタ調整が必要)
# 少し解像度が良いもので試す: 785X380
%matplotlib inline
import matplotlib.pyplot as plt
import cv2
im=cv2.imread("Figs/DriversCard.jpg")
img = cv2.cvtColor(im,cv2.COLOR_RGB2BGR)
img = cv2.cvtColor(im,cv2.COLOR_RGB2GRAY)
dst = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,3) # パラメタ調整が必要
ret, otsu = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) # 大津の二値化
plt.figure(figsize=(15,5))
plt.subplot(131), plt.imshow(im),plt.xticks([]),plt.yticks([]),plt.title('Original Image')
plt.subplot(132),plt.imshow(dst,'gray'), plt.xticks([]),plt.yticks([]),plt.title('Adaptive Gaussian')
plt.subplot(133),plt.imshow(otsu,'gray'),plt.xticks([]),plt.yticks([]),plt.title('Otsu')
plt.show()
import pyocr
from PIL import Image
tools = pyocr.get_available_tools()
tool = tools[0]
print(tool.image_to_string(Image.fromarray(dst), lang="jpn"))
大津の二値化でも試してみる
import pyocr
from PIL import Image
tools = pyocr.get_available_tools()
tool = tools[0]
print(tool.image_to_string(Image.fromarray(otsu), lang="jpn"))