OpenCV2.4.6で色抽出を行いたい。
Webカメラから取得した映像を用いて色抽出を行いたいです。
システム開発はVisual Studio 2012で言語はC++です。
OpenCV2.4.6を利用しているのですが、サンプルプログラムが古いバージョンで、OpenCV2.4.6では動かないので以下のプログラムを改良したいです。
参考にしたサイトはこちらです。
http://d.hatena.ne.jp/wah-wah-hawah/20090325/1237996168
以下プログラム
#include <cv.h>
#include <highgui.h>
void GetMaskHSV(IplImage* src, IplImage* mask,int erosions, int dilations)
{
int x = 0, y = 0;
uchar H, S, V;
uchar minH, minS, minV, maxH, maxS, maxV;
CvPixelPosition8u pos_src, pos_dst;
uchar* p_src;
uchar* p_dst;
IplImage* tmp;
tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
//HSVに変換
cvCvtColor(src, tmp, CV_RGB2HSV);
CV_INIT_PIXEL_POS(pos_src, (unsigned char*) tmp->imageData,
tmp->widthStep,cvGetSize(tmp), x, y, tmp->origin);
CV_INIT_PIXEL_POS(pos_dst, (unsigned char*) mask->imageData,
mask->widthStep, cvGetSize(mask), x, y, mask->origin);
minH = 100; maxH = 115;
minS = 80; maxS = 255;
minV = 120; maxV = 255;
for(y = 0; y < tmp->height; y++) {
for(x = 0; x < tmp->width; x++) {
p_src = CV_MOVE_TO(pos_src, x, y, 3);
p_dst = CV_MOVE_TO(pos_dst, x, y, 3);
H = p_src[0]; //0から180
S = p_src[1];
V = p_src[2];
if( minH <= H && H <= maxH &&
minS <= S && S <= maxS &&
minV <= V && V <= maxV
) {
p_dst[0] = 255;
p_dst[1] = 255;
p_dst[2] = 255;
} else {
p_dst[0] = 0;
p_dst[1] = 0;
p_dst[2] = 0;
}
}
}
if(erosions > 0) cvErode(mask, mask, 0, erosions);
if(dilations > 0) cvDilate(mask, mask, 0, dilations);
cvReleaseImage(&tmp);
}
int main(int argc, char **argv)
{
int c;
CvCapture* capture = 0;
IplImage* frame = 0;
IplImage* mask = 0;
IplImage* dst = 0;
if(argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit(argv[1][0])))
capture = cvCreateCameraCapture(argc == 2 ? argv[1][0] - '0' : 0);
frame = cvQueryFrame(capture);
mask = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);
dst = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3);
cvNamedWindow("src", CV_WINDOW_AUTOSIZE);
cvNamedWindow("dst", CV_WINDOW_AUTOSIZE);
while(1) {
frame = cvQueryFrame(capture);
GetMaskHSV(frame, mask, 1, 1);
cvAnd(frame, mask, dst);
cvShowImage("src", frame);
cvShowImage("dst", dst);
c = cvWaitKey(10);
if(c == 'q') break;
}
cvDestroyWindow("src");
cvDestroyWindow("dst");
cvReleaseImage(&frame);
cvReleaseImage(&dst);
cvReleaseImage(&mask);
cvReleaseCapture(&capture);
return(0);
}
お礼
返事していただき,ありがとうございます. その後調査および実験した結果,任意のフレームからキャプチャリングするのはビデオのファイル形式によって「できる」と「できない」が混在しているようですね. ただ,私の場合は,最初から表示すればキャプチャリングできたので,動画の全フレームを最初から全てBitmapで切り出すことにしました. #非常に非効率的ですが,致し方ないようですね.OpenCVのこれからに期待したいと思います.