感兴趣区域(Region of Interest, ROI)

roi
感兴趣区域,Region of Interest,简称ROI是指从原图中提取出的一个副矩阵,相当于从图像中抠出一块矩形区域。 用法: cv::Mat img2 = img1(cv::Rect(x,y,width,height)) 以上用法为从img1提取一个以(x,y)左上角,“width”宽度和“height”高度大小的矩阵。

感兴趣区域和原图像是一体

注意:ROI与原图像共用一块内存数据,改变ROI,则原图对应区域也会改变。

小实验

从之前的文章,这是个简单的读取并显示图像的代码: #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { //读取照片 Mat image = imread("OpenCV_Logo.png"); //检测失误 if (image.empty()) { cout << "Could not open or find the image" << endl; cin.get(); //等待键盘输入 return -1; } String windowName = "OpenCV Test"; //窗口名称 namedWindow(windowName); //创建新窗口 imshow(windowName, image); //使用新窗口显示照片 waitKey(0); //等待键盘输入 destroyWindow(windowName); //关闭所有窗口 return 0; } 记得把"OpenCV_Logo.png"改为你的图像路径。

参考上面的代码,我们编出一个最简化的实验代码: #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { //读取照片 Mat image = imread("OpenCV_Logo.png"); //感兴趣区域 Mat roi = image(Rect(300,100,300,300)); imshow("img", image); //显示原图 imshow("roi", roi); //显示感兴趣区域 waitKey(0); //等待键盘输入 destroyWindow(windowName); //关闭所有窗口 return 0; } 编译运行后,我们可以看到两个窗口,个别是我们的原图和提取的roi。
orig img
roi
注意,定义ROI范围前必须先确认源图像尺寸,确保没超边。代码中没进行这方面的错误处理。
上面我们实现了感兴趣区域的提取,下面我们要证明它与原图的关系。

在imshow之前,我们对roi进行绘图: ... Mat roi = image(Rect(300,100,300,300)); //在roi上绘画 rectangle(roi, Point(100,100), Point(200,200), Scalar(255,0,0), 2); imshow("img", image); //显示原图 ... 这段添加的代码是在roi上画一个左上角为(100,100),右下角(200,200),边颜色为(255,0,0)蓝,变厚为2的四边形。

编译运行后可获得以下结果:
orig img
roi
可发现,我们在roi上绘画的四边形,在原图上也有,而且我们并没有在原图上绘画任何东西。这证明了感兴趣区域和原图像是公用同个内存空间的。

那如何是ROI独立?

与其使用以下代码: cv::Mat img2 = img1(cv::Rect(x,y,width,height)) 我们多调用一个Mat::copyTo()函数: cv::Mat img2; img1(cv::Rect(x,y,width,height)).copyTo(img2); 即可。