找了很久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自己寫的函數的效果
追求本源,源理才是真正的原理!
完!!!!!!!!!