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

このQ&Aのポイント
  • IplImageをHSの閾値から2値化しようとしていますが、同じ画像がもう一枚現れる問題に直面しています。
  • 画像は1920x1080で取り込まれ、1枚の画像を2値化して表示したいです。
  • どうすれば1枚の画像をそのまま2値化して表示することができますか?
回答を見る
  • ベストアンサー

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

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

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

・frameの中身: cvCreateImage等の設定はどうなっているのか ・src_bufの中身: 変数宣言、領域確保など ・HSVの中身: 変数宣言、領域確保、この箇所に来た段階での値など ・画像の作成方法: frame をcvSaveImageしたもの? と、わからない点が多いので、この部分が正しいかどうか判断できません。 また > xx=1920; > yy=1080; としたものをループカウンタに使ってしまっていますが、これはよいのですか? ループ終了時点で xx = frame->width, yy=frame->heghtになって、元にもどっているかもしれませんが。

mitti0157
質問者

お礼

ややこしくなってすみません、以下に続きです。 if(HSV[y][x].H<0){ HSV[y][x].H += 360;}   HSV[y][x].S = 256*(max-min)/max; //s /= max; 円柱モデルの場合   HSV[y][x].V = max;   } }   } です. ・frameの中身: cvCreateImage等の設定はどうなっているのか 動画像をの一枚の静止画を取り込んでいます. frameに移すときはcvQueryFrameを使用しています. ・src_bufの中身: 変数宣言、領域確保など >src_buf = new short[ frame->width * frame->height ]; で領域を確保しています. ・HSVの中身: 変数宣言、領域確保、この箇所に来た段階での値など >HSVはプログラムの最初に示していた構造体を使用しています. 今プログラムを動かせる環境ではないために値を見ることができませんが正常値でした. ・画像の作成方法: frame をcvSaveImageしたもの? >cvSaveImageを使用しています. 長々と申し訳ありません. 回答ありがとうございます. よろしくおねがいします.

mitti0157
質問者

補足

説明が不足していてすみません. 一応デバックして,2値化の処理の手前までは通常に画像が表示されていたので, ここの部分が原因かと思い貼り付けてしまいました… >> xx=1920; >> yy=1080; >としたものをループカウンタに使ってしまっていますが、これはよいのですか? >ループ終了時点で xx = frame->width, yy=frame->heghtになって、元にもどっているかもしれませんが。 の部分ですが,これは掲示板で書き込む際に間違えて書き込んでしまいました.ややこしくてすみません. 不足していたプログラムを以下に貼り付けます. この続きが上記のプログラムへ続きます. bmpへの表示はSaveImage("output.bpm",frame);をつかっています. struct _HSV { int H; int S; int V; }HSV[1920][1080]; int main (int argc, char **argv) { …  //初期設定 // (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); frame = cvQueryFrame (capture); src_buf = new short[ frame->width * frame->height ]; // (3)カメラから画像をキャプチャする while (1)   {   frame = cvQueryFrame (capture); for(y = 0; y < frame->height; y++) { for(x = 0; x < frame->width; x++) {   p[0] = frame->imageData[frame->widthStep * y + x * 3]; // B   p[1] = frame->imageData[frame->widthStep * y + x * 3 + 1]; // G   p[2] = frame->imageData[frame->widthStep * y + x * 3 + 2]; // R   if (p[0] >= p[1] && p[0] >= p[2]) {max = p[0];} //Bがmax   else if (p[1] >= p[0] && p[1] >= p[2]) {max = p[1];} //Gがmax   else {max = p[2];} //Rがmax   if (p[0] <= p[1] && p[0] <= p[2]) {min = p[0];} //Bがmin   else if (p[1] <= p[0] && p[1] <= p[2]) {min = p[1];} //Gがmin   else {min = p[2];} //Rがmin   if(max==min){ HSV[y][x].H = 0; HSV[y][x].S = 0; HSV[y][x].V = p[0]; //R   }   else   { if(max==p[2])         {   HSV[y][x].H = 60 * (p[1]-p[0])/(max-min); } else if(max==p[1]) {   HSV[y][x].H = 60 * (p[0]-p[2])/(max-min);   HSV[y][x].H += 120; } else {   HSV[y][x].H = 60 * (p[2]-p[1])/(max-min);   HSV[y][x].H += 240; }

関連するQ&A

  • C++の関数等を使った書き方

    C++OpenCVで関数等を使ってプログラムをみやすくまとめたいのですが、教えていただけないでしょうか。 プログラムの内容はHSV変換をしています。 これをmain文より外に出したい場合どのような書き方をすればいいでしょうか。 返り値はHSVの3つがほしいです。 struct _HSV { int H; int S; int V; }HSV[2000][2000]; main(void){ 宣言 src_img = cvLoadImage (filename, CV_LOAD_IMAGE_COLOR); for(y = 0; y < src_img->height; y++) { for(x = 0; x < src_img->width; x++) { p[0] = src_img->imageData[src_img->widthStep * y + x * 3]; // B p[1] = src_img->imageData[src_img->widthStep * y + x * 3 + 1]; // G p[2] = src_img->imageData[src_img->widthStep * y + x * 3 + 2]; // R if (p[0] >= p[1] && p[0] >= p[2]) {max = p[0];} //Bがmax else if (p[1] >= p[0] && p[1] >= p[2]) {max = p[1];} //Gがmax else {max = p[2];} //Rがmax if (p[0] <= p[1] && p[0] <= p[2]) {min = p[0];} //Bがmin else if (p[1] <= p[0] && p[1] <= p[2]) {min = p[1];} //Gがmin else {min = p[2];} //Rがmin if(max==min){ HSV[y][x].H = 0; HSV[y][x].S = 0; HSV[y][x].V = p[0]; //R } else { if(max==p[2]){ //Rがmax HSV[y][x].H = 60 * (p[1]-p[0])/(max-min); } else if(max==p[1]) //Gがmax { HSV[y][x].H = 60 * (p[0]-p[2])/(max-min); HSV[y][x].H += 120; } else //Bがmax { HSV[y][x].H = 60 * (p[2]-p[1])/(max-min); HSV[y][x].H += 240; } if(HSV[y][x].H < 0) { HSV[y][x].H += 360; } } if(x % 60== 0){ fprintf(fp, "%d ,%d\n", HSV[y][x].H, HSV[y][x].S); } } } } 初歩的な質問ですみません。 できれば、関数以外でもこうすれば見やすい等ご指摘頂けると助かります。 よろしくお願いします。

  • K-meansについて教えてください。

    OpenCVを利用し、肌色部分をHSV値の範囲により緑色に変えています。(while文)ここから顔、右手、左手の3つにK-meansを使って三色に分けたいのですが、どのように変えればいいですか?クラスタの中心の座標を使うので座標でクラスタリングしたいです。 #include "stdafx.h" #include <cv.h> #include <highgui.h> #pragma comment(lib,"cv.lib") #pragma comment(lib,"cxcore.lib") #pragma comment(lib,"highgui.lib") #include <math.h> #define LINE_THICKNESS -1 #define LINE_TYPE 8 #define SHIFT 0 #define MAX_CLUSTERS (3) int _tmain(int argc, _TCHAR* argv[]) { CvSeq *objects; CvRect *r; char *cascade_name; int key; int i = 1; ////////////////////////////////////////////////////////////////// int x, y, W, H; int ofs, idx; unsigned char *pix; int pixCnt; int pixCnt2; int h, s, v; double n, m; double aveH, aveS, aveV; double divh, divs, divv; double divH, divS, divV; double aveH2, aveS2, aveV2; double sigmaH, sigmaS, sigmaV; /////////////////////////////////////////////////////////////////////////// CvCapture* src; IplImage *frame1; IplImage *frame2; IplImage *frame3; CvHaarClassifierCascade *cascade; CvMemStorage *storage; cvNamedWindow ("原画像"); cvNamedWindow ("HSV画像"); cvNamedWindow ("処理結果"); // カスケード・ファイルの読み込み cascade_name = "haarcascade_frontalface_default.xml"; cascade = (CvHaarClassifierCascade *) cvLoad(cascade_name, 0, 0, 0); storage = cvCreateMemStorage (0); cvClearMemStorage(storage); src = cvCaptureFromCAM(0); if(src == NULL){printf("映像が取得できません。\n"); cvWaitKey(0); return -1; } frame1 = cvQueryFrame(src); frame2 = cvCreateImage(cvGetSize(frame1), IPL_DEPTH_8U, 3); frame3 = cvCreateImage(cvGetSize(frame1), IPL_DEPTH_8U, 3); //顔領域の検出 objects = cvHaarDetectObjects(frame1, cascade, storage, 1.1, 3, 0, cvSize(0, 0)); r = (CvRect *) cvGetSeqElem(objects, i); cvRectangle(frame1, cvPoint(r->x, r->y) , cvPoint(r->x + r->width, r->y + r->height), CV_RGB(0, 255, 0), 4); cvCvtColor(frame1, frame2, CV_BGR2HSV); ///////////////////////////////////////////////////////////////////////// pix = (unsigned char*)frame2->imageData; pixCnt = frame2->width*frame2->height; pixCnt2 = r->width/6*r->height/6; printf( "%d\n", pixCnt ); printf("pixCnt2: %d\n", pixCnt2); aveV = aveS = aveH = 0; for( y=r->y+r->height/2; y<r->y+r->height/2+r->height/6; y++ ) { ofs = y*frame2->widthStep; for( x=r->x+r->width*2/3; x<r->x+r->width*2/3+r->width/6; x++ ) { idx = ofs + x*3; aveS += pix[idx+1]; if (pix[idx+1] >= 0) { aveH += pix[idx]; } else { pixCnt2--; } } } aveS /= pixCnt2; aveH /= pixCnt2; printf("H%f,S%f,V%f\n", aveH, aveS, aveV); aveH2 = 0; divh = 0; for( y=r->y; y<r->y+r->height; y++ ) { ofs = y*frame2->widthStep; for( x=r->x; x<r->x+r->width; x++ ) { idx = ofs + x*3; aveH2 += (pix[idx]-aveH)*(pix[idx]-aveH); } } aveH2 /= pixCnt2; divH = aveH2; sigmaH = sqrt(aveH2); while(1){ frame1 = cvQueryFrame(src); if(frame1 == NULL) break; // 1フレーム取得 cvRectangle(frame1, cvPoint(r->x, r->y) // 検出部に四角枠描画 , cvPoint(r->x + r->width, r->y + r->height), CV_RGB(0, 255, 0), 4); cvCvtColor(frame1, frame2, CV_BGR2HSV); cvShowImage ("原画像", frame1); // 検出結果表示 cvShowImage ("HSV画像", frame2); // 検出結果表示 for( y=0; y<frame2->height; y++ ) { ofs = y*frame2->widthStep; for( x=0; x<frame2->width; x++ ) { idx = ofs + x*3; v = pix[idx+2]; s = pix[idx+1]; h = pix[idx]; if ((h > aveH-sigmaH && h < aveH+sigmaH)&& (s > aveS-10 && s < aveS+10)) { pix[idx+2] = 230; pix[idx+1] = 230; pix[idx] = 60; } else { pix[idx+2] = 0; pix[idx+1] = 0; pix[idx] = 0; } } } cvCvtColor(frame2, frame3, CV_HSV2BGR); cvShowImage ("処理結果", frame3); // 検出結果表示 if(cvWaitKey(33) == 27) break; // ESCキーを押した時終了 } // ウィンドウ・キャプチャ・メモリの解放 cvReleaseImage(&frame1); cvReleaseImage(&frame2); cvReleaseImage(&frame3); cvDestroyWindow("原画像"); cvDestroyWindow("HSV画像"); cvDestroyWindow("処理結果"); cvReleaseCapture(&src); cvReleaseMemStorage(&storage); return 0; }

  • 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フレーム前の値”というのを、どのように表現していいかわからないのです・・

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

  • 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での白黒画像読み込み

    いつも大変お世話になっております。 ピクセルの値を「ゼロ(黒)」にしたピクセルを読み込んでも「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; } }

  • 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の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の画像データを格納する構造体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); } } 何が原因なのか教えていただけないでしょうか。

専門家に質問してみよう