• 締切済み

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つ並んでしまっている状態です。 なにか改善すべきところがありましたらよろしくお願いいたします。

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

> myDC.CreateCompatibleDC(pDC); > CBitmap *oldBMP = myDC.SelectObject(&mbmp); > pDC->BitBlt(0,0,300,300,&myDC,0,0,SRCCOPY); > myDC.SelectObject(oldBMP); が不要に思います mbmpはメンバー変数なんですよね ・・・ グレースケールで読み込んでいるのですからimgのデータは512x512しかありません ビットマップデーを構築する部分は 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 ]; といった具合でしょう y軸の計算に 幅だけでなく 1ピクセル分のバッファも乗算しましょう

s0511146
質問者

補足

早速の回答ありがとうございます。 前表示されたものよりよい感じに表示されるのですが、 次はPictureBoxにたて3つの画像が表示されてしまいます。 解決策などありましたらよろしくお願いいたします。

関連するQ&A

  • 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つ縦に画像が表示されてしまってます。 何か改善点などがありましたらよろしくお願いいたします。

  • 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 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の画像データを格納する構造体IplImageについて質問で

    opencvの画像データを格納する構造体IplImageについて質問です。 今opencvを用いて画像処理をしていて、test1とtest2という画像データを宣言して test1からは横:縦が640:512の画像を読み込みます。 そして、IplImageの中のImageDataにアクセスし、test2のImageDataにtest1のImageDataを 各ピクセルに代入して、test2という画像データをウィンドウに表示させたいと思ってます。 私的にはtest1とtest2には同じ画像データが表示されると考えているのですが、実際に実行してみると 少し違う画像が表示され、次のようなエラーが表示されます。 「"0x7c951909"の命令が"0xfffffff8"のメモリを参照しました。メモリが"read"になることはできませんでした。」 実際にCの中では以下のようにプログラムを組んでいます。 for(i=0;i<test->height;i++){ for(j=0;j<test->widthStep;j++){ *(test2->imageData+test2->widthStep*i+j)=*(unsigned char *)(test->imageData+i*test->widthStep+j); } } 何が原因なのか教えていただけないでしょうか。

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

  • Iplimageについて

    Iplimageについて プログラムを組み立てた際, 以下のエラー文がでてきます。 Null pointer(NULL array pointer is passed) in function cvGetMat, C:\user\VP\opencv\cxcore\src\cxarray.cpp(2780) Press "Abort" to terminate application. Press "Retry" to debug (if the app is running under debugger). Press "Ignore" to continue(this is not safe). これが、 空のポインタを渡したとき 出るエラー文だとわかったのですが、以下のように組むと cvSaveImageのときにエラー文が発生します。 また、cvShowImageではエラー文は出ません。 (ただ、cvShowImageの場合、画像の大きさがディスプレイよりも 大きいために調整して出力されるので全体が見えません・・・) IplImage *src_img = 0, *dst_img = 0; src_img = cvLoadImage ("a.jpg", CV_LOAD_IMAGE_COLOR); //画像読み込み dst_img = cvCloneImage(src_img); //dst_imgを黒画像に 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 * 3] = 0x00; dst_img->imageData[dst_img->widthStep * y + x * 3 + 1] = 0x00; dst_img->imageData[dst_img->widthStep * y + x * 3 + 2] = 0x00; } } cvSaveImage("test.jpg",dst_img); 空のポインタはcvCloneImageをすることで 回避できているのではと考えたのですが・・・ なぜエラーが発生するのかご教授よろしくお願いします。

  • IplImageをHSの閾値から2値化をしようとしています.

    IplImageをHSの閾値から2値化をしようとしています. 表示させたい画像は1920x1080で取り込んだ1枚の画像の2値化です. しかし以下のプログラムを実行し実際画像を見てみると, 1枚の画像の中にx=1080以降から 同じ画像がもう一枚でてきます. どうすれば一枚の画像をそのまま2値化して表示することができますか? よろしくおねがいします. xx=1920; yy=1080; for(yy = 0; yy < frame->height; yy++) {   for(xx = 0; xx < frame->width; xx++)   { if(HSV[yy][xx].H > HMin && HSV[yy][xx].H < HMax && HSV[yy][xx].S > SMin && HSV[yy][xx].S < SMax) {   src_buf[frame->width * yy + xx] = 1;   frame->imageData[frame->widthStep * yy + xx * 3] = 0x00;   frame->imageData[frame->widthStep * yy + xx * 3 + 1] = 0x00;   frame->imageData[frame->widthStep * yy + xx * 3 + 2] = 0x00; } else{   src_buf[frame->width * yy + xx] = 0;   frame->imageData[frame->widthStep * yy + xx * 3] = 0xff;   frame->imageData[frame->widthStep * yy + xx * 3 + 1] = 0xff;   frame->imageData[frame->widthStep * yy + xx * 3 + 2] = 0xff; }   } }

  • 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で特定の座標を指定しその座標の色変換

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

  • VisualC++6.0にてボタンにビットマップを表示させる方法

    VisualC++6.0のダイアログベースのアプリにおいて、 フォーム上に配置したボタン上にビットマップを表示 させたいと思ってます。OnPaint()の中で、以下のコード を書いたのですが、うまくいきません。  CWnd* myWnd = GetDlgItem(IDC_BUTTON1);  CDC* pDC = myWnd->GetDC();  CDC myDC;  CBitmap myBMP;  myBMP.LoadBitmap(IDB_BITMAP);  myDC.CreateCompatibleDC(pDC);  CBitmap* oldBMP = myDC.SelectObject(&myBMP);  pDC->BitBlt(0,0,100,100,&myDC,0,0,SRCCOPY);  myDC.SelectObject(oldBMP); ビットマップはちゃんと書かれてはいますが、その上にボタンが 描かれてしまうので、ビットマップが隠されてしまいます。 解決方法を教えてくださいますでしょうか。 よろしくお願いします。 % 絵をクリックするとアクションを起こすようにしたいので、 % ピクチャーボックスでも試してみました。これだとビット % マップはちゃんと表示されますが、BN_CLICKEDを書いて % ピクチャーボックスをクリックしてもOnPict()に処理が % 移りません。

専門家に質問してみよう