新手学习就是苦啊,好多东西都要一点点的摸索,之前的经验太少,积累太少,许多问题太简单了,问别人都不好开口,谁让自己太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()将字符转换为浮点型……