0


OpenCV实战(3)——图像感兴趣区域

OpenCV实战(3)——图像感兴趣区域

0. 前言

在实际应用场景下,图像处理函数有时只需要应用于图像的部分区域。

OpenCV

中使用了一种优雅而简单的机制来定义图像中的子区域并将可以将其视为常规图像进行操作。本节中,我们将学习如何定义图像内的感兴趣区域 (

region of interest

,

ROI

)。

1. 感兴趣区域

为了说明如何定义感兴趣区域 (

region of interest

,

ROI

),我们将一个尺寸较小图像复制到一个更大的图像上。例如,我们要将以下

OpenCV logo

插入到测试图像中:

请添加图片描述
为了完成该目标,需要定义可以应用复制操作的

ROI

ROI

的位置将决定

logo

在图像中的插入位置。

1.1 ROI 实例

首先,读取

logo

图像并定义

ROI

。我们可以使用

Rect

来定义

ROI

// 读取 logo
cv::Mat logo=  cv::imread("logo.png"); 
cv::Rect myRoi = cv::Rect(image.cols-log.cols,image.rows-logo.rows
                            logo.cols, logo.rows)

定义了

ROI

之后,我们可以创建一个新的

cv::Mat

实例

imageROI

,将

ROI

应用到这个新的

cv::Mat

实例上,可以其作为常规的

cv::Mat

实例进行操作。此时,

ROI

是一个

cv::Mat

对象,它指向与其父图像相同的数据缓冲区,并具有指定

ROI

坐标的标头。插入

logo

的方式如下:

// 定义图像感兴趣区域位于图像右下角
cv::Mat imageROI(image, myRoi);// 插入 logo
logo.copyTo(imageROI)

在以上代码中,

image

是目标图像,

logo

logo

图像,编译并执行代码可以得到以下结果:

ROI

1.2 定义 ROI

定义

ROI

的一种方法是如上一小节所示使用

cv::Rect

实例,它通过指定左上角的位置(构造函数的前两个参数)和矩形的大小(即宽度和高度,使用后两个参数指定)来描述一个矩形区域。在示例代码中,我们使用图像的大小和

logo

大小令

logo

覆盖图像右下角的位置。需要注意的是,

ROI

应该始终完全处于父图像内。

ROI

也可以使用行和列范围来描述,范围是从开始索引到结束索引(不包括两者)的连续序列,在

OpenCV

中使用

cv::Range

结构表示范围。因此,可以使用两个范围定义

ROI

,上一节示例中的

ROI

也可以等效地定义如下:

// 也可以使用 cv::Range 定义感兴趣区域
imageROI=image(cv::Range(image.rows-logo.rows,image.rows), 
                cv::Range(image.cols-logo.cols,image.cols));

在以上代码中,

cv ::Mat

operator()

函数会返回另一个

cv::Mat

实例,然后可以在后续调用中使用该实例。

ROI

的任何变换都会影响相应区域的原始图像,因为图像和

ROI

共享相同的图像数据。由于

ROI

的定义不需要数据的复制,因此无论

ROI

的大小如何,它都会在恒定的时间内执行。
如果要定义由图像的某些行组成的

ROI

,可以使用以下代码:

cv::Mat imageROI = image.rowRange(start, end);

同样,对于由某些图像列组成的

ROI

,可以使用以下代码:

cv::Mat imageROI = image.colRange(start, end);
OpenCV

方法和函数包括许多可选参数,当我们第一次使用某个函数时,应该花时间查看文档以了解有关此函数提供的可能参数的相关信息。例如,关于

ROI

的一种非常常见的可选参数是可以定义图像蒙版。

2. 使用图像掩码

有些

OpenCV

操作允许我们定义一个掩码,使用掩码可以限制给定函数或方法在图像中的应用区域(默认情况下,函数或方法会对所有图像像素进行操作)。掩码是一个

8

位图像,在希望应用操作的位置为非零值;在对应于掩码零值的像素位置,图像不受操作影响。例如,可以使用掩码调用

copyTo

方法,使用掩码仅复制显示

logo

的彩色部分:

// 定义图像的感兴趣区域
imageROI=image(cv::Rect(image.cols-logo.cols,image.rows-logo.rows,
                            logo.cols,logo.rows));// 也可以使用 cv::Range 定义感兴趣区域// imageROI= image(cv::Range(image.rows-logo.rows,image.rows), //                 cv::Range(image.cols-logo.cols,image.cols));// 将 logo 图像作为掩码
cv::Mat mask(logo);// 通过仅在非零掩码的位置复制插入
logo.copyTo(imageROI, mask);

执行以上代码可以得到下图:

带有掩码的 ROI

logo

的背景是黑色的(值为

0

),因此,可以很容易将其用作蒙版。当然,我们也可以在应用程序中自定义掩码;大多数基于

OpenCV

像素的操作都允许我们使用掩码进行操作。

3. 完整代码示例

完整代码如下:

#include<iostream>#include<opencv2/core.hpp>#include<opencv2/highgui.hpp>intmain(){// 定义新窗口
    cv::namedWindow("Image");// 读取图像
    cv::Mat image=  cv::imread("1.png");// 读取 logo
    cv::Mat logo=  cv::imread("logo.png");// 定义图像的感兴趣区域
    cv::Mat imageROI(image, 
                    cv::Rect(image.cols-logo.cols,// ROI 坐标
                            image.rows-logo.rows,
                            logo.cols,logo.rows));// ROI 尺寸// 插入 logo
    logo.copyTo(imageROI);
    cv::imshow("Image", image);// 展示图像
    cv::waitKey(0);// 重新读取原始图像
    image=  cv::imread("1.png");// 定义图像的感兴趣区域
    imageROI=image(cv::Rect(image.cols-logo.cols,image.rows-logo.rows,
                                logo.cols,logo.rows));// 也可以使用 cv::Range 定义感兴趣区域// imageROI= image(cv::Range(image.rows-logo.rows,image.rows), //                 cv::Range(image.cols-logo.cols,image.cols));// 将 logo 图像作为掩码
    cv::Mat mask(logo);// 通过仅在非零掩码的位置复制插入
    logo.copyTo(imageROI, mask);
    cv::imshow("Image", image);// 展示图像
    cv::waitKey(0);return0;}

小结

在图像处理领域,感兴趣区域 (

region of interest

,

ROI

) 可以简单理解为从图像中选择的一个图像区域,这个区域是图像分析算法所关注的重点。使用

ROI

限定需要进行进一步处理的目标区域,可以减少图像处理时间,并增加处理精度。本节介绍了两种定义

ROI

的方法,并介绍了掩码在图像处理中的作用及用法。

系列链接

OpenCV实战(1)——OpenCV与图像处理基础
OpenCV实战(2)——OpenCV核心数据结构

标签: 图像处理 opencv

本文转载自: https://blog.csdn.net/LOVEmy134611/article/details/126702587
版权归原作者 盼小辉丶 所有, 如有侵权,请联系我们删除。

“OpenCV实战(3)——图像感兴趣区域”的评论:

还没有评论