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