有时需要让一个处理函数只在图像的某个部分起作用。OpenCV 内嵌了一个精致又简洁的机制,可以定义图像的子区域,并把这个子区域当作普通图像进行操作。
假设我们要把一个小图像复制到一个大图像上。例如要把下面的标志插入到图像中。为了实现这个功能,可以定义一个感兴趣区域(Region Of Interest,ROI),在此处进行复制操作,这个ROI 的位置将决定标志的插入位置。
定义ROI区域有两种方法:第一种是使用表示矩形区域的Rect。它指定矩形的左上角坐标(构造函数的前两个参数)和矩形的长宽(构造函数的后两个参数)以定义一个矩形区域。
cv::Mat imageROI = srcImage(
cv::Rect(srcImage.cols - logo.cols,
srcImage.rows - logo.rows,logo.cols, logo.rows));
另一种定义 ROI的方式是指定感兴趣行或列的范围(Range)。Range是指从起始索引到终止索引(不包括终止索引)的一连段连续序列。如果使用Range来定义ROI,那么前例中定义ROI的代码可以重写为:
cv::Mat imageROI = srcImage(
cv::Range(srcImage.rows - logo.rows, srcImage.rows),
cv::Range(srcImage.cols - logo.cols, srcImage.cols));
运行以下程序,得到图1结果。
#include <QtCore/QCoreApplication>
#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
cv::Mat srcImage; // 创建一个空图像
cv::Mat logo = cv::imread("E:/image/log.png");
srcImage = cv::imread("E:/image/P1.jpg"); // 读取输入图像
// 在图像右下角定义一个 ROI
cv::Mat imageROI = srcImage(
cv::Rect(srcImage.cols - logo.cols,
srcImage.rows - logo.rows,logo.cols, logo.rows));
cv::Mat mask(logo);
logo.copyTo(imageROI, mask);
cv::namedWindow("Image"); // 定义窗口
cv::imshow("Image", srcImage); // 显示图像
QCoreApplication a(argc, argv);
return a.exec();
}