test_opencv

3184 days ago by takepwave

Hiroshi TAKEMOTO (take@pwv.co.jp)

SageでOpenCVを使ってみよう

OpenCV 2.2以降はpythonとのインタフェースが提供されているので、これを使って SageからOpenCVを使ってみます。

OpenCVを使う準備

通常importするものはcvだけで良いのですが、ipl2npでcv2の関数を使っているので、 cv, cv2をimportします。

また、numpyは、npとしてimportして使用します。

import cv, cv2 import numpy as np # cvに未定義の値を設定 CV_LOAD_IMAGE_ANYDEPTH = 2 CV_LOAD_IMAGE_ANYCOLOR = 4 
       

IplImageからRGBのnumpy arrayに変換関数ipl2np

SageでOpenCVのマトリックスを表示するには、IplImageからRGBの numpy arrayに変換する必要があります。

ipl2np関数を以下のように定義します。

# cvのIplImageからRGBのnumpy arrayに変換する def ipl2np(ipl): mat = cv.GetMat(ipl) bgrimage = np.asarray(mat) rgbimage = cv2.cvtColor(bgrimage, cv2.COLOR_BGR2RGB) return rgbimage/255. 
       

顔検出

OpenCVと言えば「顔検出」ということで、 OpenCVで顔検出 を参考にしながら、SageでLenaの顔の枠を表示してみましょう。

この例では、OpenCVをCから使用する1.0のインタフェースを使用しています。 「詳解OpenCV」も1.0のインタフェースを使用しているので本と照らし合わせながら試すには 1.0の方がよいと思います。

ほとんどコメントの通りですが、以下の処理を行っています。

  • 検出対象の画像ファイルパス
  • 顔検出対象の画像データの読み込み
  • カスケードのファイルパスセット
  • カスケードのロード
  • 検出に必要なメモリストレージを用意する
  • 高速に顔認識するように引数を調整して、HaarDetectObjectsを呼び出す
  • 検出したオブジェクトのリストをセット

facesの戻り値は、((x, y, width, height), 何かの値)のような形式で返されるので、 ここでは、「何かの値」をdummyとして処理しています。

# 検出対象の画像ファイルパス tarFilePath = DATA + 'lena.jpg' # 顔検出対象の画像データの読み込み tarImg = cv.LoadImage(tarFilePath, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR) # カスケードのファイルパスセット cascadeFilePath = DATA + 'haarcascade_frontalface_alt.xml' # カスケードのロード cvHCC = cv.Load(cascadeFilePath) # 検出に必要なメモリストレージを用意する cvMStr = cv.CreateMemStorage(0) # 高速に顔認識するように引数を調整して、HaarDetectObjectsを呼び出す faces = cv.HaarDetectObjects(tarImg, cvHCC, cvMStr, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING) # 戻り値がOpenCVと違うみたいなので、プリントしてみる faces 
       
[((217, 203, 169, 169), 24)]
[((217, 203, 169, 169), 24)]

検出された顔の位置を矩形で表示

検出された顔の位置をOpenCVのRectangleを使って矩形で表示します。

# 検出情報から顔の位置情報を取得し、矩形を描画する for (x, y, width, height), dummy in faces: cv.Rectangle(tarImg, (x, y), (x + width, y + height), cv.CV_RGB(255, 0, 0), 2, cv.CV_AA, 0) 
       

Sageで画像と検出されたかおの位置を表示

ipl2np関数を使ってnumpyの配列に変換し、matrix_plot関数を使って画像を表示します。

# 検出した顔の矩形を合わせて表示 # 2015/08/09 aspect_ratio='automatic'オプションが必要 matrix_plot(ipl2np(tarImg), aspect_ratio='automatic').show( axes=True, frame=True, figsize=4, aspect_ratio='1') 
       

pythonインタフェースではリソースの解放関数がない

Cの場合には、メモリストレージやイメージを解放しますが、pythonインタフェースにはこれらを解放する 関数が見当たりません。