• ベストアンサー

OpenCVを使った画像の切り抜き

添付画像のように、サイズ(X,Y)の画像があったとします。 その画像のある座標(X',Y')とサイズを指定してできた短形領域を、IplImageとして保存するにはどうすればいいのでしょうか? OpenCVを使ってるのですが、そういった関数はなかったでしょうか? よろしくお願いします。

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

  • ベストアンサー
回答No.1

 こんにちは。  cvSetImageROI()で領域指定です。以下参考程度に。  http://opencv.jp/sample/initialization.html int main() { //イメージをロード IplImage* ipl = ::cvLoadImage("test.bmp", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); //x=10, y=10から64x32でROIを設定 ::cvSetImageROI(ipl, ::cvRect(10, 10, 64, 32)); //ROIを設定した状態でセーブ ::cvSaveImage("result.bmp", ipl); //ROIの解除 ::cvResetImageROI(ipl); //イメージの解放 ::cvReleaseImage(&ipl); return 0; }

avenew
質問者

お礼

できました! そういえばcvSetImageROIという関数がありましたね。 ありがとうございました!

関連するQ&A

  • OPENCVの画像処理について

    現在OPENCVを使って画像処理の勉強をしているのですが画像を読み込む際 IplImage* cvLoadImage という関数?を使って画像を読み込んでいるのですが 例えばファイルAに10枚画像が入っていたとしてその10枚をIplImage* cvLoadImageで一枚ずつ読み込むのではなくまとめて読みこむ(配列のように読みこんだ画像の順から[1]などの番号が付くような)という関数はないのでしょうか? 画像を変えるたびに「名前.jpg」を変えないといけない手間を省きたいです。

  • opencvを使って画像比較

    opencvを使って画像比較をしたいです。 具体的には、デスクトップの背景の一部分(4×4bitくらい)が、画面上にあれば処理を実行する、みたいにしたいです。(他のウィンドウなどで隠れていたら実行しない) 具体的にどのような関数を使えば作れますか? テンプレートマッチングという方法でいけそうなのですが、一旦プリントスクリーンキーなどで画面を保存して、それと切り取った4×4の画像を比較していく。のような感じにすればいいのでしょうか? そのような関数はあるのでしょうか? それと画面を一瞬で保存して、IplImageに保存する。みたいな関数はありますか? 下手くそな日本語ですが回答よろしくお願いします・・。

  • openCVについて‥

    openCVでIplImage構造体の変数に格納された画像の座標値(i,j)の画素RBG値を取れだす方法を知れたいのですが、ご存知の方、是非ご教授ください。

  • C++での画像切り抜きについて

    こんにちは。プログラミング初心者です。 Microsoft Visual Studio C++ MFCで画像解析のプログラムを書いています。 その際、jpg画像から左上隅・右下隅の座標を指定してある領域を切り出したいのですが、 今の方法では切り出した画像の周りに黒の領域ができてしまいます。(添付画像参照) サイズを切り抜いた画像のサイズに変更して、黒の領域をなくしたいのですが、 どのように書けばいいのでしょうか? 下記のコードに追加する部分・変更する部分を具体的に教えていただけると有難いです。 説明不足で申し訳ありませんが、よろしくお願いいたします。 void CtestbView::OnUleft() //左上隅点の座標 { // TODO: ここにコマンド ハンドラー コードを追加します。 Lcpx=px; //左上隅のx座標 Lcpy=py; //左上隅のy座標 } void CtestbView::OnDright() //右下隅点を指定するサブルーチン { // TODO: ここにコマンド ハンドラー コードを追加します。 int x,y; Rcpx=px;//右下隅x座標 Rcpy=py;// y for(y=Lcpy-1; y<=Rcpy+1; y++) {//切り出し範囲を白線で囲む(白線を切り出さないため+-1を付加) img1.SetPixel(Lcpx-1,y,RGB(255,255,255)); //左側縦線 img1.SetPixel(Rcpx+1,y,RGB(255,255,255)); //右側縦線 } for(x=Lcpx-1; x<=Rcpx+1; x++) { img1.SetPixel(x,Lcpy-1,RGB(255,255,255)); //上側横線 img1.SetPixel(x,Rcpy+1,RGB(255,255,255)); //下側横線 } jpgLoadFlag1=true; Invalidate(); } void CtestbView::OnCut() //テンプレートを切り出すサブルーチン { // TODO: ここにコマンド ハンドラー コードを追加します。 int x,y; BeginWaitCursor(); for(y=0; y<jpgHeight; y++) for(x=0; x<jpgWidth; x++) img2.SetPixel(x,y,RGB(0,0,0)); //画面をクリア int xshift=0; int yshift=0; for(y=Lcpy; y<=Rcpy; y++) { for(x=Lcpx; x<=Rcpx; x++) { COLORREF color=img1.GetPixel(x,y); int RV=GetRValue(color); int GV=GetGValue(color); int BV=GetBValue(color); img2.SetPixel(x-Lcpx+xshift,y-Lcpy+yshift,RGB(RV,GV,BV)); } } xminP=xshift; xmaxP=Rcpx-Lcpx+xshift; //テンプレート上のパターンの位置 yminP=yshift; ymaxP=Rcpy-Lcpy+yshift; jpgWidth=xmaxP; jpgHeight=ymaxP; jpgLoadFlag2=true; Invalidate(); EndWaitCursor(); } void CtestbView::OnLButtonDown(UINT nFlags, CPoint point) //指定点の座標値を取り出す { // TODO: ここにメッセージ ハンドラー コードを追加するか、既定の処理を呼び出します。 CView::OnLButtonDown(nFlags, point); int i,j; int x,y; px=point.x; //マウス指定点のx座標 py=point.y; //マウス指定点のy座標 COLORREF color=img1.GetPixel(px,py); //指定点のアドレス変換 rv=GetRValue(color); //マウス指定点の赤成分 gv=GetGValue(color); //マウス指定点の緑座標 bv=GetBValue(color); //マウス指定点の青座標 img1.SetPixel(px, py, RGB(255,0,0));//指定点位置の赤点表示 for(j=0; j<=20; j++)//指定点の色を20×20の短径で表示 for(i=0; i<=20; i++) img1.SetPixel(jpgWidth-30+i,20+j,RGB(rv,gv,bv)); //指定点の色設定 jpgLoadFlag1=true; InvalidateRect(NULL); }

  • 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を用いた二値画像のアクセスと座標の取得

    いつもお世話になっています。 opencvを用いたプログラムを作成しています。 真ん中に大きな塗りつぶされた●が1つあるカラー画像を二値画像に変換して、●の部分のすべての座標をとりたいと考えています。(●は大きいので1ピクセルではありません。●を構成しているピクセルの座標すべてをとるといった感じです。) 今、途中まで作成したのですが間違っているところがあると考えられるので、エラーは出ないのですがプログラムが正常に動きません。このプログラム内での間違いであるとは考えられるので、間違っている部分を教えてもらえないでしょうか? よろしくお願いします。 //元のカラー画像 IplImage* image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); IplImage* gray_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); //二値画像 IplImage* niti_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); //座標を入れるための配列 int test_width[500]; int test_height[500]; //カラー画像ここでimage画像に大きな●を書きました。これ以降は●がimageに存在するものとして考えてくださいお願いします cvDrawContours( image, hand_contour[0], CV_RGB (0, 0, 0), CV_RGB (0, 0, 0), -1, CV_FILLED, 8 ,cvPoint(0,0)); //グレースケールの作成 cvCvtColor(image,gray_image,CV_BGR2GRAY); // 画像の二値化【判別分析法(大津の二値化)】 cvThreshold (gray_image, niti_image, 90, 255, CV_THRESH_BINARY); int k = 0;      // 左上から順番に画像を見ていく for( int y = 0; y < niti_image->height; y++){ for(int x = 0; x < niti_image->width; x++){ //もし黒色の値が入っていたら配列に座標を代入する if(niti_image->imageData[y * niti_image->widthStep + x * niti_image->nChannels] == 0){ test_width[k] = x; test_height[k] = y;   k++;             }//if } }

  • opencvのシーケンスについて。

    opencvのシーケンスについて。 opencvのシーケンスとは。 opencvを使っていると、よくシーケンスという言葉に遭遇します。本やネットで調べましたが、どんなものなのかがよく分かりません。 メモリストレージ・オブジェクト等と一緒に出てくるのですが、これらもなかなか理解しがたいです… 例えばCvFindCountorという画像内のn個の辺を持つ輪郭を調べるという関数がありますが、これに関する情報が引数として渡したシーケンスに保存されているようだ。というのは何となく感じとったのですが、この中の座標等を引き出すにはどうしたらいいのでしょうか。 どなたか分かりやすくご教授頂けないでしょうか。 また、分かりやすいサイトや本もご存知であれば教えて下さい。

  • OpenCVで画像をある角度から見たように変換する

    OpenCVを使い、画像をある角度から見たように変換したいと考えています。 しかし、cvGetPerspectiveTransform関数では4つの頂点座標を入力することによって変換行列を作成しているみたいなんですが、角度の概念がなくどうしようか困っています。 私がしたいのは任意の角度からみたように画像を回転させたいのでどうすればいいかわかりません。 言いたいことがうまく伝わらないかもしれませんがよろしくお願いします。

  • OpenCV処理画像をpictureBoxへ。

    VC++にて画像処理を行っています。 OpenCVのライブラリを使って画像処理をしようと考えているのですが、 処理した画像がMFCで作成したpitureBoxに表示の仕方が分かりません。 調べていくうちに、 「IplImage形式の画像を直接ウィンドウに描画することは出来ないので、 画像をDIBセクション形式に変換してWindows固有の描画処理を行うといい。」 ということが分かり、DIBセクション形式への変換には、IPLを入手し、 「iplConvertToDIB()関数」を使うということが分かりました。 このiplConvertToDIB()関数をつかって画像表示の方法を教えてはいただけないでしょうか?サンプルのソースなどありましたらよろしくお願いいたします。

  • OpenCVでの画像サイズ取得について教えてください。

    OpenCVでの画像サイズ取得について教えてください。 rawデータをjpgにして取得し、その画像を4分割したいのですがエラーが3つ出てしまいます。 環境はVisual Studio2008です。 いろいろと調べたのですが、原因や対策がはっきりわからず、書き変えてもNGで困っています。 エラー:その1 「error LNK2028:未解決のトークン(0A00007B)"extern "C" struct IplImage *_cdecl cvLoadImage(char const roi.obj*.int)"(cvLoadImage@@$$J0YAPAU IplImage@@PBDH@Z)が関数"int _codecl main(int,char * *)"(?main@@$$HYAHHPAPAD@Z)で参照されました。」 エラー:その2 「error LNK2019: 未解決の外部シンボル"extern "C" struct IplImage * codecl cvLoadImage(char const *.int)" (?cvLoadImage@@$$J0YAPAU IplImage@@PBDH@Z)が関数"int_codecl main(int, char * *)" (?main@@$$HYAHHPAPAD@Z)で参照されました。」 エラー:その3 「fatal error LNK1120: 外部参照2が未解決です] '================== #pragma warning(disable : 4819) #include <cv.h> #include <highgui.h> #include <stdio.h> #define DIVX (4) #define DIVY (4) #define DIVXY (DIVX*DIVY) int main (int argc, char **argv) { int w, h IplImage *img=0; img=cvLoadImage("C:\・・・\\testfile.jpg, CV_LOAD_IMAGE_GRAYSCALE); w = img->width - img->width % DIVX + DIVX; h = img->height - img->height % DIVY + DIVY; printf("幅は%w, 高さは%h です。 \n"); } '=============================================== 画像サイズを取得し、画像を4分割したあと、画素値を変更したいと思っています。 できればjpgに変換せず、rawデータそのものの精度の画像を直接扱いたいのですが、 その場合、cvLoadImageでどう表記すると実現できるのでしょうか。 また、OpenCVのグレースケールは、何チャンネルなのでしょうか。 プログラム経験はありますが、OpenCVを使うため、C言語の勉強も始めたばかりです。 なにか見当違いな質問をしていたら申し訳ありません。 お忙しいところすみませんが、もしどなたか解決策をアドバイスいただける方がいらっしゃると 大変助かります。 どうぞ宜しくお願い致します。