#include "stdafx.h"
#include<stdio.h>
#define SCALE 0.375 // 加工画像のサイズ倍率
#define WIDTH 320 // キャプチャ画像の横幅
#define HEIGHT 240 // キャプチャ画像の縦幅
#define THRESH_BOTTOM 0 // 色相値の下限の閾値
#define THRESH_TOP 96 // 色相値の上限の閾値
#define THRESHOLD_MAX_VALUE 255 // 2値化の際に使用する最大値
#define LAPLACIAN_APERTURE_SIZE 1 // Laplacianオペレータのサイズ
int main(int argc, char** argv){
int width_s = (int)(WIDTH*SCALE); // 縮小後の横幅
int height_s = (int)(HEIGHT*SCALE); // 縮小後の縦幅
int key; // キー入力用の変数
unsigned int nameCounter = 1; // ファイル名のカウンタ
char filename[32]; // ファイル名
CvCapture *capture = NULL; // カメラキャプチャ用の構造体
IplImage *frameImage; // キャプチャ画像用IplImage
char windowNameSource[] = "Source"; // キャプチャした画像を表示するウィンドウの名前
char windowNameHand[] = "HandImage"; // 肌色抽出した画像を表示するウィンドウの名前
char windowNameEdge[] = "EdgeImage"; // 輪郭抽出した画像を表示するウィンドウの名前
// 画像を生成する
IplImage *filteredImage = cvCreateImage(cvSize(WIDTH,HEIGHT),IPL_DEPTH_8U,3); // フィルタ用IplImage
IplImage *smallImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,3); // 縮小用IplImage
IplImage *backgroundImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 背景画像用IplImage
IplImage *grayImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // グレースケール画像用IplImage
IplImage *differenceImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 差分画像用IplImage
IplImage *hsvImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,3); // HSV画像用IplInmage
IplImage *hueImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 色相情報用IplImage
IplImage *saturationImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 彩度情報用IplImage
IplImage *valueImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 明度情報用IplImage
IplImage *thresholdImage1 = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 色相値がTHRES_BOTTOMより大きい領域用IplImage
IplImage *thresholdImage2 = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 色相値がTHRES_TOP以下の領域用IplImage
IplImage *thresholdImage3 = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // thresholdImage1とthresholdImage2のAND演算結果用IplImage
IplImage *handImage = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 顔領域の抽出結果用IplImage
IplImage *edgeImage16 = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_16S,1); // 輪郭抽出結果16ビット符号ありIplImage
IplImage *edgeImage8 = cvCreateImage(cvSize(width_s,height_s),IPL_DEPTH_8U,1); // 輪郭抽出結果8ビット符号なしIplImage
// カメラを初期化する
if((capture = cvCreateCameraCapture(-1)) == NULL){
// カメラが見つからなかった場合
printf("Cannot find a Webcamera.\n");
return -1;
}
// ウィンドウを生成する
cvNamedWindow(windowNameSource,CV_WINDOW_AUTOSIZE);
cvNamedWindow(windowNameEdge, CV_WINDOW_AUTOSIZE);
cvNamedWindow(windowNameHand, CV_WINDOW_AUTOSIZE);
// 初期画像を設定するためにカメラから画像取得
frameImage = cvQueryFrame(capture);
// 縮小処理
cvSmooth(frameImage,filteredImage,CV_GAUSSIAN,3,0,0,0);
cvResize(filteredImage,smallImage,CV_INTER_LINEAR);
// frameImageをグレースケール化し、背景画像とする
cvCvtColor(smallImage,backgroundImage,CV_BGR2GRAY);
// メインループ
while(1){
// カメラからの入力画像1フレームをframeImageに格納する
frameImage = cvQueryFrame(capture);
// 縮小処理
cvSmooth(frameImage,filteredImage,CV_GAUSSIAN,3,0,0,0);
cvResize(filteredImage,smallImage,CV_INTER_LINEAR);
// smallImageをグレースケール化したものを、grayImageに格納する
cvCvtColor(smallImage,grayImage,CV_BGR2GRAY);
// grayImageと背景画像との差分をとる
cvAbsDiff(grayImage,backgroundImage,differenceImage);
// smallImageをBGRからHSVに変換する
cvCvtColor(smallImage,hsvImage,CV_BGR2HSV);
// HSV画像をH,S,Vに分ける
cvSplit(hsvImage,hueImage,saturationImage,valueImage,NULL);
// 色相が肌色に近い部分を抽出、その部分のみ出力する
cvThreshold(hueImage,thresholdImage1,THRESH_BOTTOM,THRESHOLD_MAX_VALUE,CV_THRESH_BINARY);
cvThreshold(hueImage,thresholdImage2,THRESH_TOP,THRESHOLD_MAX_VALUE,CV_THRESH_BINARY_INV);
cvAnd(thresholdImage1,thresholdImage2,thresholdImage3,NULL);
// 背景差分画像と肌色領域とのANDをとる
cvAnd(differenceImage,thresholdImage3,handImage,NULL);
cvThreshold(handImage,handImage,12,THRESHOLD_MAX_VALUE,CV_THRESH_BINARY_INV);
if(handImage->origin == 0){
// 左上が原点の場合
cvFlip(handImage,handImage,0);
}
// Laplaceオペレータをかける
cvLaplace(handImage,edgeImage16,LAPLACIAN_APERTURE_SIZE);
// 16ビットの符号ありデータを8ビットの符号なしデータに変換する
cvConvertScaleAbs(edgeImage16,edgeImage8,1,0);
// 画像を表示する
cvShowImage(windowNameSource,frameImage);
cvShowImage(windowNameEdge,edgeImage8);
cvShowImage(windowNameHand,handImage);
// 's'キーで画像を保存
key = cvWaitKey(1);
if(key == 's'){
sprintf_s(filename,"capture_%04d.bmp",nameCounter); // ファイル名を設定
nameCounter++; // カウントアップ
cvSaveImage(filename,edgeImage8);
}else if(key == 'b'){
// 'b'キーが押されたら、その時点でのキャプチャ画像を背景画像とする
frameImage = cvQueryFrame(capture);
cvSmooth(frameImage,filteredImage,CV_GAUSSIAN,3,0,0,0);
cvResize(filteredImage,smallImage,CV_INTER_LINEAR);
cvCvtColor(smallImage,backgroundImage,CV_BGR2GRAY);
}else if(key == 'q'){
// 'q'キーが入力されたらループを抜ける
break;
}
// 9999枚で自動的に終了
if(nameCounter > 9999){
printf("pieces of capture images are 9,999.\n");
break;
}
}
// キャプチャを開放する
cvReleaseCapture(&capture);
// メモリを開放する
cvReleaseImage(&filteredImage);
cvReleaseImage(&smallImage);
cvReleaseImage(&backgroundImage);
cvReleaseImage(&grayImage);
cvReleaseImage(&differenceImage);
cvReleaseImage(&hsvImage);
cvReleaseImage(&hueImage);
cvReleaseImage(&saturationImage);
cvReleaseImage(&valueImage);
cvReleaseImage(&thresholdImage1);
cvReleaseImage(&thresholdImage2);
cvReleaseImage(&thresholdImage3);
cvReleaseImage(&handImage);
cvReleaseImage(&edgeImage16);
cvReleaseImage(&edgeImage8);
// ウィンドウを破棄する
cvDestroyWindow(windowNameSource);
cvDestroyWindow(windowNameEdge);
cvDestroyWindow(windowNameHand);
return 0;
}
以上の参考プログラムに挑戦していますが、試行錯誤しているのですが次のエラーが解決できません。
hadairorinkaku.exe の 0x773cb9bc で初回の例外が発生しました: Microsoft C++ の例外: cv::Exception (メモリの場所 0x0029f67c)。
hadairorinkaku.exe の 0x773cb9bc でハンドルされていない例外が発生しました: Microsoft C++ の例外: cv::Exception (メモリの場所 0x0029f67c)。
プログラム '[5276] hadairorinkaku.exe: ネイティブ' はコード -529697949 (0xe06d7363) で終了しました。
ご教授お願いいたします。