图像处理——(源)线性叠加(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自己写的函数的效果

追求本源,源理才是真正的原理!

完!!!!!!!!!

萍水相逢逢萍水,浮萍之水水浮萍!
原文地址:https://www.cnblogs.com/AIBigTruth/p/11135160.html