opencv学习之感兴趣区域(ROI)

新手学习就是苦啊,好多东西都要一点点的摸索,之前的经验太少,积累太少,许多问题太简单了,问别人都不好开口,谁让自己太low了啊!

那就自己折腾呗……

今天看了opencv的矩阵和图像操作部分内容,这里把这折腾的过程弄上来了

书上给了两种获得感兴趣矩形区域的方式


一个是直接用函数  cvSetImageROI(IplImage* image, Cvrect  rect),    其中image是加载的一幅图像,  rect =  cvRect(x, y, width,  height) ,x,y给出了矩形在原图像中的起点(从左上起),width,height给出了矩形的宽和高。    书中示例给出了将该矩形区域的蓝色通道增加150  ( 即语句cvAddS(interestimg, cvScalar(add), interestimg))后的图像输出。书中源码如下:


#include 
#include 
// ch3_ex3_12 image_name x y width height add# 
int main(int argc, char** argv)
{

    IplImage* src;
    cvNamedWindow("Example3_12_pre", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("Example3_12_post", CV_WINDOW_AUTOSIZE);  
    if( argc == 7 && ((src=cvLoadImage(argv[1],1)) != 0 ))
    {
		int x = atoi(argv[2]);
		int y = atoi(argv[3]);
		int width = atoi(argv[4]);
		int height = atoi(argv[5]);
		int add = atoi(argv[6]);
		cvShowImage( "Example3_12_pre", src);
		cvSetImageROI(src, cvRect(x,y,width,height));
		cvAddS(src, cvScalar(add),src);
		cvResetImageROI(src);
		cvShowImage( "Example3_12_post",src);
      cvWaitKey();
    }
  cvReleaseImage( &src );
  cvDestroyWindow("Example3_12_pre");
  cvDestroyWindow("Example3_12_post");   
    return 0;
}


另一个方法是通过使用widthStep来直接达到与上面相同的效果,这个相当于通过原图的信息来建立一个需要的长宽的矩形IplImage类型,然后再根据期望的感兴趣区域位置,找到矩形的左上角在原图上的坐标,这样就成功划出了感兴趣矩形区域了

与此同时,根据后面的alpha融合的内容,试着将载入了另一幅图像,然后选取了该图像同样大小的一部分,和原图的感兴趣区域按一定的权值融合了,于是使得操作区域出现了“你中有我,我中有你”的现象

 

#include 
#include 
// ch3_ex3_12 image_name x y width height add# 
int main(int argc, char** argv)
{

	IplImage* src;
	IplImage* src2;
	cvNamedWindow("Example3_12_pre", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("Example3_12_post", CV_WINDOW_AUTOSIZE);
	if (argc == 10 && ((src = cvLoadImage(argv[1], 1)) != 0))
	{
		src2 = cvLoadImage(argv[9]);
		IplImage* interestimg = cvCreateImageHeader(
			cvSize(250, 300),
			src->depth,
			src->nChannels
			);
		IplImage* interestimg2 = cvCreateImageHeader(
			cvSize(250, 300),
			src->depth,
			src->nChannels
			);
		interestimg2->origin = src2->origin;
		interestimg2->widthStep = src2->widthStep;
		interestimg2->imageData = src2->imageData + 12 * src2->widthStep + 12 * src2->nChannels;
		interestimg->origin = src->origin;
		interestimg->widthStep = src->widthStep;
		interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels;
		int add = atoi(argv[6]);
		//double alpha = (double)atof(argv[7]);
		//double beta = (double)atof(argv[8]);
		cvShowImage("Example3_12_pre", src);
	    //cvAddS(interestimg, cvScalar(add), interestimg);
		cvAddWeighted(interestimg, alpha, interestimg2, beta, 0.0, interestimg);
		//interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels + 1;
		//cvAddS(interestimg, cvScalar(20), interestimg);
		//interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels + 2;
		//cvAddS(interestimg, cvScalar(30), interestimg);
		cvResetImageROI(src);
		cvShowImage("Example3_12_post", src);
		cvWaitKey();
	}
	cvReleaseImage(&src);
	cvDestroyWindow("Example3_12_pre");
	cvDestroyWindow("Example3_12_post");
	return 0;
}


书中源程序使用

         sub_img->imageData = interest_img->imageData +
          interest_rect.y * interest_img->widthStep  +
          interest_rect.x * interest_img->nChannels;

来找到感兴趣区域的左上角坐标,这样是对蓝色通道数据进行操作,我们可以在后面+1,或+2来对红色或绿色通道来操作,如:interestimg->imageData = src->imageData + 120 * src->widthStep + 120 * src->nChannels + 1;来对红色通道操作


在本程序中,出项了之前没用过的函数“atoi()”,这是一个将字符转换为整形的函数,比如,命令参数中输入的字符串“12”,可以用该函数转换为整形数“12”,同样,atof()将字符转换为浮点型……







你可能感兴趣的:(opencv,opencv,C++)