1. 程式人生 > >線性混合操作

線性混合操作

在這裡插入圖片描述

利用cv::addWeighted()函式實現影象線性混合

  • 函式定義
void addWeighted(
       InputArray src1,//InputArray型別的src1,表示需要加權的第一個陣列,常常填一個Mat。
       double alpha, //表示第一個陣列的權重
       InputArray src2,//表示第二個陣列,它需要和第一個陣列擁有相同的尺寸和通道數。
       double beta, //表示第二個陣列的權重值。
       double gamma, //輸出的陣列,它和輸入的兩個陣列擁有相同的尺寸和通道數。
OutputArray dst, //一個加到權重總和上的標量值 int dtype = -1 //dtype,輸出陣列的可選深度,有預設值-1。;當兩個輸入陣列具有相同的深度時,這個引數設定為-1(預設值),即等同於src1.depth()。 );

相同通道數

  • 相同尺寸大小
    #include"opencv2/opencv.hpp"
    #include<iostream>
    using namespace cv;
    using namespace std;
    int main() {
         //【0】定義一些區域性變數  
    	Mat src,
    src2,dst,dst2,dst3; //【1】讀取影象 ( 兩幅圖片需為同樣的型別和尺寸 ) src = imread("D:\\test\\first.png"); src2 = imread("D:\\test\\second.png"); if (!src.data) { cerr << "open first error" << endl; return -1; } if (!src2.data) { cerr << "open second error" << endl; return -1; }
    //【2】做影象混合加權操作 if (src.rows == src2.rows && src.cols == src2.cols) { double alpha = 0.7; addWeighted(src, alpha, src2, 1 - alpha,0.0, dst); add(src, src2, dst3); multiply(src, src2, dst2); //【3】建立並顯示原圖視窗 namedWindow("src", WINDOW_NORMAL); namedWindow("src2", WINDOW_NORMAL); namedWindow("line-blend", WINDOW_NORMAL); namedWindow("multiply", WINDOW_NORMAL); namedWindow("add", WINDOW_NORMAL); imshow("src", src); imshow("src2", src2); imshow("line-blend", dst); imshow("multiply", dst2); imshow("add", dst3); waitKey(0); return 0; } else { cerr << "images is not same" << endl; return -1; } }

在這裡插入圖片描述
在這裡插入圖片描述

  • 不同尺寸大小

    #include"opencv2/opencv.hpp"
    #include<iostream>
    using namespace cv;
    using namespace std;
    int main() {
    
    	//【2】定義一個Mat型別並給其設定ROI區域
    	Mat src, src2, imageROI;
    	src = imread("D:\\2.jpg");
    	src2 = imread("D:\\test\\second.png");
    	if (!src.data) {
    		cerr << "open first error" << endl;
    		return -1;
    	}
    	if (!src2.data) {
    		cerr << "open second error" << endl;
    		return -1;
    	}
    	//方法一  
    	//imageROI = src(Rect(200, 250, src2.cols, src2.rows));
    	//方法二  
    	imageROI= src(Range(0,0+src2.rows),Range(0,0+src2.cols));  
    
    	//【3】將logo加到原圖上  
    	addWeighted(imageROI, 0.5, src2, 0.3, 0., imageROI);
    
    	//【4】顯示結果  
    	imshow("src", src);
    	imshow("src2", src2);
    	imshow("imageROI", imageROI);
    	waitKey(0);
    	return 0;
    }
    

不同通道數

單通道可以融合到多通道中

採用通道分離即呼叫函式split,混合後通道融合即呼叫函式merge。
分離宣告:CV_EXPORTS_W void split(InputArray m, OutputArrayOfArrays mv);
融合宣告:CV_EXPORTS_W void merge(InputArrayOfArrays mv, OutputArray dst);

#include"opencv2/opencv.hpp"
#include<iostream>
using namespace cv;
using namespace std;
int main() {
	Mat srcImage;
	Mat logoImage;
	vector<Mat> channels;
	Mat  imageBlueChannel;

	//=================【藍色通道部分】=================  
	//  描述:多通道混合-藍色分量部分  
	//============================================  

	// 【1】讀入圖片  
	logoImage = imread("D:/test/first.png", 0);
	srcImage = imread("D:/test/second.png");

	if (!logoImage.data) { printf("Oh,no,讀取logoImage錯誤~! \n"); return false; }
	if (!srcImage.data) { printf("Oh,no,讀取srcImage錯誤~! \n"); return false; }

	//【2】把一個3通道影象轉換成3個單通道影象  
	split(srcImage, channels);//分離色彩通道  

	//【3】將原圖的藍色通道引用返回給imageBlueChannel,注意是引用,相當於兩者等價,修改其中一個另一個跟著變  
	imageBlueChannel = channels.at(0);
	//【4】將原圖的藍色通道的(0,0)座標處右下方的一塊區域和logo圖進行加權操作,將得到的混合結果存到imageBlueChannel中  
	addWeighted(imageBlueChannel(Rect(0, 0, logoImage.cols, logoImage.rows)), 0.5,
		logoImage, 0.5, 0.0, imageBlueChannel(Rect(0, 0, logoImage.cols, logoImage.rows)));

	//【5】將三個單通道重新合併成一個三通道  
	merge(channels, srcImage);

	//【6】顯示效果圖  
	namedWindow(" <1>遊戲原畫+logo藍色通道");
	imshow(" <1>遊戲原畫+logo藍色通道", srcImage);

	
	waitKey(0);
	return 0;
}