• 締切済み

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); }

みんなの回答

  • tlmg
  • ベストアンサー率50% (2/4)
回答No.1

本当に動きませんか?私の環境は2.4.5ですが動作しましたので、2.4.6で使えなくなっているとは思えません。 情報が何もないので予想することしかできませんが、考えられる中で可能性が高そうなのはヘッダがincludeできていないことでしょうか。 もしそれでも動かないなら設定レベルでの問題になると思います。 その場合は具体的なエラーなどを記載して質問されることをお勧めします。

関連するQ&A

  • c++のif文についてです。

    webカメラを使って肌色の面積を求めて、現在より1フレーム前の値と比較したいのですが、そのif文の部分がどのように書けば良いのかわかりません。 printf関数を使ってwebカメラで取得した肌色部分のピクセル数の前後を比較する場合(例えば、前のあたいより10倍以上大きかったら等)のif文の書き方をどなたかご教授お願いします。 以下ソースコードです。 #include "stdafx.h" #include <cv.h> #include <highgui.h> #include <time.h> #include <math.h> #include <string> int hsv=0; IplImage*mask = 0; CvSeq* contour = 0; 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); 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 = 120; minS = 70; maxS = 255; minV = 70; 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]; 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; hsv++; } 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); printf("%d\n",hsv); if(){}←ここのif文がわかりません cvReleaseImage(&tmp); } int _tmain(int argc, _TCHAR* argv[]) { int key; CvCapture* src; IplImage* frame; cvNamedWindow("カメラ映像表示"); src = cvCaptureFromCAM(0); if(src == NULL){ printf("映像が取得できません。\n"); cvWaitKey(0); return -1; } frame = cvQueryFrame(src); mask = cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3); while(1){ frame = cvQueryFrame(src); cvShowImage("カメラ映像表示", frame); GetMaskHSV(frame,mask,1,1); cvDrawContours(frame, contour, CV_RGB (255, 255, 0), CV_RGB (0, 0, 0), 1, 1, CV_AA, cvPoint (0, 0)); key = cvWaitKey(33); if(key == 27) break; } cvDestroyWindow("カメラ映像表示"); cvReleaseCapture(&src); return 0; } 1フレーム前の値を変数に記憶して、その前の状態を記憶しておいた変数と hsv とを比較すればよいというアルゴリズムは想像できるのですが、その“1フレーム前の値”というのを、どのように表現していいかわからないのです・・

  • OpenCV 2値化について

    いつもお世話になっております。 画像の2値化(黒は全てゼロ、白は全て255)をした画像bw_imgを用意して 左上端から11×11サイズのROIに切り取って決まった処理をかけていこうとしていますが、 2値化した画像をROIで保持させることができず、困っています。 int main() { //画像の2値化処理用変数 IplImage *src_img = 0, *dst_img = 0, *bw_img = 0; IplImage *src_img_gray = 0; IplImage *tmp_img, *out_img, *lap_img; CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *contours = 0; // (1)画像を読み込み、グレースケール化(src_img_gray)、二値化(tmp_img) src_img = cvLoadImage("C:\\Users...\\サンプル画像\\sample.jpg", CV_LOAD_IMAGE_COLOR); tmp_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); src_img_gray = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1);//もとはIPL_DEPTH_8U cvCvtColor(src_img, src_img_gray, CV_BGR2GRAY); cvAdaptiveThreshold(src_img_gray, tmp_img, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, 8); //11×11 走査用変数 dst_img = cvCreateImage(cvGetSize(tmp_img), IPL_DEPTH_8U, 1); bw_img = cvCreateImage(cvGetSize(tmp_img), IPL_DEPTH_8U, 1); out_img = cvCreateImage(cvGetSize(tmp_img), IPL_DEPTH_8U, 1); cvThreshold(tmp_img, bw_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); for (x = 0; x < bw_img->width; x++){ // x 座標を 1ピクセルずつ進める for (y = 0; y < bw_img->height; y++){ // y 座標を 1ピクセルずつ進める //(1) 11×11ピクセルに切り取って2値化する。 cvCopy(bw_img, dst_img); lap_img = cvCreateImage(cvSize(11, 11), IPL_DEPTH_8U, 1); CvMat *sub = cvCreateMatHeader(11, 11, CV_8UC1); cvGetSubRect(bw_img, sub, cvRect(y, x, 11, 11)); //コピー画像から11×11切り取り。 cvThreshold(sub, lap_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); //2値化、結果はlap_img. uchar iro = lap_img->imageData[lap_img->widthStep * (y + 6) + (x + 6)]; if (iro ==0){ →ここでどうみても黒なのにiroに「238」「71」などの値が入っています。 roiで切り取ったlap_imgが2値になっていません。 何が問題で2値化できていないのでしょうか。 どうすると2値化した画像(lap_img)を決まったサイズのウィンドウで扱えるでしょうか。 もしおわかりでしたらヒントでも結構ですのでぜひ教えてください。 よろしくお願いします。

  • OpenCVでサンプルコードを使うとエラーが出ます

    環境はVidualStudio2008、OpenCVは2.1のバージョンを利用しています。 OpenCVのテンプレートマッチングのサンプルを利用したところエラーが発生しました。 ソースは以下のものを使っています。 ところどころに入っているprintfは私が自分で入れたものですがこれが原因であるとは考えにくいのです。 エラーは添付したような画像で現れます。 またデバッグしたところ [下のフレームは間違っているか、または見つかりません。KernelBase.dll に対して読み込まれたシンボルはありません。] KernelBase.dll!76b7b9bc() このような文章も表示されました。 どうすれば解決できるでしょうか。 #include <cv.h> #include <highgui.h> int main (int argc, char **argv) { double min_val, max_val; CvPoint min_loc, max_loc; CvSize dst_size; IplImage *src_img, *tmp_img, *dst_img; argv[1]="○○"; argv[2]="○○"; argc=3; printf("1complete\n"); cvNamedWindow ("Image", 1); src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); tmp_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR); if(argc != 3 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR))==0||(tmp_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR))==0) return -1; printf("2complete\n"); // (1)探索画像全体に対して,テンプレートのマッチング値(指定した手法に依存)を計算 dst_size = cvSize (src_img->width - tmp_img->width + 1, src_img->height - tmp_img->height + 1); printf("2-1complete\n"); dst_img = cvCreateImage (dst_size, IPL_DEPTH_32F, 1);    //ここで動作停止 printf("2-2complete\n"); cvMatchTemplate (src_img, tmp_img, dst_img, CV_TM_CCOEFF_NORMED); printf("2-3complete\n"); cvMinMaxLoc (dst_img, &min_val, &max_val, &min_loc, &max_loc, NULL); printf("3complete\n"); // (2)テンプレートに対応する位置に矩形を描画 cvRectangle (src_img, max_loc, cvPoint (max_loc.x + tmp_img->width, max_loc.y + tmp_img->height), CV_RGB (255, 0, 0), 3); printf("4complete\n"); cvShowImage ("Image", src_img); printf("ALL COMPLETE!\n"); cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&src_img); cvReleaseImage (&tmp_img); cvReleaseImage (&dst_img); return 0; }

  • opencv c++についての質問です

    int main (int argc, char **argv){ int i, c, counter; int INIT_TIME = 100; int w = 0, h = 0; char *FileName = "動画名"; if((capture = cvCaptureFromFile(FileName)) == NULL){ printf("指定された動画がみつかりません\n"); return -1; } CvCapture *capture = 0; IplImage *frame; IplImage *av_img, *sgm_img; IplImage *lower_img, *upper_img, *tmp_img; IplImage *dst_img, *msk_img; CvFont font; capture = cvCreateFileCapture (FileName); // (2)1フレームキャプチャし,キャプチャサイズを取得する. frame = cvQueryFrame (capture); w = frame->width; h = frame->height; // (3)作業用の領域を生成する av_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); sgm_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); tmp_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); lower_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); upper_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); dst_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 3); msk_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 1); // (4)背景の輝度平均の初期値を計算する printf ("Background statistics initialization start\n"); cvSetZero (av_img); for (i = 0; i < INIT_TIME; i++) { frame = cvQueryFrame (capture); cvAcc (frame, av_img); } cvConvertScale (av_img, av_img, 1.0 / INIT_TIME); // (5)背景の輝度振幅の初期値を計算する cvSetZero (sgm_img); for (i = 0; i < INIT_TIME; i++) { frame = cvQueryFrame (capture); cvConvert (frame, tmp_img); cvSub (tmp_img, av_img, tmp_img); cvPow (tmp_img, tmp_img, 2.0); cvConvertScale (tmp_img, tmp_img, 2.0); cvPow (tmp_img, tmp_img, 0.5); cvAcc (tmp_img, sgm_img); } cvConvertScale (sgm_img, sgm_img, 1.0 / INIT_TIME); printf ("Background statistics initialization finish\n"); // (6)表示用ウィンドウを生成する cvInitFont (&font, CV_FONT_HERSHEY_COMPLEX, 0.7, 0.7); cvNamedWindow ("Input", CV_WINDOW_AUTOSIZE); cvNamedWindow ("Substraction", CV_WINDOW_AUTOSIZE); // (7)取得画像から背景を分離するループ counter = 0; while (1) { frame = cvQueryFrame (capture); cvConvert (frame, tmp_img); // (8)背景となりうる画素の輝度値の範囲をチェックする cvSub (av_img, sgm_img, lower_img); cvSubS (lower_img, cvScalarAll (Zeta), lower_img); cvAdd (av_img, sgm_img, upper_img); cvAddS (upper_img, cvScalarAll (Zeta), upper_img); cvInRange (tmp_img, lower_img, upper_img, msk_img); // (9)輝度振幅を再計算する cvSub (tmp_img, av_img, tmp_img); cvPow (tmp_img, tmp_img, 2.0); cvConvertScale (tmp_img, tmp_img, 2.0); cvPow (tmp_img, tmp_img, 0.5); // (10)背景と判断された領域の背景の輝度平均と輝度振幅を更新する cvRunningAvg (frame, av_img, B_PARAM, msk_img); cvRunningAvg (tmp_img, sgm_img, B_PARAM, msk_img); // (11)物体領域と判断された領域では輝度振幅のみを(背景領域よりも遅い速度で)更新する cvNot (msk_img, msk_img); cvRunningAvg (tmp_img, sgm_img, T_PARAM, msk_img); // (12)物体領域のみを出力画像にコピーする(背景領域は黒) cvSetZero (dst_img); cvCopy (frame, dst_img, msk_img); // メディアンフィルタでノイズを除去する cvSmooth( dst_img, dst_img, CV_MEDIAN ); cvMoments( frame, &moment, 0 ); m_00 = cvGetSpatialMoment( &moment, 0, 0 ); m_10 = cvGetSpatialMoment( &moment, 1, 0 ); m_01 = cvGetSpatialMoment( &moment, 0, 1 ); gravityX = m_10 / m_00; gravityY = m_01 / m_00; if (frame->nChannels == 3 && cvGetImageCOI (frame) == 0) cvSetImageCOI (frame, 1); cvSetImageCOI (frame, 0); cvCircle( dst_img, cvPoint( gravityX, gravityY ), CIRCLE_RADIUS,CV_RGB( 255, 0, 0 ), LINE_THICKNESS, LINE_TYPE, 0 ); // (13)処理結果を表示する cvShowImage ("Input", frame); cvShowImage ("Substraction", dst_img); counter++; c = cvWaitKey (10); if (c == '\x1b') break; } cvDestroyWindow ("Input"); cvDestroyWindow ("Substraction"); cvReleaseImage (&frame); cvReleaseImage (&dst_img); cvReleaseImage (&av_img); cvReleaseImage (&sgm_img); cvReleaseImage (&lower_img); cvReleaseImage (&upper_img); cvReleaseImage (&tmp_img); cvReleaseImage (&msk_img); return 0; } 動画を指定して背景差分を行い、動画内の物体の重心を求めて円を描きたいのですがcvMoments()とcvCircle()関数を入れてコンパイルしたところウィンドウが出て動画が始まる前に終了してしまいます。 どのようにすれば正常に動くようになるのでしょうか?

  • OpenCv 透明度について

    OpenCv 透明度について 透明度を表すRGBAのA(アルファチャネル)をいじって画像の透明にしたいのですが、いじってみてもなにも変化がありません。 なにが悪いのかわかりません ↓こんな感じでやってます。 // 画像を読み込む src_img = cvLoadImage(src_imgfile,CV_LOAD_IMAGE_COLOR); //RGBA変換 dst_img = cvCreateImage(cvGetSize(bg_img),IPL_DEPTH_8U,4); cvCvtColor(bg_img,dst_img,CV_RGB2RGBA); //透明度をいじる for ( int y = 0 ; y < dst_img->height ; y++ ) { for ( int x = 0 ; x < dst_img->width ; x++ ) { dst_img->imageData[dst_img->widthStep * y + x * 4 + 3] = -255; } }

  • カメラを用いて動画から画像を取り込みトリミングしようとするプログラムを

    カメラを用いて動画から画像を取り込みトリミングしようとするプログラムを作っています. 最下部のプログラムを貼り付けているところまででデバックしつつ実行すると "OpenCVwithDShow.exe の 0x00462614 でハンドルされていない例外が発生しました: 0xC0000094: Integer division by zero" とエラー文がでてきます. 色々考えたのですが、原因が分からないのでどなたかご教授お願いします. よろしくお願いします. //トリミング CvRect cvClipRect(IplImage *frame, CvRect r) { r.x = 240; r.y = 0; r.width = 1080; r.height = 1680; if (r.x < 0) {r.width += r.x; r.x = 0;} if (r.y < 0) {r.height += r.y; r.y = 0;} if (r.x >= frame->width ) {r.width -= r.x - frame->width ; r.x = frame->width - 1;} if (r.y >= frame->height) {r.height -= r.y - frame->height; r.y = frame->height - 1;} if (r.width > frame->width - r.x) {r.width = frame->width - r.x;} if (r.height > frame->height - r.y) {r.height = frame->height - r.y;} return r; } IplImage *cvCreateSubRectImage(IplImage *frame, CvRect r) { IplImage tmp; CvMat submat; cvGetSubRect(frame, &submat, cvClipRect(frame, r)); cvGetImage(&submat, &tmp); return cvCloneImage(&tmp); } //トリミング終了 int main (int argc, char **argv){ CvCapture *capture = 0; IplImage *frame = NULL; IplImage *frame1 = NULL; IplImage *reduce = NULL; int c; int x,y; int max,min; int h,s; uchar p[3]; LabelingSS labeling; short *src_buf; float centerX,centerY; HANDLE hCom; //トリミング関数 // (1)コマンド引数によって指定された番号のカメラに対するキャプチャ構造体を作成する if (argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit (argv[1][0]))) capture = cvCreateCameraCapture (argc == 2 ? argv[1][0] - '0' : 0); /* この設定は,利用するカメラに依存する */ // (2)キャプチャサイズを設定する. cvNamedWindow ("Capture", CV_WINDOW_AUTOSIZE); frame1 = cvQueryFrame (capture); src_buf = new short[ frame1->width * frame1->height ]; // (3)カメラから画像をキャプチャする while (1) { frame1 = cvQueryFrame (capture); frame = cvCloneImage(frame1); //トリミング呼び出し CvRect cvClipRect(IplImage *frame, CvRect r); IplImage *cvCreateSubRectImage(IplImage *frame, CvRect r);

  • opencvについてわからないことがあります。

    IplImage *frame, *img_gray, *img_out;//画像変数宣言 CvPoint pushpt[10]; int cnum; CvScalar color[10]; int _tmain(int argc, _TCHAR* argv[]) { int key=0; int wait=100; int newFrame=0; CvCapture* src; //ビデオキャプチャ宣言 CvVideoWriter* rec; //ビデオライタ宣言 void on_mouse(int event,int x,int y,int flags,void *param); cvNamedWindow ("入力映像");//表示ウインドウの作成 cvNamedWindow ("出力映像"); src = cvCaptureFromFile("movie.avi");//映像取得 cvSetMouseCallback("入力映像",on_mouse,0); if(src == NULL){//ファイルが読み込めない場合 printf ("canot open\n"); //cvWaitKey(0); return -1; } cnum=-1; newFrame=1; frame = cvQueryFrame(src);//初期フレーム取得 //画像領域の確保 //img_gray = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 1); img_out = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); //ビデオファイル書き込み設定 rec = cvCreateVideoWriter("movie_out.avi",CV_FOURCC('X','V','I','D'),30,cvSize(frame->width, frame->height)); for(int i=0;i<10;i++){//クリックした数だけiを増やして色を変える color[i]=CV_RGB((int)(255.0/10*(10-i)),(int)(255.0/10*i),0); } while(1){//映像が終了するまで繰り返す if(newFrame){ frame = cvQueryFrame(src);//1フレーム取得 cvCopy (frame,img_out,0); newFrame=0; } if(frame == NULL) break;//映像終了時 //cvLine(frame,cvPoint(50,50),cvPoint(100,100),CV_RGB(255,0,0),2,CV_AA,0); //draw mark for(int i=0;i<=cnum;i++){//クリックした数だけ円を描画 cvCircle(img_out,pushpt[i],10,color[i],2,CV_AA,0); } cvShowImage ("入力映像", frame);//1フレーム表示 cvShowImage ("出力映像", img_out); cvWriteFrame(rec ,img_out);//1フレーム書き込み key=0; key=cvWaitKey(wait);//key 'n'の入力を待つ if(key == 'n'){ cnum=-1; newFrame=1; } if(key==27) break;//escキーを押した時終了 } cvDestroyAllWindows();//すべての表示ウインドウ破棄 cvReleaseCapture(&src);//ビデオキャプチャの解放 cvReleaseVideoWriter(&rec);//ビデオライタの解放 cvReleaseImage(&img_gray);//画像領域の解放 cvReleaseImage(&img_out); return 0; } //追加 void on_mouse(int event,int x,int y,int flags,void *param){ //printf("OnMouseDown\n"); if(event == CV_EVENT_LBUTTONDOWN){ cnum++; if(cnum>10) cnum=10;//マークの最大点制限 pushpt[cnum] = cvPoint(x,y); printf("OnMouse:%d\n",cnum); //cvCircle(frame,pushpt,20,CV_RGB(255,128,0),8,CV_AA,0); } } このソースコードを実行すると、nキーで1フレーム進む動画が2つ表示されます。 1つは読み込んだ動画を表示しています。 もう1つはそれを録画して、動画ファイルとして書き出しています。 読み込んだ動画上にマウスでクリックすると、録画の画面上に丸でマークをします。 ここまではできました。 しかし、ここから次に書くことができません。 1フレーム目でマウスでクリックしてマークをします。 次に、nキーを押して2フレーム目に進みます。(この時1フレームでマークしたものは消えています。) そして、2フレーム目でマウスでクリックして、マークをすると1フレーム目でマークしたものが一緒に出てくる(できれば色が薄くなって) ということがしたいです。 pushptという配列に座標がはいっているのは、わかっているのですがどう書けばよいかわかりません。 教えてくださいお願いします。

  • opencvでの2枚の画像の差分のやり方

    opencvのc言語で2枚の画像の差分をとりたいのですが,最後の差分をとるところでエラーが出てしまいます. char *filename = "動画の名前.avi"; CvCapture* cap = cvCaptureFromAVI(filename);//filename:const char*型のファイル名 filenameの動画像を読み込む double framecount = (int)cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT);//フレーム数を数える IplImage *srcCur=NULL; IplImage *srcOld=NULL; cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 1); srcOld = cvQueryFrame(cap);//1フレーム目の画像を読み込む cvSetCaptureProperty(cap, CV_CAP_PROP_POS_FRAMES, 2); srcCur = cvQueryFrame(cap);//2フレーム目の画像を読み込む cvAbsDiff(srcOld2,srcCur2,dst);←ここでエラーがでます。 エラー内容は多分,差分するためには,同じ画像サイズ同士で 同じ型どうしでないといけないと書かれていますが, 同じ動画から読み込まれているので,違うことはありえないと思います. どうしたらいいですか?

  • OpenCV での画素値の比較について

    サイズが同じ2枚のbmp画像(img1とimg2)の色をピクセルごとに比較し、同じ色ならそのピクセルを白、違う色なら黒にして、3枚目(img3)の画像を生成するコードを書いています。 imgとimg2は同じ画像ですが、img2にのみ「あ」という文字が書いてあります。うまくいけばimg3には、白い背景に「あ」と黒く表示されるはずです。 ところが、結果に「あ」と表示されません。ピクセル単位で比較していますが、白い背景に、まだらなな黒色と、2~3ミリ四方の同じ大きさの黒い四角形もたくさん(規則的にではなく、ランダムに)表示されます。 img1と2と3が、それぞれ違うピクセルを参照しているのだろうかと、自分なりに調べていますが、どこがまずいのかわからず困っています。どなたかおわかりになれば、ぜひアドバイスをいただけると助かります。 どうぞ宜しくお願い致します。 === int main (int argc, char :: argv) { int x, y, i; uchar p1[3], p2[3]; IplImage *img1, img2, img3; img1 = cvLoadImage ("D:\\...\\ichimaime.bmp", CV_LOAD_IMAGE_COLOR); img2 = cvLoadImage ("D:\\...\\nimaime.bmp", CV_LOAD_IMAGE_COLOR); img3 = cvCreateImage(cvSize (100, 100), IPL_DEPTH_8U, 3); cvZero (img3); for (y = 0 ; y < img1->height; y++) { for (x = 0 ; x < img1->width, x++) { //一枚目の画素値 p1[0] = img1->imageData[img->widthStep * y + x * 3]; // B p1[1] = img1->imageData[img->widthStep * y + x * 3 + 1]; // G p1[2] = img1->imageData[img->widthStep * y + x * 3 + 2]; // R //二枚目の画素値 p2[0] = img2->imageData[img->widthStep * y + x * 3]; // B p2[1] = img2->imageData[img->widthStep * y + x * 3 + 1]; // G p2[2] = img2->imageData[img->widthStep * y + x * 3 + 2]; // R if ( p1[0]!=p2[0] || p1[1]!=p2[1] || p1[2]!=p2[2] ) { /*もし違う色なら黒にする*/ img3-> imageData[img3->widthStep * y + x * 3] = 0; img3-> imageData[img3->widthStep * y + x * 3 +1] = 0; img3-> imageData[img3->widthStep * y + x * 3 +2] = 0; }else{ /*もし同じ色なら白にする*/ img3-> imageData[img3->widthStep * y + x * 3] = 255; img3-> imageData[img3->widthStep * y + x * 3 +1] = 255; img3-> imageData[img3->widthStep * y + x * 3 +2] = 255; } } } cvNmaedWindow(“Image”, CV_WINDOW_AUTOSIZE); CVsHOWiMAGE (“Image”, img3); cvWaitKey(0); cvDestroyWindow(“Image”); cvReleaseImage (&img1); cvReleaseImage (&img2); cvReleaseImage (&img3); return 0; } ===

  • opencvで特定の座標を指定しその座標の色変換

    #include <cv.h> #include <highgui.h> #include <stdio.h> /* グローバル変数 */ CvFont font; IplImage *img; int num1=0; int num2=0; int num3=0; int num4=0; /* プロトタイプ宣言 */ void on_trackbar1 (int val1); void on_trackbar2 (int val2); void on_trackbar3 (int val3); void on_trackbar4 (int val4); int main (int argc, char *argv[]) { img = cvLoadImage ( "bgr.jpg", CV_LOAD_IMAGE_COLOR); cvInitFont (&font, CV_FONT_HERSHEY_DUPLEX, 1.0, 1.0); cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE); cvCreateTrackbar ("X", "Image", 0, 255, on_trackbar1); cvCreateTrackbar ("Y", "Image", 0, 255, on_trackbar2); cvCreateTrackbar ("COLOR", "Image", 0, 255, on_trackbar3); cvCreateTrackbar ("-", "Image", 0, 100, on_trackbar4); cvShowImage ("Image", img); int x,y; uchar p[3]; for (y = 0; y < img->height; y++) { for (x = 0; x < img->width; x++) { p[0] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3]; // B p[1] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3+1]; // G p[2] =((uchar*)(img->imageData + img->widthStep*num2))[num1*3+2]; // R p[0] = num3; p[1] = num3; p[2] = num3; } } cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&img); return 0; } /* コールバック関数 */ void on_trackbar1 (int val1) { num1 = val1; char str[64]; printf ( "X=%d Y=%d C=%d -=%d\n", val1, num2, num3, num4); } void on_trackbar2 (int val2) { num2 = val2; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, val2, num3, num4); } void on_trackbar3 (int val3) { num3 = val3; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, num2, val3, num4); } void on_trackbar4 (int val4) { num4 = val4; char str [64]; printf ( "X=%d Y=%d C=%d -=%d\n", num1, num2, num3, val4); } このプログラムで特定の座標の色変換をしたいのですがうまくいきません。 トラックバー1でX座標 トラックバー2でY座標 トラックバー3で変更後の色 を指定します。 実行すると画像は表示されますがトラックバーを動かしても変化がありません。トラックバーを動かした時にmain関数に戻れば良いと思い、思いつく限り試しましたが上手くいきません。 どなたかアドバイスお願いします。

専門家に質問してみよう