Opencvは、ある画像の小さなブロック領域を別の画像の指定領域にコピーする

4224 ワード

Opencvは、ある画像の小さなブロック領域を別の画像の指定領域にコピーします.
// vv.cpp :              。
//opencv                        

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

int main()
{ 
	IplImage* img = cvLoadImage("c:\\lh.jpg",0);	
	CvRect roi =cvRect(6, 6, 48, 48); 
	cvNamedWindow("img");
	cvShowImage("img", img);

	IplImage* img1 = cvLoadImage("c:\\leehom.jpg",0);	
	CvRect roi1 = cvRect(6, 6, 48, 48); 
	cvNamedWindow("img1");
	cvShowImage("img1", img1);

	cvSetImageROI(img, roi);
	cvSetImageROI(img1, roi1);
	cvCopy(img1, img);
	cvResetImageROI(img);
	cvResetImageROI(img1);

	cvNamedWindow("result");

	cvShowImage("result", img);
	
	

	cvWaitKey(-1);
	cvReleaseImage(&img);
	cvReleaseImage(&img1);
	cvDestroyAllWindows();
	return 0;
}

結果図:
要注意
3チャネル画像について:【コピーした2枚の画像のdepthとnchanelsは同じはずですよ】
ええ、実はコードが同じです.初めて勝手に指定したRectエリアだけで、3チャンネル画像がダメで、cvSetImageROIのソースコードも見ました.
後で発見して、額、3つの通路、rect区域の指定はきっと3の倍数撒きです!
わざわざ同じrectエリアを设定してみたところ、コピーした画像が同じだったんですね.
いい料理額・・・
よくわかりませんが、階調図では6番目の画素点から始まり、3チャネル図も6番目の画素から始まるのではないでしょうか.過去の画像をコピーするのは同じですからね.
3チャネル図の6も6番目の画素を指す場合、roi 1は3の倍数ではないでしょうか.
もしこの6が3番目の画素の1番目のチャネル位置を指していたら、なぜ過去の画像をコピーするのと同じなのでしょうか???
ええ...しばらくは納得していませんが...
// vv.cpp :              。
//opencv                        

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

int main()
{ 
	IplImage* img = cvLoadImage("c:\\lh.jpg",1);	
	CvRect roi =cvRect(6, 6, 48, 48); 
	cvNamedWindow("img");
	cvShowImage("img", img);

	IplImage* img1 = cvLoadImage("c:\\leehom.jpg",1);	
	CvRect roi1 = cvRect(6, 6, 48, 48); 
	cvNamedWindow("img1");
	cvShowImage("img1", img1);

	cvSetImageROI(img, roi);
	cvSetImageROI(img1, roi1);
	cvCopy(img1, img);
	cvResetImageROI(img);
	cvResetImageROI(img1);

	cvNamedWindow("result");
	cvShowImage("result", img);
	
	

	cvWaitKey(-1);
	cvReleaseImage(&img);
	cvReleaseImage(&img1);
	cvDestroyAllWindows();
	return 0;
}

OpencvのcvSetImageROIはcvcore.hでは、具体的にはcxarray.cpp:
CV_IMPL void
cvSetImageROI( IplImage* image, CvRect rect )
{
    if( !image )
        CV_Error( CV_HeaderIsNull, "" );

    // allow zero ROI width or height
    CV_Assert( rect.width >= 0 && rect.height >= 0 &&
               rect.x < image->width && rect.y < image->height &&
               rect.x + rect.width >= (int)(rect.width > 0) &&
               rect.y + rect.height >= (int)(rect.height > 0) );
    
    rect.width += rect.x;
    rect.height += rect.y;
    
    rect.x = std::max(rect.x, 0);
    rect.y = std::max(rect.y, 0);
    rect.width = std::min(rect.width, image->width);
    rect.height = std::min(rect.height, image->height);
    
    rect.width -= rect.x;
    rect.height -= rect.y;

    if( image->roi )
    {
        image->roi->xOffset = rect.x;
        image->roi->yOffset = rect.y;
        image->roi->width = rect.width;
        image->roi->height = rect.height;
    }
    else
        image->roi = icvCreateROI( 0, rect.x, rect.y, rect.width, rect.height );
}

=================
後で私が使ったとき、私が使っているopencv 2なのか分からない奇妙な現象を発見しました.3.1リリースの問題
ex:
//顔領域CvRect roi=cvRect(r_ret->x*scale,r_ret->y*scale,r_ret->width*scale,r_ret->height*scale);cvRectangle(img, cvPoint(roi.x , roi.y ), cvPoint( roi.x + roi.width , roi.y + roi.height), CV_RGB(0, 255, 0), 3, 8, 0);  cvSetImageROI(img, roi);//顔画像を切り出し、階調マップIplImage*face=cvCreateImage(cvSize(roi.width,roi.height),8,1);cvCopy(img, face);cvResetImageROI(img);
これで大丈夫ですが、次は問題があります.
//顔領域CvRect roi=cvRect(r_ret->x*scale,r_ret->y*scale,r_ret->width*scale,r_ret->height*scale);cvRectangle(img, cvPoint(roi.x , roi.y ), cvPoint( roi.x + roi.width , roi.y + roi.height), CV_RGB(0, 255, 0), 3, 8, 0);//顔画像を切り出し、階調マップIplImage*face=cvCreateImage(cvSize(roi.width,roi.height),8,1);
         cvSetImageROI(img, roi);cvCopy(img, face);cvResetImageROI(img);
奇しくも、roiエリアは変わらないし......