圖像處理——(源)線性疊加(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自己寫的函數的效果

 

 

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

完!!!!!!!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM