opencv学习(八)之ROI区域和图像混合叠加

来源:互联网 发布:蒙内铁路 知乎 编辑:程序博客网 时间:2024/05/05 23:06

1.图像线性混合叠加

在进行图像处理时,opencv中提供了addWeighted()实现对两幅图像的叠加。这是一种线性混合操作,其公式如下:
这里写图片描述
通过改变a的值,可以实现两幅图像或视频进行混合时出现不同的效果。
其函数定义如下:

CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,                              double beta, double gamma, OutputArray dst, int dtype=-1);

详细参数说明如下:
src1: 第一幅输入图像
alpha: 线性混合时第一幅图像的权重
src2: 第二幅输入图像
beta: 第二幅输入图像的权重
dst: 图像线性混合后的目标图像
gamma: 添加到每一个线性叠加总和的gamma值
dtype: 目标图像深度,当两幅图像深度相同时可以将dtype置为-1,这样目标图像的深度将与输入图像相同

其中beta - (1.0 - alpha);

对于每个像素点其计算公式如下:
这里写图片描述

示例代码如下:

#include <iostream>#include <opencv2/core.hpp>#include <opencv2/highgui.hpp>using namespace std;using namespace cv;int main(){    Mat srcImage1 = imread("forest.jpg");    Mat srcImage2 = imread("rain.jpg");    Mat dstImage;    //检查文件是否加载成功    if(srcImage1.empty() || srcImage2.empty())    {        cout << "图像加载失败!" << endl << endl;        return -1;    }    else        cout << "图像加载成功!" << endl << endl;    double alpha = 0.5;    double beta;    double input;    cout << "Please Input alpha[0-1]: ";    cin >> input;    //判断输入的alpha是否符合要求    if(input >= 0.0 && input <= 1.0)    {        alpha = input;    }    namedWindow("线性混合", WINDOW_NORMAL);    beta = (1.0 - alpha);    addWeighted(srcImage1, alpha, srcImage2, beta, 0.0, dstImage);    imshow("线性混合", dstImage);    namedWindow("srcImage1",WINDOW_NORMAL);    imshow("srcImage1",srcImage1);    namedWindow("srcImage2",WINDOW_NORMAL);    imshow("srcImage2",srcImage2);    waitKey(0);    return 0;}

运行结果如下所示:

这里写图片描述

该运行结果输入值为0.5.

注意:两幅图像混合时必须要求两幅图像的尺寸和类型完全相同。

通过对图像设置ROI区域可以实现不同尺寸图像的混合。
在进行图像处理时,常常需要设置感兴趣区域(ROI, region of interest),可以在图像任意位置创建ROI区域,设置ROI区域后可以更有针对性的进行下一步处理。
定义ROI有两种方法(假定都从图像左上角(100,100)的位置划定ROI):
第一种是使用表示矩形区域的Rect。它指定矩形的左上角坐标和矩形的长宽来划定ROI区域。

ROIImage = srcImage(Rect(100,100,smallImage.cols,smallImage.rows));

第二种方法是使用Range()指定感兴趣区域的行或列的范围。Range()指定的区域是一个连续的存储序列。

ROIImage = srcImage(Range(100,smallImage.rows),Range(100,smallImage.cols));

示例代码如下:

#include <iostream>#include <opencv2/core.hpp>#include <opencv2/highgui.hpp>#include <opencv2/imgproc.hpp>using namespace std;using namespace cv;int main(){    Mat srcImage = imread("space.jpg");    Mat addImage = imread("astronautB.jpg");    //判断文件是否加载成功    if(srcImage.data && addImage.data)        cout << "图像加载成功!" << endl << endl;    else    {        cout << "图像加载失败!" << endl << endl;        return -1;    }    imshow("srcImage",srcImage);    imshow("astronaut",addImage);    //设置srcImage感兴趣区域    //第一种方式,使用Rect()函数设置ROI    Mat imageROI = srcImage(Rect(50,50,addImage.cols,addImage.rows));    addWeighted(imageROI,0.7,addImage,0.3,0,imageROI);    imshow("混合后图像",srcImage);    waitKey(0);    return 0;}

其运行结果如下所示:
这里写图片描述

还可以利用copyTo()通过图像掩模板直接将图像复制到ROI区域。但是这种方法要求maskImage必须是灰度图。示例代码如下:

#include <iostream>#include <opencv2/core.hpp>#include <opencv2/highgui.hpp>using namespace std;using namespace cv;int main(){    Mat srcImage = imread("space.jpg");    Mat addImage = imread("astronautB.jpg");    Mat maskImage = imread("astronautB.jpg",IMREAD_GRAYSCALE);  //加载其灰度图    //判断文件是否加载成功    if(srcImage.data && addImage.data)        cout << "图像加载成功!" << endl << endl;    else    {        cout << "图像加载失败!" << endl << endl;        return -1;    }    //以第二种方式Range()函数设置其ROI区域    Mat imageROI = srcImage(Range(50,50+maskImage.rows), Range(50,50+maskImage.cols));    addImage.copyTo(imageROI,maskImage);    imshow("混合后图像",srcImage);    waitKey(0);    return 0;}

运行结果如下:
这里写图片描述

0 0
原创粉丝点击