Pythonの画像処理ライブラリであるOpenCVを使って、レシートをトリミングしてみました。 今回はその時のメモです。 手順通りにやればほぼほぼうまくいくと思います。
環境
準備
# 仮想環境を作成
python3 -m venv opencv-demo
#仮想環境の立ち上げ
cd opencv-demo
source bin/activate
# opencv-pythonのインストール
# 41.2MBほどあるので注意
pip install opencv-python
# Python3の起動
python3
opencv-demo配下にトリミングしたいreceipt.jpgを配置します。 今回はネットで拾ったこの画像がやりやすかったので、使わせていただきます。
下のソースコードを実行します。
import os
import numpy as np
import cv2
filename = "receipt"
imp_filename = "receipt.jpg"
def transform_by4(img, points):
points = sorted(points, key=lambda x:x[1])
top = sorted(points[:2], key=lambda x:x[0])
bottom = sorted(points[2:], key=lambda x:x[0], reverse=True)
points = np.array(top + bottom, dtype='float32')
width = max(np.sqrt(((points[0][0]-points[2][0])**2)*2), np.sqrt(((points[1][0]-points[3][0])**2)*2))
height = max(np.sqrt(((points[0][1]-points[2][1])**2)*2), np.sqrt(((points[1][1]-points[3][1])**2)*2))
dst = np.array([
np.array([0, 0]),
np.array([width-1, 0]),
np.array([width-1, height-1]),
np.array([0, height-1]),
], np.float32)
trans = cv2.getPerspectiveTransform(points, dst)
return cv2.warpPerspective(img, trans, (int(width), int(height)))
im = cv2.imread(imp_filename)
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite(filename+'_gray.jpg', im_gray)
im_blur = cv2.fastNlMeansDenoising(im_gray)
im_th = cv2.adaptiveThreshold(im_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 5)
cv2.imwrite(filename+'_th.jpg', im_th)
cnts = cv2.findContours(im_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
cnts.sort(key=cv2.contourArea, reverse=True)
im_line = im.copy()
warp = None
for c in cnts[1:]:
arclen = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02*arclen, True)
if len(approx) == 4:
cv2.drawContours(im_line, [approx], -1, (0, 0, 255), 2)
if warp is None:
warp = approx.copy()
else:
cv2.drawContours(im_line, [approx], -1, (0, 255, 0), 2)
for pos in approx:
cv2.circle(im_line, tuple(pos[0]), 4, (255, 0, 0))
im_rect = transform_by4(im, warp[:,0,:])
cv2.imwrite(filename+'_rect.jpg', im_rect)
receipt_rect.jpgができあがって、 無事にレシートだけがトリミングできました!
今回は、OpenCVを使って、レシートをトリミングすることをやってみました 次回は、トリミングされた画像から、OCRをして文字を取得してみようと思います。
【追記】 次回の記事です!!!