图像处理——(源)线性叠加(addWeighted)函数编程实现
找了很久addWeighted函数的实现,硬是没找到,气的自己码一码。效果还不错。
源理是线性混合操作,g(x)=(1-a)f1(x)+af2(x),0<=a<=1;产生时间上的画面重叠。
像网上一样先来函数解析(找到的都是这个,讲一下函数怎么用,再调用一下函数看看效果,看得吐血)
addWeighted原函数:
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);
第一个参数:要叠加的第一个图像Mat
第二个参数:标识第一个参数叠加的权重
第三个参数:表示第二个叠加的图像,他需要和第一个数组拥有同样的尺寸和通道数
第四个参数:表示第二个叠加图像的权重
第五个参数:输出参数,需要和前两个图像拥有同样的通道数和尺寸
第六个参数:一个加到权重总和上的标量值(填0就好)
第七个参数:输出阵列的深度有默认值-1, 当两张叠加图片深度相同时,参数为-1
对应表达式为:dst = src1[i] * alpha + src2[i] * beta + gamma;//两张图片每个通道对应数值之和。
重点!!!!!!!!!!!!!!!!!!!
自己实现这个函数,三个图都是512*512*3
1 #include <opencv2/opencv.hpp> 2 #include <opencv2/core/core.hpp> 3 #include<iostream> 4 #include<stdlib.h> 5 using namespace cv; 6 using namespace std; 7 //原int main() 8 bool add() 9 { 10 Mat srcImage=imread("E://wpp.jpg"); 11 if(!srcImage.data){ 12 printf("error"); 13 return false; 14 } 15 Mat logoImage=imread("E://opencv.jpg"); 16 if(!logoImage.data){ 17 printf("error"); 18 return false; 19 } 20 Mat ImageROI=srcImage(Rect(200,250,logoImage.cols,logoImage.rows)); 21 Mat mask=imread("E://opencv.jpg",0); 22 logoImage.copyTo(ImageROI,mask); 23 namedWindow("add"); 24 imshow("add",srcImage); 25 waitKey(0); 26 return true; 27 28 } 29 //原int main() 30 bool addw() 31 { 32 double alp=0.5; 33 double bet=0.5; 34 Mat src2,src3,dst; 35 src2=imread("E://wpp3.jpg"); 36 src3=imread("E://rice.jpg"); 37 resize(src2,src2,Size(500,500)); 38 resize(src3,src3,Size(500,500)); 39 addWeighted(src2,alp,src3,bet,0.0,dst); 40 namedWindow("addw"); 41 imshow("addw",dst); 42 waitKey(0); 43 return true; 44 } 45 //方法一 46 void addweighted_my1(Mat & src1,double alpha,Mat &src2,double beta,double gama,Mat &src3,int dtype=-1) 47 { 48 int row=src1.rows; //行数 49 int col=src1.cols*src1.channels();//列数*通道数=每一行元素个数 50 //行循环列循环 51 for(int i=0;i<row;i++){ 52 uchar* data1=src1.ptr<uchar>(i);//获取第i行首地址 53 uchar* data2=src2.ptr<uchar>(i); 54 uchar* data3=src3.ptr<uchar>(i); 55 for(int j=0;j<col;j++){ 56 data3[j]=data1[j]*0.4+data2[j]*0.6+gama;//g(x)=(1-a)f1(x)+af2(x)+gama,两个像素的加权和,产生时间上的画面叠加 57 } 58 } 59 } 60 //方法二 61 void addweighted_my2(Mat & src1,double alpha,Mat &src2,double beta,double gama,Mat &src3,int dtype=-1) 62 { 63 int row=src1.rows; //行数 64 int col=src1.cols; //列数 65 //行循环列循环 66 for(int i=0;i<row;i++){ 67 for(int j=0;j<col;j++){ 68 src3.at<Vec3b>(i,j)[0]=alpha*src1.at<Vec3b>(i,j)[0]+beta*src2.at<Vec3b>(i,j)[0]+gama;//蓝色通道 69 src3.at<Vec3b>(i,j)[1]=alpha*src1.at<Vec3b>(i,j)[1]+beta*src2.at<Vec3b>(i,j)[1]+gama;//绿色通道 70 src3.at<Vec3b>(i,j)[2]=alpha*src1.at<Vec3b>(i,j)[2]+beta*src2.at<Vec3b>(i,j)[2]+gama;//红色通道 71 } 72 } 73 } 74 75 76 int main() 77 { 78 double alpha=0.4,beta=0.6; 79 double gama0=0; 80 double gama1=100; 81 double gama2=1000; 82 Mat src1=imread("E://lena.jpg"); 83 Mat src2=imread("E://opencv.jpg"); 84 Mat src3=imread("E://heibai.jpg"); 85 imshow("lena",src1); 86 imshow("opencv",src2); 87 imshow("heibai",src3); 88 //addWeighted(src1,alpha,src2,beta,gama0,src3); 89 //addweighted_my1(src1,alpha,src2,beta,gama1,src3); 90 addweighted_my2(src1,alpha,src2,beta,gama2,src3); 91 imshow("addweighted",src3); 92 waitKey(0); 93 return 0; 94 95 }
运行结果
opencv自带的addWeighted效果:
addWeighted_my1自己写的函数的效果
addWeighted_my2自己写的函数的效果
追求本源,源理才是真正的原理!
完!!!!!!!!!