由于OpenCV2是C++编写,基于运算符重载,实现了许多我们算数上的操作符重载,其中今天我们着重使用cv::add更准确的说是cv::addWeighted。当然无论是用那种运算都使用cv::saturate_cast来保证输出图像的像素值在合理的范围内。
本篇我们想合并两个不同大小的图像。例如把一个小的logo加到我们的测试图像上。我们不能直接使用add函数,我们要先定义感兴趣区域(ROI ),只要感兴趣的区域和logo图像大小相同,add就能工作,ROI的位置决定了logo图像的插入位置。
首先介绍两幅到校一样的图片的叠加:
这个例子是把image2的灰度值图像加到image1图像的蓝色通道上去
image1
=
cv::imread(
"boldt.jpg"
);
image2
=
cv::imread(
"rain.jpg"
, 0);
// create vector of 3 images
std::
vector
<cv::
Mat
> planes;
// split 1 3-channel image into 3 1-channel images
cv::split(image1, planes);
// add to blue channel
planes
[
0
]
+=
image2;
// merge the 3 1-channel images into 1 3-channel image
cv::merge(planes, result);
这个例子呢,两幅图不一样大,所以先定义ROI
// read images
cv::
Mat
image = cv::imread(
"boldt.jpg"
);
cv::
Mat
logo = cv::imread(
"logo.bmp"
);
// define image ROI
cv::
Mat
imageROI;
imageROI
=
image
(
cv::
Rect
(385, 270, logo.cols, logo.rows)
)
;
// add logo to image
cv::addWeighted(imageROI, 1.0, logo, 0.3, 0., imageROI);
// show result
cv::namedWindow(
"with logo"
);
cv::imshow(
"with logo"
, image);
通过图像的掩模操作来拷贝ROI
// read images
image
=
cv::imread(
"boldt.jpg"
);
logo
=
cv::imread(
"logo.bmp"
);
// define ROI
imageROI
=
image
(
cv::
Rect
(385, 270, logo.cols, logo.rows)
)
;
// load the mask (must be gray-level)
cv::
Mat
mask = cv::imread(
"logo.bmp"
, 0);
// copy to ROI with mask
logo.copyTo(imageROI, mask);
// show result
cv::namedWindow(
"with logo 2"
);
cv::imshow(
"with logo 2"
, image);
直接在imag1的绿色通道上定义感兴趣区,并操作
// read images
logo
=
cv::imread(
"logo.bmp"
, 0);
image1
=
cv::imread(
"boldt.jpg"
);
// split 3-channel image into 3 1-channel images
std::
vector
<cv::
Mat
> channels;
cv::split(image1, channels);
imageROI
=
channels.at(1);
cv::addWeighted(imageROI
(
cv::
Rect
(385, 270, logo.cols, logo.rows)
)
, 1.0,
logo, 0.5, 0., imageROI
(
cv::
Rect
(385, 270, logo.cols, logo.rows)
)
);
cv::merge(channels, image1);
cv::namedWindow(
"with logo 3"
);
cv::imshow(
"with logo 3"
, image1);