顔検出のOpenCVについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
抹茶
記事: 15
登録日時: 10年前

顔検出のOpenCVについて

#1

投稿記事 by 抹茶 » 9年前

今目を検出して矩形で囲むPGを作っているのですが、同一カメラからの映像をcaptureに取り、frameでは矩形ありの動画、frame3では矩形なしの素の動画を表示させたいと考えています。(capture2やframe2は別のカメラからの動画を取り込むので無視してください。)

それぞれ別のcapture関数を用意すると動作が重くなってしまったため、1つのcaptureからframe,frame3にそれぞれ割り振り、frameにのみ矩形を描画するようにしたつもりなのですがframe3にも矩形が描画されてしまいます。

何か改善する方法はありますか?

コード:

//サーマルカメラを考慮

#include <C:/opencv2411/build/include\opencv/highgui.h>
#include <C:/opencv2411/build/include\opencv/cv.h>

//opencvの関数名省略のため [cv::]省略
using namespace std;
using namespace cv;

int main(int argc, char* argv[]){
	

	CvCapture *capture = 0;
	CvCapture *capture2 = 0;
//	CvCapture *capture3 = 0;
	// フレーム単位データ
	IplImage *frame = 0;
	IplImage *frame2 = 0;
	IplImage *frame3 = 0;

	// 縦横サイズ
	double height = 240;
	double width = 320;
	// 入力キー受け付け用
	int c;
	int cnt = 0;

	///
	// eye検出器の読み込み
	CvHaarClassifierCascade* cvHCC2 = (CvHaarClassifierCascade*)cvLoad("C:/image/haarcascade_eye_tree_eyeglasses.xml");
	CvMemStorage* cvMStr2 = cvCreateMemStorage(0);
	CvSeq* eye;
	///

	// 0番号のカメラに対するキャプチャ構造体を生成するる
	capture = cvCreateCameraCapture (0);
	capture2 = cvCreateCameraCapture (1);
//	capture3 = cvCreateCameraCapture (0);
	
	// キャプチャのサイズを設定する。ただし、この設定はキャプチャを行うカメラに依存するので注意
	cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, width);
	cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, height);
	cvNamedWindow ("capture_face_detect", CV_WINDOW_AUTOSIZE);

	cvSetCaptureProperty (capture2, CV_CAP_PROP_FRAME_WIDTH, width);
	cvSetCaptureProperty (capture2, CV_CAP_PROP_FRAME_HEIGHT, height);
	cvNamedWindow ("capture_face_detect2", CV_WINDOW_AUTOSIZE);

	cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, width);
	cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, height);
	cvNamedWindow ("capture_face_detect3", CV_WINDOW_AUTOSIZE);

	///
	double fps = 5.0;
	CvVideoWriter* VideoWriter = cvCreateVideoWriter("testimage.avi", CV_FOURCC('D','I','B',' '), fps, cvSize(width, height), 1 );
	CvVideoWriter* VideoWriter2 = cvCreateVideoWriter("testimage2.avi", CV_FOURCC('D','I','B',' '), fps, cvSize(width, height), 1 );
	CvVideoWriter* VideoWriter3 = cvCreateVideoWriter("testimage3.avi", CV_FOURCC('D','I','B',' '), fps, cvSize(width, height), 1 );
	///

	// 停止キーが押されるまでカメラキャプチャを続ける
	while (1) {
		frame = cvQueryFrame (capture);
		frame2 = cvQueryFrame (capture2);
		frame3 = cvQueryFrame (capture);

		// 画像中から検出対象の情報を取得する

		eye = cvHaarDetectObjects(frame, cvHCC2, cvMStr2);

		if(eye != nullptr) cnt++;
		
		for (int i = 0; i < eye->total; i++) {

			// 検出情報から顔の位置情報を取得
			CvRect* eyeRect = (CvRect*)cvGetSeqElem(eye, i);
			
			cvRectangle(frame,
				cvPoint(eyeRect->x, eyeRect->y),
				cvPoint(eyeRect->x + eyeRect->width, eyeRect->y + eyeRect->height),
				CV_RGB(0, 255 ,0),
				3, CV_AA);
				
		}

		cvShowImage ("capture_face_detect", frame);
		cvWriteFrame(VideoWriter, frame);
		cvShowImage ("capture_face_detect2", frame2);
		cvWriteFrame(VideoWriter2, frame2);
		cvShowImage ("capture_face_detect3", frame3);
		cvWriteFrame(VideoWriter2, frame3);
		printf("%d\n",cnt);

		// 終了キー入力待ち(タイムアウト付き)
		c = cvWaitKey (1);
		if (c == 'e') {
			break;
		}
	}

	// 生成したメモリストレージを解放
	cvReleaseMemStorage(&cvMStr2);

	// キャプチャの解放
	cvReleaseCapture (&capture);
	cvReleaseCapture (&capture2);
//	cvReleaseCapture (&capture3);

	///
	cvReleaseVideoWriter(&VideoWriter);
	cvReleaseVideoWriter(&VideoWriter2);
	cvReleaseVideoWriter(&VideoWriter3);
	///
	
	// ウィンドウの破棄
	cvDestroyWindow("capture_face_detect");
	cvDestroyWindow("capture_face_detect2");
	cvDestroyWindow("capture_face_detect3");

	// カスケード識別器の解放
	cvReleaseHaarClassifierCascade(&cvHCC2);
	
	return 0;

}

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: 顔検出のOpenCVについて

#2

投稿記事 by usao » 9年前

以前のトピック
http://dixq.net/forum/viewtopic.php?f=3&t=17179
の時には気づきませんでしたが,frameに矩形描画してはならないように思います.
リファレンスでcvQueryFrame()を見ると

It is not allowed to modify or release the image! You can copy the frame using cvCloneImage() and
then do whatever you want with the copy.

と書かれています.


で,今回の件ですが,
frameとframe3が同じ値になっている(同一の画像バッファを指してる)とかいうことはないのでしょうか.

抹茶
記事: 15
登録日時: 10年前

Re: 顔検出のOpenCVについて

#3

投稿記事 by 抹茶 » 9年前

>>usaoさん
何度もありがとうございます。
指摘していただいて思いついたのですが、frameに対してcloneをつくり、処理前のframeを表示するものと処理後のcloneを表示させる方法にした結果うまくできました。
ありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る