pythonで簡単画像物体認識!



画像認識ってなんかめちゃくちゃ難しそう・・・

って思いますよね。僕も思ってました。でも意外とやって見ると簡単です!

https://qiita.com/neriai/items/448a36992e308f4cabe2

のサイトが詳しく書いていただいて参考になったのですが2017年の記事で最新のOpenCVでは仕様が代わりエラーが出てしまいました。

公式の仕様を読んだところcv2.findContoursの返り値が2つから3つに変わっていることが原因でした。少しですが直しましたので下に乗っけときます。

OpneCVのダウンロード

pip install opencv-python


これはpipで簡単です。

早速プログラムです。

import cv2
import numpy as np


detect_contour(‘img.png')

# 画像を読込
src = cv2.imread(path, cv2.IMREAD_COLOR) #print (src)
# グレースケール画像へ変換
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 2値化
retval, bw = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 輪郭を抽出
#   contours : [領域][Point No][0][x=0, y=1]
#   cv2.CHAIN_APPROX_NONE: 中間点も保持する
#   cv2.CHAIN_APPROX_SIMPLE: 中間点は保持しない
img,contours, hierarchy = cv2.findContours(bw, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
 # 矩形検出された数(デフォルトで0を指定)
 detect_count = 0
 # 各輪郭に対する処理
 for i in range(0, len(contours)):
   # 輪郭の領域を計算
   area = cv2.contourArea(contours[i])
   # ノイズ(小さすぎる領域)と全体の輪郭(大きすぎる領域)を除外
   if area < 1e2 or 1e5 < area:
     continue
   # 外接矩形
   if len(contours[i]) > 0:
     rect = contours[i]
     x, y, w, h = cv2.boundingRect(rect)
     cv2.rectangle(src, (x, y), (x + w, y + h), (0, 255, 0), 2)
     detect_count = detect_count + 1
 # 外接矩形された画像を表示
 cv2.imshow('output', src)
 cv2.waitKey(0)
 # 終了処理
 cv2.destroyAllWindows()

説明

画像にはRed,Blue,Greenの要素があり全て0から255までの値をとります。写真の物体を認識するにはここまで白黒画像の(0,0,0)と(255,255,255)の値だけに変換したほうが計算量が少なく効率的に物体が認識出来るわけです。
こちらの画像を入力に物体認識をして行きます。

スクリーンショット 2020-05-08 0.02.44

結果がこちら

スクリーンショット 2020-05-08 0.02.53

結果を見るように全体的に精度の悪い結果となってしまいました。原因は画像の輪郭がはっきりしない場合や背景が濃かったりする場合、閾値処理をかけても輪郭が取れなかったり背景が残ってしまったりするのが原因であると考えられます。画像の場合、ネックレス、タバコは少女が身につけていて輪郭がはっきりしないです。これは平滑化などによる処理で緩和しないといけません。

もっと詳しく学びたい方へ

OpenCVのチュートリアルがこちらに載ってますので是非ご覧ください

http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_tutorials.html

この記事が気に入ったらサポートをしてみませんか?