今天我们来一起学习在OpenCV中如何定义感兴趣区域ROI,如何使用addWeighted函数对两幅图像进行混合,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操作。
一、图像的混合
1、addWeighted函数详解
功能:计算两幅图像的加权和。
公式:
dst = src1 * alpha + src2 * beta + gamma;
函数原型:
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);
(1)第一个参数,src1,表示需要加权的第一个数组,常常填一个Mat类型的图像;
(2)第二个参数,alpha,表示第一个数组的权重;
(3)第三个参数,src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数;
(4)第四个参数,beta,表示第二个数组的权重值;
(5)第五个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数;
(6)第六个参数,gamma,一个加到权重总和上的标量值,看上面的公式就会理解了;
(7)第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。
2、createTrackbar()函数
功能:它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上。
函数原型:
int createTrackbar( const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange = 0, void* userdata = 0);
(1)第一个参数,const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条;
(2)第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名;
(3)第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置,并且在创建时,滑块的初始位置就是该变量当前的值;
(4)第四个参数,int类型的count,表示滑块可以达到的最大位置的值,滑块最小的位置的值始终为0;
(5)第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0,这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调,并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化;
(6)第六个参数,void*类型的userdata,它也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件,如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
3、线性混合操作
线性混合操作是一种典型的二元(两个输入)的像素操作,它的理论公式是这样的:
线性混合操作
我们通过在范围0到1之间改变alpha值,来对两幅图像(f0(x)和f1(x))或两段视频(同样为(f0(x)和f1(x))产生时间上的画面叠化(cross-dissolve)效果,就像幻灯片放映和电影制作中的那样,即在幻灯片翻页时设置的前后页缓慢过渡叠加效果,以及电影情节过渡时经常出现的画面叠加效果。
实例:
#include #include #include using namespace cv;using std::cout;const int alpha_slider_max = 100;int alpha_slider;double alpha;double beta;Mat src1;Mat src2;Mat dst;static void on_trackbar(int, void*){ alpha = (double)alpha_slider / alpha_slider_max; beta = (1.0 - alpha); // 对两幅图像进行混合 addWeighted(src1, alpha, src2, beta, 0.0, dst); // 显示图像 imshow("Linear Blend