HSPでOpenCV試し
hspcvを使ってUSBカメラ画像のOpenCVでの顔認識をやってみた。
#右側のしきい値回転の表示は今後のために…。
もう少しオプション切り替えのボタンとかも付けて、hspcvの全体的なサンプルにしたいなー。
cvsel を行なっても反映されず、0バッファが対象となることがあるみたい。何か使い方が間違ってるのか?
#include "hspcv.as"
#module
#include "kernel32.as"
#defcfunc getmtime ; 時+分+秒+ミリ秒を整数値で返す(当ってますかね?年月日は省略)
dim SYSTEMTIME, 4
GetLocalTime varptr(SYSTEMTIME)
return int(strf("%02d", wpeek(SYSTEMTIME,8))+strf("%02d", wpeek(SYSTEMTIME,10))+strf("%02d", wpeek(SYSTEMTIME,12))+strf("%03d", wpeek(SYSTEMTIME,14)))
#global
onexit goto *exit ; 終了時の処理設定
title "HSPCVサンプル"
screen ,320*2+30,280
;dir="C:\\Program Files\\OpenCV\\data\\haarcascades\\"
dir="C:\\Program Files\\hsp31\\sample\\hspcv\\"
cvloadxml dir+"haarcascade_frontalface_alt2.xml" ; 顔認識パラメータ読み込み
cvcapture ; カメラ取り込み開始
cvbuffer 1,320,240 ; CV側処理バッファ用意
buffer 2 : buffer 3 ; HSP側画像バッファ用意
gsel 0 ; スクリーン側に戻しておく
cvsel 1 ; ←cvsel が効かない?
cvgetinfo x,1,CVOBJ_INFO_SIZEX
cvgetinfo y,1,CVOBJ_INFO_SIZEY
cvgetinfo ch,1,CVOBJ_INFO_CHANNEL
cvgetinfo bit,1,CVOBJ_INFO_BIT
pos 10,250
mes ""+x+","+y+","+ch+","+bit
angle=0 : size=1.0 : dsize=-0.05
t_fps=0 : t_tpf=0
repeat
t_start=getmtime()
redraw 0 ; 画面更新停止
cvgetcapture ; カメラ画像取り込み
cvsel 0 : cvflip ; 画像上下反転
cvsel 1 : cvcopy 0 ; 取り込み画像コピー
cvthreshold CV_THRESH_BINARY,65,255 ; 二値化
;cvconvert 0,1
;cvsmooth CV_BLUR,5,5
size=1
cvrotate angle,size : angle+=5 : if angle>=360 : angle=0 ; 画像回転
;size+=dsize : if (size>1.5)or(size<0.4) : dsize=-dsize
gsel 3 : cvgetimg 1 ;←cvsel が効かない?
gsel 0 : pos 10*2+320,10 : gcopy 3,0,0,320,240 ; 画像表示
cvfacedetect 0 : facenum=stat ; 顔検出
title ""+t_fps+"fps ("+t_tpf+"ms): "+"face="+facenum
gsel 2 : cvgetimg 0
gsel 0 : pos 10,10 : gcopy 2,0,0,320,240 ; 画像表示
if facenum>0 { ; 顔検出時の処理
color 255,0,0
repeat facenum
cvgetface x,y,sx,sy ; 呼び出し毎に次データ取得
x+=10 : y+=10
xx=x+sx : yy=y+sy
title ""+t_fps+"fps ("+t_tpf+"ms): "+"face="+facenum+"; "+x+","+y+","+sx+","+sy
line x ,y ,xx,y
line xx,y ,xx,yy
line x ,y ,x ,yy
line x ,yy,xx,yy
loop
}
redraw 1 ; 画面描画
t_end=getmtime()
t_tpf=t_end-t_start
t_fps=strf("%.1f", 1000.0/t_tpf)
await 0 ; 少し待つ
loop
gosub *exit
stop
*exit
cvendcapture ; キャプチャ終了
end
追記:
このプログラムを動かし続けていると、次のようなcvAllocでの「Out of memory」エラーが出た。どこか使い方が間違っているのかもしれん(毎回何かを解放する必要があるとか?)。
フレームの取得回数を測ってみるとコンピュータが変わっても10100~10200回目くらいでこのエラーが表示される。メモリの使用状況をタスクマネージャで見ていると、回数が進むにつれどんどん増えていき、260MBにまで達していた。
いろいろとコメントアウトしたりして試したところ、結局cvfacedetectを繰り返すとこの状況になることがわかった。その箇所だけ示すとこんな感じ。
#include "hspcv.as" onexit goto *exit ; 終了時の処理設定 title "HSPCVサンプル" screen ,320,240 dir="C:\\Program Files\\hsp31\\sample\\hspcv\" cvloadxml dir+"haarcascade_frontalface_alt2.xml" ; 顔認識パラメータ読み込み cvcapture ; カメラ取り込み開始 cvgetcapture repeat 20000 ;redraw 0 title ""+cnt ;cvgetcapture : cvflip : cvgetimg cvfacedetect ;redraw 1 await 0 loop *exit cvendcapture ; キャプチャ終了 end
Java版のOpenCVではこのような現象は起こらないようなので、おそらくHSP側のhspcv.dllあたりがおかしいんじゃないかなぁ…。
追記
hspsdk31中のhspcvのソースを眺めてみると、cvfacedetectでのstorageの解放が抜けてたようです。
--- hspsdk31/hspcv/main.cpp.org 2007-03-14 19:12:18.000000000 +0900 +++ hspsdk31/hspcv/main.cpp 2009-02-05 20:53:11.932000000 +0900 @@ -762,6 +762,7 @@ cvReleaseImage( &gray ); cvReleaseImage( &small_img ); + cvReleaseMemStorage( &storage ); return -cvface_total; }
HSPの掲示板に書き込んでみましたが、さて。
あとhspsdk関連でいくつか。
- hspsdk31.zip – download – HSPTV!
- MakeHPI – HSP開発wiki
- Let’s make plug-in for hsp3!! – HSP講座 HPI編 序章 – プログラ広場