« WordPressプラグイン:iG:Synta... Main JavaでOpenCV »

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関連でいくつか。

Leave a comment

Your comment