线性混合操作

在这里插入图片描述

利用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;
}

猜你喜欢

转载自blog.csdn.net/qq_41498261/article/details/83932193