[Python / OpenCV] 画像認識
ゴール
画像の中から例えば「車がある/ない」「人間がある/ない」「犬がある/ない」など、
何か物体が画像のなかに存在しているかどうかを検知したい
OpenCV
機械学習で画像認識処理をするときによく使われるライブラリ
インスコ
① mkdir
でPJフォルダを作る
② フォルダ直下に移動
③ python -m venv venv
を実行する
④ .\venv\Scripts\activate
を実行し、仮想環境を構築
⑤ pip install opencv-python
でインストールする
ライブラリのインポート
import cv2
import numpy as np
cv2というのが今回のOpenCVのこと
numpyはPythonでの機械学習の計算をより速く、効率的に行えるようにする拡張モジュール
→つまり機械学習とか大量データを扱う、みたいなときによく使われるよ
※OpenCVをインストールすると一緒に自動でインストールされるよ
まずこれをやってみる
画像読み込み
img = cv2.imread('./Sample.jpg')
画像表示
cv2.imshow('Image', img)
cv2.waitKey()
imshow
の部分でポップアップで画像表示される
waitKey
で次のユーザーのアクションを待つ。例えばポップアップを×で閉じたら次に進む
Learn OpenCV
OpenCVの使い方などたくさんのっているところ
サンプルコードなど
Learn OpenCV にある Mask-RCNN をやってみる。
これに倣って。
ただし、今回は静止画で検知できればよいので、動画は省くとする①必要なもののインストール
READMEの「Download Code」ボタンを押せばおk
その下に書いてある wget もする必要あり
wget http://download.tensorflow.org/models/object_detection/mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
tar zxvf mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
②下記で画像から物体を検知できる
python3 mask_rcnn.py --image=画像パス
ChatGPTに解説させた。
argparse
標準ライブラリ。コマンドライン引数を扱いやすくしてくれるモジュール
ここで、さっき使った「--image」とかを設定できるようになる
cv.dnn.readNetFromTensorflow
Reads a network model stored in TensorFlow framework's format.
コメントには # Load the network
と書いてある
OpenCVにDNNモジュールというものがある
→OpenCVの中でもディープラーニングの推論機能を担当するモジュールのこと
→Tensorflowなどのサービスによってあらかじめ学習されているモデルを利用している
→つまりここでは、Tensorflowの該当モデルのネットワークモジュールを読んでる
サンプルソースでは、
net = cv.dnn.readNetFromTensorflow(modelWeights, textGraph);
とあるので、今後このネットワークモジュールの何かを使うときはnet.hogehoge
となる
独り言(そういえばC#でも機械学習できるってなんかで見たな)
cv.namedWindow
画像表示に使うウィンドウの設定はここでする
サンプルコードでは、「Mask-RCNN Object detection and Segmentation in OpenCV
というタイトルにするぜ」と設定してる
cv.VideoCapture
その名の通り、メディア(Videoって名前ついてるけど静止画もこれ)ファイルや映像を読み込めるように準備する(オブジェクト生成)
映像を取得する先のカメラを指定することもできるらしい
(今回はファイルパスを指定)
cap = cv.VideoCapture(args.image)
この宣言でファイルのオブジェクトができるので、以降の設定とか画像取得とかはcap
を使っていくことになる
cap.read()
ここで画像データを読み込んで第2戻り値に渡す
第1引数は、画像データの読み込みが成功したかどうか
→つまりサンプルコードだと
hasFrame, frame = cap.read()
となっているので、 frame
の方に肝心のデータを入れる、それが成功/失敗したかをhasFrame
で管理している、ということ
cv.waitKey
引数が0の場合キーイベントが発生するまで待機する
引数が正の数の場合、指定したミリ秒までキーイベントを待機する
→指定された時間が経過する前にキーが押されなかった場合、-1を返す
キーが押されたらキーのコードを返す
while cv.waitKey(1) < 0: の中身が所謂めいん関数のぶぶん
→つまり、キーが押されない場合(-1が返って来続ける場合)続行するということ
cv.dnn.blobFromImage
画像データから4Dのバイナリデータを取得する
Blob:バイナリ・ラージ・オブジェクト
net.setInput
ネットワークモジュールに、4Dバイナリにした画像データをセットする
net.forward
画像をフォワードパスに変換
モデルの入力から出力までの計算を実行し、予測結果や出力を得るために使用される
フォワードパス:モデルの入力データから出力を計算する過程
サンプルコードでは下記のようになっている
boxes, masks = net.forward(['detection_out_final', 'detection_masks'])
boxesは検出結果(境界ボックス)、masksはセグメンテーションマスクを格納している
postprocess関数
検出された物体の数でforしている
物体の信頼度の数値が、閾値より高ければ画像に物体の枠と信頼度を表示するようにしている
mscoco_labels.names
MSCOCOデータセットのラベルファイル
ここで、何を検知するかを設定できる。
Mask R-CNN(Mask Region-based Convolutional Neural Network)
これちゃんとした名前だったんだ(今更)
→物体検出とセグメンテーションのためのディープラーニングモデルの一種
高性能かつ簡単にできるのが ultralytics ってわけ(4行で済む…)
いったんこっちはクローズ
次は↓