概要
レシートに対して入力されている文字の場所を取得する。
環境
- OpenCV-python Version: 4.1.0.25
- Python 3.6.8
- Windows 10
処理内容
- 画像の読み取り
- ガウシアンフィルタで画像の平滑化
- Laplacianを使った画像の勾配検出
- 大津の手法を使った画像の2値化
- モルフォロジー変換(クロージング)
- 純粋なクロージング
- Laplacianを使った画像の勾配検出
- 外接矩形
1. 画像の読み取り
text_detection.py
input_original_data = 'target_img.jpg'
img = cv2.imread(input_original_data)
h, s, gray = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2HSV))
2. ガウシアンフィルタで画像の平滑化
text_detection.py
size = (3, 3)
blur = cv2.GaussianBlur(gray, size, 0)
3. Laplacianを使った画像の勾配検出
text_detection.py
lap = cv2.Laplacian(blur, cv2.CV_8UC1)
※2値化で必要なためcv2.CV_8UC1にする
4. 大津の手法を使った画像の2値化
text_detection.py
ret2, th2 = cv2.threshold(lap, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
5. モルフォロジー変換(クロージング)
text_detection.py
kernel = np.ones((3, 20), np.uint8)
closing = cv2.morphologyEx(th2, cv2.MORPH_CLOSE, kernel)
※縦×横の配列は扱う画像により調整する
6. 純粋なクロージング
text_detection.py
kernel = np.ones((3, 3), np.uint8)
dilation = cv2.dilate(closing, kernel, iterations = 1)
erosion = cv2.erode(dilation, kernel, iterations = 1)
7. Laplacianを使った画像の勾配検出
text_detection.py
lap2 = cv2.Laplacian(erosion, cv2.CV_8UC1)
8. 外接矩形
text_detection.py
contours, hierarchy = cv2.findContours(lap2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
min_area = img.shape[0] * img.shape[1] * 1e-4
tmp = img.copy()
if len(contours) > 0:
for i, contour in enumerate(contours):
rect = cv2.boundingRect(contour)
if rect[2] < 10 or rect[3] < 10:
continue
area = cv2.contourArea(contour)
if area < min_area:
continue
cv2.rectangle(tmp, (rect[0], rect[1]), (rect[0]+rect[2], rect[1]+rect[3]), (0, 255, 0), 2)
まとめ
参考にした元のソースがpython以外で書かれていたため、アップされている画像と少し違う状態になっているが、だいたいやっていることは同じです。pythonベースで書かれているソースをgitに挙げています。
https://github.com/chibadai/data/blob/master/py/20190616/text_detection.py
その他
画像中からレシートのみを検出して最初に切り取りを行うことで検出の精度が上がったり、その後の文字検出なんかでも使えると思うので、論文の文字起こしとかで使えるかと。