目的
- レシートと背景が写った写真からレシートをくりぬきたい
- OpenCVの理解
- なんか画像処理っぽいことしたい
環境
- Windows11 Home
- VSCode
- Python3.9
- pip
opencv-python 4.5.5.62
【追記20220305:パラメータなど調整しました】
- グレースケール化の方法を変更 cv2.cvtColor→cv2.decolor
- 二値化のパラメータ変更 cv2.THRESH_OTSUに変更
- cv2.findContoursの引数を変更 cv2.RETR_TREE→cv2.RETR_EXTERNAL(ご意見いただきました。ありがとうございます。中の余計な線が消えました。)
本編
参考文献
ありがとうございます。お世話になりました
※0
※1
※2
※3
プログラム
元の画像
パンを買ってきました。その時のレシートをパシャリ
背景の影響とかありそうだな。。
グレースケール化
ちょっと変更。従来からある方法から最近できた方法(※2)でグレースケールしています。
# 2-1.グレースケール化
#gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray, _ = cv2.decolor(img)
save_image(filename+"2_gray", gray)
二値化
# 2-2.二値化
##ret, th1 = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
ret, th1 = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
save_image(filename+"2", th1)
案外うまくいっている?
輪郭抽出
# 3-1.輪郭抽出
#contours, hierarchy = cv2.findContours(th1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(th1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
# 3-2.面積の大きいもののみ選別
areas = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 50000:
## 輪郭の近似
epsilon = 0.08*cv2.arcLength(cnt,True) # <<==※3
approx = cv2.approxPolyDP(cnt,epsilon,True)
areas.append(approx)
cv2.drawContours(img,areas,-1,(0,255,0),3)
save_image(filename+"3", img)
おおっ!輪郭は描画された。
よく見ると輪郭は描画されてのですがなんか余計なものも描画されているな。。。。
改良の余地ありです。
パラメータ調整したらだいぶいい感じにできました。
つづく。。。