在之前学的的设定感兴趣区域ROI和使用addWeighted()函数进行图像线性混合的基础上,可以将两者结合起来,先指定ROI区域,再用addWeighted()函数对指定区域的图像进行混合操作,将其封装在一个ROI_LinearBlending()函数中,方便学习理解。下面是具体栗子:
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
//-----------------------------【全局函数声明部分】------------------------------
bool ROI_AddImage();
bool LinearBlending();
bool ROI_LinearBlending();
int main() {
system("color 5A");
if (ROI_AddImage() && LinearBlending() && ROI_LinearBlending())
cout << "运行成功!得出需要的图像了!:)" << endl;
waitKey(0);
return 0;
}
//----------------------【ROI_AddImage()函数】--------------------------
bool ROI_AddImage() {//利用感兴趣区域ROI实现图像叠加
//读入图像
Mat srcImage1 = imread("dota_pa.jpg");
Mat logoImage = imread("dota_logo.jpg");
if (!srcImage1.data) {
cout << "读取srcImage1失败!" << endl;
return false;
}
if (!logoImage.data) {
cout << "读取logoImage失败!" << endl;
return false;
}
//定义一个Mat类型并给其设定ROI区域
Mat imageROI = srcImage1(Rect(560, 240, logoImage.cols, logoImage.rows));
//加载掩膜(必须是灰度图)
Mat mask = imread("logoImage.jpg", 0);
//将掩膜复制到ROI区域
logoImage.copyTo(imageROI, mask);
//显示效果
namedWindow("<1>利用ROI实现图像叠加示例窗口");
imshow("<1>利用ROI实现图像叠加示例窗口", srcImage1);
return true;
}
//------------------------【LinearBlending()函数】----------------------------
bool LinearBlending() {//利用cv::addWeighted()函数实现图像线性混合
//定义一些局部变量
double alpha = 0.5;
double beta;
Mat srcImage2, srcImage3, dstImage;
//读取图像
srcImage2 = imread("mogu.jpg");
srcImage3 = imread("rain.jpg");
if (!srcImage2.data) {
cout << "读取srcImage2错误!" << endl;
return false;
}
if (!srcImage3.data) {
cout << "读取srcImage3错误!" << endl;
return false;
}
//进行图像混合加权操作
beta = (1.0 - alpha);
double gamma = 0;
addWeighted(srcImage2, alpha, srcImage3, beta, gamma, dstImage);
//创建并显示原图窗口
namedWindow("<2>线性混合示例窗口【原图】");
imshow("<2>线性混合示例窗口【原图】", srcImage2);
namedWindow("<3>线性混合示例窗口【效果图】");
imshow("<3>线性混合示例窗口【效果图】",dstImage);
return true;
}
//----------------------【ROI_LinearBlending()函数】---------------------------------
bool ROI_LinearBlending() {//指定区域线性图像混合
//读取图像
Mat srcImage4 = imread("dota_pa.jpg", 1);//载入三通道图像
Mat logoImage = imread("dota_logo.jpg");//默认flags=1,载入三通道图像
if (!srcImage4.data) {
cout << "读入srcImage4失败!" << endl;
return false;
}
if (!logoImage.data) {
cout << "读入logoImage失败!" << endl;
return false;
}
//定义一个Mat类型并给其设定ROI区域
Mat imageROI;
//imageROI = srcImage4(Rect(560, 240, logoImage.cols, logoImage.rows));
imageROI = srcImage4(Range(240, 240 + logoImage.rows), Range(560, 560 + logoImage.cols));//方法二
//注意:Range()方法是先给定上下范围,再给定左右范围!!
//定义一些局部变量
double alpha = 0.5, beta = 0.3, gamma = 0;
//将logo加到原图上
//将logo线性叠加到ROI区域并赋值给imageROI,而imageROI属于srcImage4,所以srcImage4为最终效果图
addWeighted(imageROI, alpha, logoImage, beta, gamma, imageROI);//注意参数一三六必须尺寸相同&通道数相同
//显示结果
namedWindow("<4>区域线性图像混合示例窗口");
imshow("<4>区域线性图像混合示例窗口", srcImage4);
return true;
}
运行结果: