图像混合是把每一个像素给混合起来;图像叠加就是简单的给一幅图像加上另一幅图像。效果分别如下所示:


在OpenCV中 线性混合是指将两幅图像的像素进行线性混合。 理论公式f(x) = αg(x) +(1 - α)h(x);其中α在[0,1]中取值。
OpenCV提供了一个叫做addWeighted函数的函数来实现图像混合和图像叠加操作。
//addWeighted函数原型
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);
//gamma因子是加到每一个混合以后的像素上的。即:
//f(x) = α * src1[i][j] + α src2[i][j] + gamma因此在OpenCV中使用addWeighted函数的方式如下:
Mat src1 = imread("C:/Users/zhou_/Desktop/1.png");
Mat src2 = imread("C:/Users/zhou_/Desktop/2.png");
if (src1.empty())
{
perror("load failed:");
exit(-1);
}
else
{
namedWindow("src1");
imshow("src1", src1);
}
if (src2.empty())
{
perror("load failed");
exit(-1);
}
else
{
namedWindow("src2");
imshow("src2", src2);
}
double α = 0.5;
//图像的尺寸和类型应当一致。
if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type())
{
Mat dst;
addWeighted(src1, α, src2, 1 - α, 0.0, dst);
namedWindow("dst");
imshow("dst", dst);
}addWeighted函数的参数从上面可以看处理,很简单。
参数1:图像1;
参数2:线性混合参数α;
参数3:图像2;
参数4:线性混合参数1-α;
参数5:权重gamma;
参数6:目标图像。
下面我们对图像进行部分区域混合,这样的操作需要指定区域范围,如下所示:
src2ROI = src2(Rect(100, 100, src1.cols,src1.rows));Rect用来指定从坐标(100,100)开始,长是src1.cols,宽是src1.rows这个范围内进行图像混合。
Mat src1 = imread("C:/Users/zhou_/Desktop/1.png");
Mat src2 = imread("C:/Users/zhou_/Desktop/壁纸1.jpg");
Mat src2ROI;
double α = 0.5;
src2ROI = src2(Rect(100, 100, src1.cols,src1.rows));
addWeighted(src2ROI, α, src1, 1 - α, 0.0, src2ROI);
namedWindow("图像混合");
imshow("图像混合", src2);需要注意addWeighted函数的参数,混合的目标图像是src2ROI,而不是src2。这样才能改变原图像src2。
图像叠加和图像混合不同的地方在于图像叠加需要使用灰度图像来进行掩码操作。这样才能得到叠加的图像。
Mat src1 = imread("C:/Users/zhou_/Desktop/1.png");
Mat src2 = imread("C:/Users/zhou_/Desktop/壁纸1.jpg");
Mat src2ROI;
double α = 0.5;
src2ROI = src2(Rect(100, 100, src1.cols,src1.rows));
//读入图像1的灰度图像,并进行掩码
Mat mask = imread("C:/Users/zhou_/Desktop/1.png", IMREAD_GRAYSCALE);
src1.copyTo(src2ROI, mask);
addWeighted(src2ROI, α, src1, 1 - α, 0.0, src2ROI);
namedWindow("图像叠加");
imshow("图像叠加", src2);这样就完成了图像的叠加。