注:本文部分文字参考自OpenCV中文网,仅供个人学习记录之用!如果无意中侵犯了您的版权请联系本人:[email protected],.本人会及时编辑掉
一,概述
既然我们要执行
我们需要两幅输入图像 ( 和 )。相应地,我们使用常用的方法加载图像
Warning
因为我们对 src1 和 src2 求 和 ,它们必须要有相同的尺寸(宽度和高度)和类型。
现在我们生成图像 .为此目的,使用函数 addWeighted 可以很方便地实现:
这是因为 addWeighted 进行如下计算
这里 对应于上面代码中被设为 的参数。
创建显示窗口,显示图像并等待用户结束程序。
AddWeighted
计算两数组的加磅值的和
void cvAddWeighted( const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst );
src1 第一个原数组.
alpha 第一个数组元素的磅值
src2 第二个原数组
beta 第二个数组元素的磅值
dst 输出数组
gamma 作和合添加的数量。
函数 cvAddWeighted 计算两数组的加磅值的和: dst(I)=src1(I)*alpha+src2(I)*beta+gamma
所有的数组必须的相同的类型相同的大小(或 ROI 大小)
createTrackbar
Creates a trackbar and attaches it to the specified window.
第一个参数,const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是是由该变量当前的值。
第四个参数,int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
第六个参数,void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。下面的例子中用到的调用为
二,实验
1,线性融合图像
// ConsoleAppOpenCvAddImages.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace cv; int _tmain(int argc, _TCHAR* argv[]) { double alpha = 0.5; double beta=0.0; double input=0.0; int count=0; Mat src1, src2, dst; while (true) { /// Ask the user enter alpha std::cout<<" Simple Linear Blender "<<std::endl; std::cout<<"-----------------------"<<std::endl; std::cout<<"* Enter alpha [0-1]: "; std::cin>>input; // We use the alpha provided by the user iff it is between 0 and 1 if( alpha >= 0 && alpha <= 1 ) alpha = input; /// Read image ( same size, same type ) src1 = imread("LinuxLogo.jpg"); src2 = imread("WindowsLogo.jpg"); if( !src1.data ) { std::cout<< "Error loading src1"<<std::endl; return -1; } if( !src2.data ) { std::cout<< "Error loading src2"<<std::endl; return -1; } /// Create Windows namedWindow("Linear Blend", 1); beta = ( 1.0 - alpha ); addWeighted( src1, alpha, src2, beta, 0.0, dst); imshow( "Linear Blend", dst ); count++; if (count>10) { break; } waitKey(0); } return 0; }
2,实验二,添加滑动条
// ConsoleAppMatTest.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include < opencv2/highgui/highgui.hpp > #include "iostream" using namespace std; using namespace cv; /** Global Variables */ const int alpha_slider_max = 100;//滑动条最大值 int alpha_slider_init;//滑动条初始值 double alpha; double beta; /** Matrices to store images */ Mat src1;//第一附图 Mat src2;//第二幅图 Mat dst;//存储融合后的图像 static void on_trackbar( int, void* ) { //判断两幅图片是否相同以及是否成功读入 CV_Assert(src1.depth() == CV_8U); CV_Assert(src1.depth() == src2.depth()); CV_Assert(src1.size() == src2.size()); if( !src1.data ) cout<<"Error loading src1"<<endl; if( !src2.data ) cout<<"Error loading src2"<<endl; /******************融合开始********************/ alpha = (double) alpha_slider_init/alpha_slider_max ; beta = ( 1.0 - alpha ); addWeighted( src1, alpha, src2, beta, 0.0, dst);//线性融合 imshow( "Linear Blend", dst ); } int main( void ) { /// Read image ( same size, same type ) src1 = imread("LinuxLogo.jpg"); src2 = imread("WindowsLogo.jpg"); /// Initialize values alpha_slider_init = 10; /// Create Windows namedWindow("Linear Blend", 1); /// 创建滑动条 char TrackbarName[50];//滑动条名字 sprintf_s( TrackbarName, "Alpha x %d", alpha_slider_max ); createTrackbar( TrackbarName, "Linear Blend", &alpha_slider_init, alpha_slider_max, on_trackbar ); /// Show some stuff on_trackbar( alpha_slider_init, 0 ); /// Wait until user press some key waitKey(0); return EXIT_SUCCESS; }
三,OpenCV+MFC简单实现
未完待续...........