openCVを使用して、手のひらの画像を使って個人認証を行いたいのですが、なかなか進みません
手順として、画像入力→グレースケール変換→2値化→収縮・膨張→ラベリング→指の長さ計算
という手順で考えています。
膨張・収縮もうまい事できてはいないのですが、ラベリングが分からず困っています。
以下がプログラムです。
画像読み込みはUSBカメラ、openCV,Windows7,Visual C++を使用しています。
#include <stdio.h>
#include <highgui.h>
#include<cxcore.h>
#include<highgui.h>
#include<cv.h>
#define DEFAULT_H 22
#define DEFAULT_S 90
#define WIDTH 176
#define HEIGHT 144
#define THRESHOLD 128
#define THRESHOLD_MAX_VALUE 255
#define DILATIONS 3
#define EROSIONS 1
int main( int argc, char** argv ){
int key; // キー入力用の変数
int levels = 128;
CvCapture *capture; // カメラキャプチャ用の構造体
IplImage *frameImage; // キャプチャ画像用 IplImage
IplImage *sourceImage; // 元画像用 IplImage
IplImage *grayImage; // グレースケール画像用 IplImage
IplImage *binaryImage; // 2値化画像用 IplImage
char str[80];
char filename[256];
char windowNameSource[] = "Source"; // 元の画像を表示するウィンドウの名前
char windowNameCapture[] = "Capture"; // キャプチャした画像を表示するウィンドウの名前
char windowNameBinary[] = "Binary"; // 2値化した画像を表示するウィンドウの名前
char windowNameDila[] = "Dilation";
char windowNameEro[] = "Erosion";
int count = 0;
//char str[32];
if ( ( capture = cvCreateCameraCapture( -1 ) ) == NULL ) {
// カメラが見つからなかった場合
printf( "カメラが見つかりません\n" );
return -1;
}
// ウィンドウを生成する
cvNamedWindow( windowNameCapture,CV_WINDOW_AUTOSIZE );
printf("カメラ画像表示中\n\n");
printf("q キーを押すと終了します\n");
printf("s キーを押すと静止画保存します\n");
printf("o キーを押すと撮影した画像を表示します\n");
printf("b キーを押すと撮影した画像を2値化して表示します\n");
// CvSize sizeOfImage = cvGetSize( sourceImage ); //色空間変換結果の格納先確保
// メインループ
while ( 1 ) {
// カメラからの入力画像1フレームをframeImageに格納する
frameImage = cvQueryFrame( capture );
// 画像を表示する
cvShowImage( windowNameCapture, frameImage );
// 'q'キーが入力されたらループを抜ける
key = cvWaitKey( 1 );
if ( key == 'q' )
{
break;
}
else if ( key == 'o'){
cvNamedWindow( windowNameSource,CV_WINDOW_AUTOSIZE);
sourceImage = cvLoadImage("img.jpeg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
// cvCvtColor(sourceImage,grayImage,CV_BGR2GRAY);
cvShowImage( windowNameSource,sourceImage);
}
else if (key=='s'){
//sキーを押すと画像保存
// printf("登録する人の名前を入力して下さい>>" );
// scanf("%s",str);
sprintf(filename,"img.jpeg",count);
// sprintf(filename,"%s.jpeg",str,count);
cvSaveImage(filename,frameImage);
count++;
// printf("登録しました\n");
}
else if (key == 'b') {
//bキーを押すと撮影画像を2値化して表示する
cvNamedWindow(windowNameBinary,CV_WINDOW_AUTOSIZE);
cvNamedWindow(windowNameDila,CV_WINDOW_AUTOSIZE);
cvNamedWindow(windowNameEro,CV_WINDOW_AUTOSIZE);
sourceImage = cvLoadImage("img.jpeg",CV_LOAD_IMAGE_ANYDEPTH |CV_LOAD_IMAGE_ANYCOLOR);
IplImage *grayImage = cvCreateImage(cvSize(WIDTH,HEIGHT),IPL_DEPTH_8U,1);
IplImage *binaryImage = cvCreateImage(cvSize(WIDTH,HEIGHT),IPL_DEPTH_8U,1);
IplImage *dilationImage = cvCreateImage(cvSize(WIDTH,HEIGHT),IPL_DEPTH_8U,1);
IplImage *erosionImage = cvCreateImage(cvGetSize(sourceImage),IPL_DEPTH_8U,1);
cvCvtColor(sourceImage, grayImage,CV_BGR2GRAY);//sourceImageをグレースケール化
cvThreshold(grayImage,binaryImage,levels,THRESHOLD_MAX_VALUE,CV_THRESH_BINARY);//grayImageを2値化
cvErode(binaryImage,erosionImage,NULL,EROSIONS);
cvDilate(erosionImage,dilationImage,NULL,DILATIONS);
//cvDilate(binaryImage, dilationImage, NULL, DILATIONS);
//cvErode(dilationImage, erosionImage, NULL, EROSIONS);
sprintf(filename,"binary_img.jpeg",count);
cvSaveImage(filename,binaryImage);
count++;
cvShowImage(windowNameBinary,binaryImage);//2値化した画像の表示
cvShowImage(windowNameDila,dilationImage);//
cvShowImage(windowNameEro,erosionImage);
}
}
// キャプチャを解放する
cvReleaseCapture( &capture );
// ウィンドウを破棄する
cvDestroyWindow( windowNameCapture );
return 0;
}
画像の名前はimg.jpegを使用しています。
初めてで書き方も、至らない所があると思いますが。
よろしくお願いします。