OpenCV笔记之感兴趣区域ROI

By AverageJoeWang
 标签:

在图像处理领域,有一个非常重要的名词ROI。

那么什么是ROI呢?

它的英文全称是Region Of Interest,对应的中文解释就是感兴趣区域。

感兴趣区域,就是我们从图像中选择一个图像区域,这个区域就是图像分析所关注的焦点。我们圈定这个区域,那么我们要处理的图像就从大图像变为一个小图像区域了,这样以便进行进一步处理,可以大大减小处理时间。

定义ROI方法

  • 使用表示矩阵区域的Rect。

它指定矩阵的左上角坐标(构造函数的前两个参数)和矩阵的长宽(构造函数的后两个参数)以定义一个矩阵区域。

// 定义一个Mat类型并给定其设定的区域
Mat imageROI;
// 方法一
imageROI = image(Rect(100, 200, 100, 300));//Rect四个形参分别是:x坐标,y坐标,长,高;注意(x,y)指的是矩形的左上角点
  • 指定感兴趣行或列的范围(Range)。

Range是指从起索引到终止索引(不包括终止索引)的一连串连续序列。cRange可以用来定义Range。如果使用Range来定义ROI,那么前例中定义ROI的代码可以重写为:

imageROI = image( Range(250, 250+logoImage.rows),                   Range(200, 200+logoImage.cols));//Range两个形参分别是:起始行或列,起始行或列+偏移量

标注ROI区域

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage = imread("test.jpg");
    if (!srcImage.data)
    {
        cout << "读取原始图失败!" << endl;
        return -1;
    }
    rectangle(srcImage, Rect(0, 0, 100, 100), Scalar(255, 0, 0),2); //将感兴趣区域框出来,这里是用2像素的蓝色线标注出来
    imshow("ROI", srcImage);
    waitKey();
    return 0;
}
  • 结果如图所示

ROI

蓝色区域就是我们标出来的ROI

提取ROI区域

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage = imread("test.jpg");
    if (!srcImage.data)
    {
        cout << "读取原始图失败!" << endl;
        return -1;
    }
    Mat image(srcImage.rows, srcImage.cols, CV_8UC3);//声明一个Mat实例,长宽高和srcImag一样
    srcImage(Rect(300, 300, 200, 200)).copyTo(image);//copyTo()方法是深拷贝方法
    imshow("ROI", srcImage);
    imshow("ima", image);
    waitKey();
    return 0;
}

ROI区域提取

ROI区域在上面我们进行标注和提取,那这里我们利用ROI进行一个图像logo添加

  • 思路
    • 先定义好ROI区域(logo区域)
    • 使用addWeigthed函数进行线性叠加。

addWeighted线性混合操作是一种典型的二元(两个输入)的像素操作,它的理论公式如下:

$ f(x) = (1-\alpha)f _\alpha(x) + \alpha f_3(x) $

我们通过在范围0到1之间改变$\alpha$值,来对两幅图像(如上述公式中的$f_\alpha$和$f_3$)进行画面迭代效果。OpenCV的相关操作如下

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage = imread("/Users/oliverwang/Pictures/opencv/test.jpg");
    if (!srcImage.data)
    {
        cout << "读取原始图失败!" << endl;
        return -1;
    }
    namedWindow("srcImage", WINDOW_NORMAL);//可以自由拉动宽高
    imshow("srcImage", srcImage);

    Mat logo = imread("/Users/oliverwang/Pictures/opencv/logo.jpeg");
    if (!logo.data)
    {
        cout << "读取原始图失败!" << endl;
        return -1;
    }

    Mat ROI = srcImage(Rect(30, 30, logo.cols, logo.rows));//从原图中抠出矩形区域,Rect第一二参数表示矩形左上角定点的坐标,用于定位,后两个参数表示矩形的宽和高
    imshow("ROI", ROI);

    addWeighted(ROI, 0.2, logo, 0.8, 0., ROI);//dst = src1[I]*alpha+ src2[I]*beta + gamma;第一第四个参数就是各自权重,第5个参数就是公式中的偏执因子gamma。
    namedWindow("原图加logo", WINDOW_NORMAL);
    imshow("logo", srcImage);
    waitKey();
    return 0;
}

添加logo前后