前回は画像特徴点の抽出関数どもを使用。交通標識の識別を試みました。今回も「古典的」な画像認識の手法です。Haar Cascadeとな。画像の中から「お顔」に見えるような領域を検出するのに向いたカスケード構造の分類器らしいです。最近のカメラだったら出来て当然?の機能か。その昔デモ見たときはビクッリしたもんだが。
※「手習ひデジタル信号処理」投稿順 Indexはこちら
※Windows11上の Scilab2024.0.0およびScilab上のScilab IPCVツールボックスを使用させていただいております。
imdetectobjects関数
今回試用してみる関数は、imdetectobjects関数です。その名のとおり「オブジェクトを検出する」関数みたいです。複数のパラメータをとるのですが、最低以下の2つを与えなければなりませぬ。
-
- 第1引数、ソース画像
- 第2引数、XML形式の分類器のソースファイル
突然「XML形式の分類器のソースファイル」と言われても困るわな、と思いましたが、IPCVモジュールのインストールフォルダ内demosというフォルダ内にはこの目的に使用可能なXMLファイルが複数含まれております。今回、試用させていただく haar cascade アルゴリズム用と思われるファイルは以下の3つありました。
「三つもある」と思ったのはぬか喜びで サイズが同じ818KBの ~alt.xmlファイルと~alt2.xmlファイルはまったく同じファイルみたいです。何故お名前変えて2ファイル準備してあるのか意図は不明。またこの2つはどうもOpen CV付属のファイルじゃないかと思われます。
一方3番目の 50KB と妙にサイズの小さいファイルは上記2つとは異なるHaar分類器のソースみたいです。しかしこんなにサイズが小さくてちゃんと分類できるのか?やってみるしかありますまい。
なお、「お顔」の検出のターゲットになりそうな画像もちゃんと用意されてます。imagesフォルダ配下に
-
- people.jpg
- people2.jpg
Haar Cascadeの処理ステップ
処理は簡単っす。
-
- 検出ターゲット(ソース)画像をimread
- 使用する xml ファイル名(フルパス)を変数に入れておく
- imdetectobject関数の第1引き数にimreadした画像、第2引数に上記のxmlファイル名を与えて処理させる
- 上記関数は「お顔」として分類できた矩形領域を返してくるので最初の画像に重ねて矩形を描く(imrects)
こんな感じ。
S1 = imread(fullpath(getIPCVpath() + "/images/people.jpg")); cfn1 = fullpath(getIPCVpath() + "/demos/haarcascade_frontalface_alt.xml"); r11 = imdetectobjects(S1,cfn1); scf(); title('people-cfn1'); imshow(S1); imrects(r11,[0 255 0]);
処理結果
まずは people 画像に対して「大きい方」の分類器をかけた結果が以下に。
楽しそうだな。大学生かな?古の『合同ハイキング』的な?「今の若いもん」は『合ハイ』とか知らんよな。もしかすると縄文時代に遡る風習ぞなもし(お惚け老人の妄想デス。)肝心な「お顔」の検出は顔が半分隠れている1名様を除いて成功。
「小さい方」の分類器の結果は以下に。
「大きい方」と同様に検出できとる感じがします。しかし2つの画像を重ねてみると、微妙に「小さい方」の方が「お顔」の範囲が広めな結果を得ている場合がありそうです。気づかぬくらいの差なんじゃが。
つづいてpeople2画像に関する処理結果が以下に。左が「大きい」分類器。右が「小さい」分類器です。
「お顔」に関しては双方ちゃんと見つけているのだけれども、右の小さい方、赤矢印を書き込んでしまいましたが、青年の腰というかお腹のあたりを「お顔」だと誤認しているみたい。指に騙されたのか?知らんけど。