本节主要介绍
1、定义感兴趣区域ROI
2、addWeighted函数进行图像线性混合。
3、RGB三通道分别显示,split函数
4、合并成一个多通道的数组,merge函数
1、ROI区域定义的两种方法
cv::Rect表示一个矩形区域。指定矩形的左上角坐标(构造函数的前两个参数)和矩形的长宽(构造函数的后两个参数)就可以定义一个矩形区域。
另一种定义ROI的方式是指定感兴趣行或列的范围(Range)
Mat imageROI;
//方法一
imageROI=image(Rect(500,250,logo.cols,logo.rows));
//方法二
imageROI=srcImage3(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));
#include
#include
using namespace cv;
using namespace std;
int main()
{
Mat srcImage = imread("dota.png");
Mat logoImage = imread("logo.png");
//ROI区域
Mat imageROI = srcImage(Rect(200, 250, logoImage.cols, logoImage.rows));
//掩摸为单通道即可
Mat mask = imread("logo.png",0);
//将掩膜拷贝到ROI
logoImage.copyTo(imageROI, mask);
imshow("【利用ROI实现图像叠加示例窗口】", srcImage);
waitKey();
return 0;
}
2、addWeighted函数
dst = src1[I]*alpha+ src2[I]*beta + gamma;
其中,src1和src2有相同的尺寸和通道数。
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);
double alphaValue = 0.5;
double betaValue = (1.0 - alphaValue);
Mat srcImage2, srcImage3, dstImage;
//【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )
srcImage2 = imread("dota.png");
srcImage3 = imread("logo.png");
//【2】进行图像混合加权操作
addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);
//【3】创建并显示原图窗口
imshow("<3>线性混合示例窗口【效果图】 by浅墨", dstImage);
3、split函数
将一个多通道数组分离成几个单通道数组。有两种形式。
C++: void split(const Mat& src, Mat*mvbegin);
C++: void split(InputArray m,OutputArrayOfArrays mv);
char d[] = {1,2,3,4,5,6,7,8,9,10,11,12};
Mat m(2, 2, CV_8UC3, d);
Mat imageBlueChannel;
Mat imageGreenChannel;
Mat imageRedChannel;
//或者vector channels;
Mat channels[3];
//第一个参数是Mat数组,第二个参数是指针数组
split(m, channels);
imageBlueChannel = channels.at(0);
imageGreenChannel = channels.at(1);
imageRedChannel = channels.at(2);
/*
channels[0] =
[ 1, 4;
7, 10]
channels[1] =
[ 2, 5;
8, 11]
channels[2] =
[ 3, 6;
9, 12]
*/
4、merge函数
创建出一个由多个单通道阵列组成的多通道阵列
C++: void merge(const Mat* mv, size_tcount, OutputArray dst)
C++: void merge(InputArrayOfArrays mv,OutputArray dst)
Mat m1 = (Mat_(2,2) << 1,4,7,10);
Mat m2 = (Mat_(2,2) << 2,5,8,11);
Mat m3 = (Mat_(2,2) << 3,6,9,12);
Mat channels[3] = {m1, m2, m3};
Mat m;
merge(channels, 3, m);
/*
m =
[ 1, 2, 3, 4, 5, 6;
7, 8, 9, 10, 11, 12]
m.channels() = 3
*/
综合实例
先用split()分离通道,然后在单通道上使用addWeighted()叠加,最后再使用merge()将各通道合并。
#include
#include
#include
using namespace cv;
using namespace std;
bool multichannelblending();
int main()
{
if (multichannelblending())
{
cout << endl << "得出了你需要混合的图像了";
}
waitKey();
return 0;
}
bool multichannelblending()
{
//声明变量
Mat image;
Mat logo;
Mat imagebluechannel;
vector channels;//!!!!通道
//读入图像
image = imread("dota.png");
logo = imread("logo.png", 0);
//3通道图像转换成3个单通道图像split
split(image, channels);
//蓝色通道
imagebluechannel = channels.at(0);
//addweight
addWeighted(imagebluechannel(Rect(500, 250, logo.cols, logo.rows)), 1.0,
logo, 0.5, 0., imagebluechannel(Rect(500, 250, logo.cols, logo.rows)));
//合并成一个通道merge
merge(channels, image);
//显示
imshow("<1>游戏原画+logo蓝色通道 by浅墨", image);
return true;
}