前書き#
最近、カード上の数字認識を行っています。caffe モジュールを呼び出し、mnist モデルを使用していますが、この記事では caffe については説明しません。
画像に一連の前処理を行い、カード上の数字を分離する必要があります。OCR のような感じです。
今回使用したすべての opencv 関数を簡単に説明します。
1. 動画の読み込み cv2.VideoCapture ()#
引数 1:数字またはカメラの番号。またはビデオの名前。
カメラを使用する場合、フレームを繰り返し読み込むためにループを使用する必要があります。
c = cv2.VideoCapture(0)
while 1:
ret, image = c.read()
cv2.imshow("Origin", image) # 画像を表示
cv2.waitKey(1) # この行と一緒に使用する必要があります
2. 待機 cv2.waitKey ()#
引数 1:待機時間(ミリ秒)。
通常、cv2.imshow () と組み合わせて使用します。
もう一つの便利な機能は、キーを押すことで if 条件文に入ることです。
以下の例では、ESC キーを押してウィンドウを閉じ、ループを終了し、プログラムを終了します。
c = cv2.VideoCapture(0)
while 1:
ret, image = c.read()
cv2.imshow("Origin", image)
key = cv2.waitKey(1)
if key == 27:
cv2.destroyAllWindows()
break
3. 画像にテキストを追加 cv2.putText ()#
引数 1:画像
引数 2:テキストの内容
引数 3:座標位置
引数 4:フォント
引数 5:フォントサイズ
引数 6:色
引数 7:フォントの太さ
c = cv2.VideoCapture(0)
while 1:
ret, image = c.read()
cv2.putText(image, 'HandsomeHans', (220, 130), cv2.FONT_HERSHEY_SIMPLEX, 4, (127, 127, 255), 2)
cv2.imshow("Origin", image)
key = cv2.waitKey(1)
if key == 27:
cv2.destroyAllWindows()
break
4. 画像に枠を追加 cv2.rectangle ()#
引数 1:画像
引数 2:左上の座標
引数 3:右下の座標
引数 4:枠の色
引数 5:枠の太さ
5. 輪郭の抽出 cv2.findContours ()#
引数 1:画像
引数 2:抽出ルール。cv2.RETR_EXTERNAL:外部の輪郭のみを検出する。cv2.RETR_TREE:内部および外部の輪郭をすべて検出する。
引数 3:輪郭の出力形式。cv2.CHAIN_APPROX_SIMPLE:少数の輪郭点を出力する。cv2.CHAIN_APPROX_NONE:多数の輪郭点を出力する。
出力引数 1:画像
出力引数 2:輪郭のリスト
出力引数 3:階層構造
contours_map, contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
6. 輪郭を描画 cv2.drawContours ()#
引数 1:画像
引数 2:輪郭のリスト
引数 3:輪郭のインデックス。負の値の場合、すべての輪郭を描画します。
引数 4:輪郭の色
引数 5:輪郭の太さ
cv2.drawContours(image, contours, -1, (0, 0, 255), 2)
7. ピクセルが輪郭内にあるかどうかを判定する cv2.pointPolygonTest ()#
引数 1:輪郭のリスト
引数 2:ピクセルの座標
引数 3:True の場合、ピクセルから輪郭までの最短距離を出力します。False の場合、正の値は輪郭内、0 は輪郭上、負の値は輪郭外を表します。
result = cv2.pointPolygonTest(biggest, (w, h), False)
8. 輪郭の面積を計算する cv2.contourArea ()#
引数 1:輪郭
area = cv2.contourArea(contours[i])
9. 輪郭を包含する最小の矩形を求める cv2.minAreaRect ()#
引数 1:輪郭
出力引数 1:四角形の 4 つの角の座標と回転角度
最小の矩形を求め、描画します:
rect = cv2.minAreaRect(contours[i])
box = np.int0(cv2.boxPoints(rect)) # boxPoints()はopencv3の関数です
cv2.drawContours(image, [box], 0, (0, 255, 255), 2)
10. 輪郭を包含する矩形を求める cv2.boundingRect ()#
引数 1:輪郭
x, y, w, h = cv2.boundingRect(contours[i])
11. 画像の色変換 cv2.cvtColor ()#
引数 1:画像
引数 2:変換方法。cv2.COLOR_BGR2GRAY:グレースケールに変換。cv2.COLOR_BGR2HSV:HSV 色空間に変換。
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
12. ガウシアンフィルタリング cv2.GaussianBlur ()#
引数 1:画像
引数 2:フィルタのサイズ
引数 3:標準偏差
gray = cv2.GaussianBlur(gray, (3, 3), 0) # 画像をぼかす
13. メディアンフィルタリング cv2.medianBlur ()#
引数 1:画像
引数 2:フィルタのサイズ
gray = cv2.medianBlur(gray, 5) # 白いノイズを埋める
14. 画像の二値化 cv2.threshold ()#
引数 1:グレースケール画像
引数 2:閾値
引数 3:最大値
引数 4:変換方法 cv2.THRESH_BINARY、 cv2.THRESH_BINARY_INV、 cv2.THRESH_TRUNC、
cv2.THRESH_TOZERO、 cv2.THRESH_TOZERO_INV
ret, thres = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
15. 画像の拡張 cv2.copyMakeBorder ()#
引数 1:画像
引数 2:上部の拡張長さ
引数 3:下部の拡張長さ
引数 4:左側の拡張長さ
引数 5:右側の拡張長さ
引数 6:境界の種類:
BORDER_CONSTANT:定数、追加される値はすべて value 色 [value][value] | abcdef |
[value][value][value]
BORDER_REFLICATE:境界の色で埋める、 aaaaaa | abcdefg | gggg
BORDER_REFLECT:反射、abcdefg | gfedcbamn | nmabcd
BORDER_REFLECT_101:反射、上記と同様ですが、反射時に境界を開けます、abcdefg | egfedcbamne | nmabcd
BORDER_WRAP:このような方法で埋める abcdf | mmabcdf | mmabcd
引数 7:定数の値
iimgg = cv2.copyMakeBorder(num_thres, top, down, left, right, cv2.BORDER_CONSTANT, value=0)
16. 画像の回転 cv2.getRotationMatrix2D ()#
引数 1:回転の中心点
引数 2:回転角度
引数 3:スケールの大きさ
出力引数 1:回転行列
rotateMatrix = cv2.getRotationMatrix2D(center=(thres.shape[1]/2, thres.shape[0]/2), angle=rect[2], scale=1)
rotImg = cv2.warpAffine(thres, rotateMatrix, (thres.shape[1], thres.shape[0]))