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

このQ&Aのポイント
  • OpenCVを使用して、2つの画像のピクセルごとの色の比較を行い、結果を表示するコードを作成しています。
  • 画像img1とimg2の色をピクセルごとに比較し、同じ色のピクセルは白、違う色のピクセルは黒に変換して、3枚目の画像img3を生成します。
  • しかし、img3には予期しない表示がされるため、ピクセルの参照方法に問題があるかもしれません。解決策をお知りの方はアドバイスをお願いします。
回答を見る
  • ベストアンサー

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

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

書き写したのでしょうか、このプログラムにはいろいろ間違いが多くてそのままでは動かなかったですが、文法間違いを直したら、白地に黒で文字が浮びましたよ。 それぞれの画像サイズは同じ100x100ですか? > //一枚目の画素値 > 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 となってますけど、それぞれ p1[0] = img1->imageData[img1->widthStep * y + x * 3]; // B p2[0] = img2->imageData[img2->widthStep * y + x * 3]; // B になってますか? img1,img2はちゃんと 8bit、3チャンネルになってますか?

rosafilipes
質問者

お礼

大変申し訳ありません、せっかくお返事いただいたのにお礼とクローズをしていませんでした。 アドバイスくださってすぐに画像を確認し、 念のため画像を入れ替えたところうまくいきました。 すぐに解決することができました、ありがとうございました。 重ねて、お礼が遅くなりましたことをお詫びいたします。

関連するQ&A

  • openCVでの白黒画像読み込み

    いつも大変お世話になっております。 ピクセルの値を「ゼロ(黒)」にしたピクセルを読み込んでも「255(白)」となってしまい困っています。cvShowImageでこの画像を表示すると、どうみてもその場所は黒です。 なぜ「255(白)」になるのかわからず困っています。 原因を教えていただけませんでしょうか。 詳細は以下のとおりです。 out_imgという変数名のCV_LOAD_IMAGE_COLORの真っ白の画像 out_img = cvLoadImage("C:...\shiro.jpg", CV_LOAD_IMAGE_COLOR); の6×6ピクセルの値を、以下の文で「黒」にして    out_img->imageData[out_img->widthStep * 6 + 6 * 3] = 0;    out_img->imageData[out_img->widthStep * 6 + 6 * 3 + 1] = 0;    out_img->imageData[out_img->widthStep * 6 + 6 * 3 + 2] = 0; 保存し、再び(別のソリューションで)src_img変数としてこの画像を読み込み    src_img = cvLoadImage("C:...¥shiro.jpg", CV_LOAD_IMAGE_COLOR); グレースケール化し、       src_img_gray = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); tmp_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1 ゼロイチの2値化(バイナリ画像)に変換し、 cvCvtColor(src_img, src_img_gray, CV_BGR2GRAY); 閾値でゼロイチに変換した後(なぜか上のsrc_img_grayでは黒がゼロにはならないため) cvAdaptiveThreshold(src_img_gray, tmp_img, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, 8); 6×6の位置の値(変数iro)を確認すると「255」となります。 for (x = 0; x < tmp_img->width; x = x + 1){ // x 座標を 1ピクセルずつ進める for (y = 0; y < tmp_img->height; y = y + 1){ // y 座標を 1ピクセルずつ進める if (x == 6 && y == 6){ x = 6; (ここでデバックを掛けて、下の変数iroの値がいくつかを確認しています。ゼロであってほしいのですが、255です。 } uchar iro = tmp_img->imageData[tmp_img->widthStep * y + x * 3]; if (iro == 0){ 画像読み込みの引数がおかしいのだろうと思い、 CV_LOAD_IMAGE_ANYCOLOR や「0」にしたところ 今度はfor文のところでエラーになり、走査が始まりません。 for (x = 0; x < tmp_img->width; x = x + 1){ // x 座標を 1ピクセルずつ進める for (y = 0; y < tmp_img->height; y = y + 1){ // y 座標を 1ピクセルずつ進める 初歩的な質問で申し訳ありません。 ぜひアドバイスをいただけると助かります。 どうぞよろしくお願い致します。

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

  • opencv BGR成分を指定し、該当するピクセルの位置を表示させる

    トラックバー1,2,3を使用します。 トラックバー1,2,3がそれぞれB,G,Rの値を指定します。 トラックバー1、2、3で指定したBGR成分を持つピクセルの色情報の座標をforループと、if文で探しprintfで表示させます。 私が作成したプログラムだとコンパイルは通りますが、BGR=(0,0,0)の時にのみ、x=0~254y=0~254が羅列されますが、上記の動作をしてくれません。 どなたかアドバイスお願いします。 #include <cv.h> #include <highgui.h> #include <stdio.h> /* グローバル変数 */ CvFont font; IplImage *img; int B = 0; int G = 0; int R = 0; uchar p[3]; void on_trackbar1 (int val1); void on_trackbar2 (int val2); void on_trackbar3 (int val3); int main (int argc, char *argv[]) { img = cvLoadImage ( "bgr2.jpg", CV_LOAD_IMAGE_COLOR); cvInitFont (&font, CV_FONT_HERSHEY_DUPLEX, 1.0, 1.0); cvNamedWindow ("Image", CV_WINDOW_AUTOSIZE); cvCreateTrackbar ("B", "Image", 0, 255, on_trackbar1); cvCreateTrackbar ("G", "Image", 0, 255, on_trackbar2); cvCreateTrackbar ("R", "Image", 0, 255, on_trackbar3); cvShowImage( "Image", img); cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&img); return 0; } void on_trackbar1 (int val1) { printf ("B=%d G=%d R=%d %d %d %d\n ", B,G,R,p[0],p[1],p[3] ); B = val1; char str [64]; int x, y; for (y = 0; y < img->height; y++) { for (x = 0; x < img->width; x++) { ((uchar*)(img->imageData + img->widthStep*y))[x*3]=p[0]; ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]=p[1]; ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]=p[2]; if ((p[0] == B) && (p[1] == G) && (p[2] == R)) { printf ("X=%d Y=%d %d %d %d\n ", y, x, p[0],p[1],p[3] ); } } } } void on_trackbar2 (int val2) { printf ("B=%d G=%d R=%d %d %d %d\n ", B,G,R,p[0],p[1],p[3] ); G = val2; char str [64]; int x, y; for (y = 0; y < img->height; y++) { for (x = 0; x < img->width; x++) { ((uchar*)(img->imageData + img->widthStep*y))[x*3]=p[0]; ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]= p[1]; ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]=p[2]; if ((p[0] == B) && (p[1] == G) && (p[2] == R)) { printf ("X=%d Y=%d %d %d %d\n", y, x, p[0],p[1],p[2] ); } } } } void on_trackbar3 (int val3) { printf ("B=%d G=%d R=%d %d %d %d\n ", B,G,R,p[0],p[1],p[2] ); R = val3; char str [64]; int x, y; for (y = 0; y < img->height; y++) { for (x = 0; x < img->width; x++) { ((uchar*)(img->imageData + img->widthStep*y))[x*3]=p[0]; ((uchar*)(img->imageData + img->widthStep*y))[x*3+1]=p[1]; ((uchar*)(img->imageData + img->widthStep*y))[x*3+2]=p[2]; if ((p[0] == B) && (p[1] == G) && (p[2] == R)) { printf ("X=%d Y=%d %d %d %d\n", y, x, p[0],p[1],p[2] ); } } } }

  • 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関数に戻れば良いと思い、思いつく限り試しましたが上手くいきません。 どなたかアドバイスお願いします。

  • 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)を決まったサイズのウィンドウで扱えるでしょうか。 もしおわかりでしたらヒントでも結構ですのでぜひ教えてください。 よろしくお願いします。

  • IplImageのBmp変換。

    いつもこちらでお世話になっております。 現在OpenCVをつかって画像処理を行なっています。言語はVC++です。 OpenCVで処理した画像をPictureBoxに表示させたいのですが、 うまく表示できません。 IplImageをBmpに変換させる部分がおかしいとは思うのですが… //-------------------------------------------------------- IplImage *img; img = cvLoadImage(filename, 0); // 0: グレイスケールで読み込む cvThreshold(img,img, 70, 255, CV_THRESH_BINARY_INV);//二値化 // ビットマップ用のカラーバッファ char* ColorBuf = (char*)calloc( sizeof(char), img->width * img->height * 4 ); for( int y = 0; y < img->height; y++ ) { for( int x = 0; x < img->width; x++ ) { // Blue ColorBuf[ y * img->width + x * 4 + 0 ] = img->imageData[ y * img->widthStep + x * 3 + 0 ]; // Green ColorBuf[ y * img->width + x * 4 + 1 ] = img->imageData[ y * img->widthStep + x * 3 + 1 ]; // Red ColorBuf[ y * img->width + x * 4 + 2 ] = img->imageData[ y * img->widthStep + x * 3 + 2 ]; } } mbmp.CreateBitmap( img->width, img->height, 1, 32, ColorBuf ); free( ColorBuf ); ((CStatic*)GetDlgItem( IDC_IMGSRC ))->SetBitmap ( mbmp ); myDC.CreateCompatibleDC(pDC); CBitmap *oldBMP = myDC.SelectObject(&mbmp); pDC->BitBlt(0,0,300,300,&myDC,0,0,SRCCOPY); myDC.SelectObject(oldBMP); cvReleaseImage( &img ); //----------------------------------------------- PictureBoxのリソースIDをIDC_IMGSRCに設定しています。 今はPictureBoxの上部に画像が4つ並んでしまっている状態です。 なにか改善すべきところがありましたらよろしくお願いいたします。

  • openCVの画像処理について

    画像の中にある粒子の位置を検出し、座標の値の取得をどうしてもOpenCVをつかって、出したいと考えております。 プログラミングが実行したら、すべて0と表示されたり、エラーが出たりします。 現在、画像を読み込み、2値化し、2値化した画像の画素数を列ごとに足して、垂直方向の画素数の最大値の検出、2値化した画像の画素数を行ごとに足して、水平方向の画素数の最大値の検出を行っています。 使用した画像を添付させていただきますので、もしアドバイスなどいただけたらよろしくお願い致します。 #include <stdio.h> #include <math.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> #define X 640 #define Y 480 IplImage *grayImage; //グレースケール画像用IplImage IplImage *binaryImage; //2値画像用IplImage char windowNameBinarization[] = "Binarization";//2値化した画像を表示するウィンドウの名前 int levels = 115; //トラックバーの値(2値化の際の閾値) static int h[X][Y]; int main( /*int argc, char **argv*/ ){ // 画像を読み込む IplImage *sourceImage = cvLoadImage( "C:/Documents and Settings/Owner/My Documents/My Pictures/Logicool Webcam/Picture 10.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); if ( sourceImage == NULL ) { // 画像が見つからなかった場合 printf( "画像が見つかりません\n" ); return -1; } // 画像を生成する IplImage *grayImage = cvCreateImage( cvGetSize(sourceImage), IPL_DEPTH_8U, 1 );//グレースケール画像用IplImage IplImage *binaryImage = cvCreateImage( cvGetSize(sourceImage), IPL_DEPTH_8U, 1 ); //2値画像用IplImage // BGRからグレースケールに変換する cvCvtColor( sourceImage, grayImage, CV_BGR2GRAY ); // グレースケールから2値に変換する cvThreshold( grayImage, binaryImage, levels, 255, CV_THRESH_BINARY ); /*グラフ値の取得*/ IplImage *img; img = cvCloneImage (binaryImage); //画像をコピー int bytes_per_pixel = ((img->depth & 255) / 8) * img->nChannels; // (1)画素値を順次取得 int i,j,k,t; int Hy[Y],Hx[X]; //宣言 //垂直方向の画素値 for(k = 0; k <Y /*img->height*/; k++) { Hy[k] = 0;//初期化 } if((unsigned char)img->imageData>levels){ for(j = 0;j < Y/*img->height*/; j++) { for(i = 0; i < X; i++) {Hy[j] += *(img->imageData + (img->widthStep*j) + (i*bytes_per_pixel)); } }} //水平方向の画素値 for(t = 0; t < X/*img->width*/; t++) { Hx[t]=0; //初期化 } if((unsigned char)img->imageData>levels){ for(i = 0;i < X/*img->width*/; i++) { for(j = 0;j < Y; j++) { Hx[i] = Hx[i]+h[i][j]; } }} //Hy[j]の最大値の座標を調べる int MY = Hy[0]; int my = 0; for(int j=0; j< Y-1; j++){ if(Hy[j]<Hy[j+1]){ MY = Hy[j+1]; my = j+1; } } //Hx[i]の最大値の座標を調べる int MX = Hx[0]; int mx = 0; for(int i=0; i< X-1; i++){ if(Hx[i]<Hx[i+1]){ MX = Hx[i+1]; mx = i+1; } } printf("垂直方向の最大値 %d , 垂直方向の最大値になるときのy軸の値 %d \n", MY,my); printf("水平方向の最大値 %d , 水平方向の最大値になるときのx軸の値 %d \n", MX,mx); int cvWaitKey(int delay=10); //どこでとめるかをあらわす cvReleaseImage( &sourceImage ); cvReleaseImage( &grayImage ); cvReleaseImage( &binaryImage ); cvDestroyWindow( windowNameBinarization); return 0 ; }

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

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

  • IplImageをPictureBoxへ表示がうまくいきません。

    VC++にてOpenCVを使い画像処理を行っている者です。 処理後の画像をMFCで作成したPictureBoxに表示したいのですが、 IplImageからBmpへの変換がうまくいきません。 //--------------------------------------------------------------- IplImage *img; img = cvLoadImage(filename, 0); // 0: グレイスケールで読み込む cvThreshold(img,img, 70, 255, CV_THRESH_BINARY_INV);//二値化 char* ColorBuf = (char*)calloc( sizeof(char), img->width * img->height * 4 ); for( int y = 0; y < img->height; y++ ) { for( int x = 0; x < img->width; x++ ) { ColorBuf[ y * img->width * 4 + x * 4 + 0 ] = img->imageData[ y * img->widthStep + x * 3 + 0 ]; ColorBuf[ y * img->width * 4 + x * 4 + 2 ] = ColorBuf[ y * img->width * 4 + x * 4 + 1 ]= ColorBuf[ y * img->width * 4 + x * 4 + 0 ]; } } mbmp.CreateBitmap( img->width, img->height, 1, 32, ColorBuf ); free( ColorBuf ); ((CStatic*)GetDlgItem( IDC_IMGSRC ))->SetBitmap ( mbmp ); cvReleaseImage( &img ); } //--------------------------------------------------------------- 今はPictureBoxに3つ縦に画像が表示されてしまってます。 何か改善点などがありましたらよろしくお願いいたします。

専門家に質問してみよう