图像合成本质上是alpha blending,也称为alpha融合,数学表达如下
y = alpha * x1 + (1 - alpha) * x2
opencv中提供了融合函数,可进行单通道或多通道整合(本质上是各个通道分别整合),如下为官方文档描述。
对于c++版本,有7个参数,分别是:
对于更便捷的python来说,方法为cv2.addWeighted,参数与c++版本基本一样,后面直接看代码。
直接show代码:
#include "opencv2/highgui/highgui.hpp"
#include
#include "opencv2/opencv.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
Mat imsrc1 = imread(argv[1]);
Mat imsrc2 = imread(argv[2]);
Mat imsrc2_scaler; //将imsrc2缩放到imsrc1的尺寸
Mat imdst; //合成的目标图像
double alpha = 0.3;
double gamma = 0;
if(imsrc1.size() != imsrc2.size()){
printf("resize start!\n");
//resize(imsrc2, imsrc2_scaler, Size(imsrc1.cols, imsrc1.rows), 0, 0, INTER_LINEAR);
resize(imsrc2, imsrc2_scaler, imsrc1.size(), 0, 0, INTER_LINEAR); //方法2
addWeighted(imsrc1, alpha, imsrc2_scaler, 1 - alpha, gamma, imdst);
}
else{
addWeighted(imsrc1, alpha, imsrc2, 1 - alpha, gamma, imdst);
}
imwrite("imdst.jpg", imdst);
return 0;
}
保存为image_merge.cpp
编译:g++ pkg-config --cflags --libs opencv
image_merge.cpp -o test
运行:./test im1.jpg im2.jpg
原始图片:
结果如下:
python实现如下,简洁、便捷!
import cv2
imsrc1 = cv2.imread("../../c-base/opencv-imageprocess/im1.jpg")
imsrc2 = cv2.imread("../../c-base/opencv-imageprocess/im2.jpg")
alpha = 0.7
imdst = cv2.addWeighted(imsrc1, alpha, imsrc2, 1 - alpha, 0)
#cv2.namedWindow("merge")
#cv2.imshow("merge", imdst)
cv2.imwrite("imDstMerge.jpg", imdst)
split可将多通道拆分开,然后各个通道使用Rect做区域融合
#include "opencv2/highgui/highgui.hpp"
#include
#include "opencv2/opencv.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
//合成图像的中间区域
int main(int argc, char **argv)
{
Mat imsrc1 = imread(argv[1]);
Mat imsrc2 = imread(argv[2]);
Mat imsrc2_scaler; //将imsrc2缩放到imsrc1的尺寸
Mat imdst; //合成的目标图像
double alpha = 0.3;
double gamma = 0;
vector channels_src1;
split(imsrc1, channels_src1);
Mat imageRedChannels = channels_src1.at(0);
Mat imageGreenChannels = channels_src1.at(1);
Mat imageBlueChannels = channels_src1.at(2);
resize(imsrc2, imsrc2_scaler, Size(imsrc1.cols / 2, imsrc1.rows / 2), 0, 0, INTER_LINEAR);
vector channels_src2;
split(imsrc2_scaler, channels_src2);
Mat imageRedChannels_src2 = channels_src2.at(0);
Mat imageGreenChannels_src2 = channels_src2.at(1);
Mat imageBlueChannels_src2 = channels_src2.at(2);
addWeighted(imageRedChannels(Rect(imsrc1.cols / 4, imsrc1.rows / 4, imsrc2_scaler.cols, imsrc2_scaler.rows)),
0.3, imageRedChannels_src2, 0.7, 0, imageRedChannels(Rect(imsrc1.cols / 4, imsrc1.rows / 4, imsrc2_scaler.cols, imsrc2_scaler.rows)));
addWeighted(imageGreenChannels(Rect(imsrc1.cols / 4, imsrc1.rows / 4, imsrc2_scaler.cols, imsrc2_scaler.rows)),
0.3, imageGreenChannels_src2, 0.7, 0, imageGreenChannels(Rect(imsrc1.cols / 4, imsrc1.rows / 4, imsrc2_scaler.cols, imsrc2_scaler.rows)));
addWeighted(imageBlueChannels(Rect(imsrc1.cols / 4, imsrc1.rows / 4, imsrc2_scaler.cols, imsrc2_scaler.rows)),
0.3, imageBlueChannels_src2, 0.7, 0, imageBlueChannels(Rect(imsrc1.cols / 4, imsrc1.rows / 4, imsrc2_scaler.cols, imsrc2_scaler.rows)));
merge(channels_src1, imdst);
imwrite("imdst.jpg", imdst);
return 0;
}
参考:
[1] https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html