Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

画像から数字(文字)の輪郭抽出 (pyhon 画像処理)

14日目 pyhon 画像処理

本日の課題と目標
手書き数字の輪郭をとる


今回はこちらのサイトを参考にさせていただきました


はじめに
前回の手書き数字認識でいろいろ試してみたのですが、正解率が思ったより良くありませんでした。原因は画像いっぱいに数字が書かれてないことだと気づき、どんな大きさで書いても画像いっぱいに調節できる機能を作りたいと考えました。


輪郭抽出のプログラム

import cv2

# 画像の読み込み
img = cv2.imread('the_image.jpg')

# 画像サイズを確認する場合
# print(img.shape)

# RGBからグレースケールに(白黒写真のように)変換
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)

# グレースケールから二値画像(白黒のみ)に変換
# thresholdの使い方
# [python title=”filter2Dメソッドの使い方”] cv2.threshold(img_src, thresh(閾値), 画素値の最大値, 二値化するためのタイプ)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
cv2.imshow('thresh', thresh)

# findContoursの使い方
# 輪郭,輪郭の階層情報 = cv2.findContours(入力画像,contour retrieval mode,輪郭検出するためのタイプ)
ctrs = cv2.findContours(thresh.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[0]

x1 = [] #x座標の最小値
y1 = [] #y座標の最小値
x2 = [] #x座標の最大値
y2 = [] #y座標の最大値
for i in range(1, len(ctrs)):
    # boundingRectの使い方
    # 外接矩形の左上の位置を(x,y),横と縦のサイズを(w,h), [x,y,w,h]で出力
    ret = cv2.boundingRect(ctrs[i])
    x1.append(ret[0])
    y1.append(ret[1])
    x2.append(ret[0] + ret[2])
    y2.append(ret[1] + ret[3])

    # 輪郭の一番外枠
    x1_min = min(x1)
    y1_min = min(y1)
    x2_max = max(x2)
    y2_max = max(y2)

# 輪郭を一番外枠で囲む
rect = cv2.rectangle(img, (x1_min, y1_min), (x2_max, y2_max), (0, 255, 0), 2)
# 輪郭の一番外枠で切り抜く場合
# rect = thresh[y1_min:y2_max, x1_min:x2_max]
cv2.imshow('rect', rect)

cv2.waitKey(0)
cv2.destroyAllWindows() 


OpenCVのインストール

pip install opencv-pythonでインストール
(opencv-contrib-pythonは、特許アルゴリズムが含まれているため商用利用が制限されている可能性があるので今回はこちらにしました)


参考サイト:
print(im.shape)で画像サイズが確認できます。

thresholdの使い方


こんなことも出来ます
実はこちらを先にやってしまったのですが利用方法はかなり限定的です。




文責:Reyl



保存ファイル:
lesson18.py
lesson19.py