昊虹AI笔记网

 找回密码
 立即注册
搜索
查看: 1976|回复: 0
收起左侧

OpenCV-C++选择、提取感兴趣区域(ROI区域)【附用鼠标选取ROI区域的代码】

[复制链接]

239

主题

241

帖子

928

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
928
昊虹君 发表于 2022-11-11 14:58 | 显示全部楼层 |阅读模式
OpenCV-C++选择、提取感兴趣区域(ROI区域)【附用鼠标选取ROI区域的代码】

在图像处理中,我们常常要对某个区域进行选择、提取,然后对这个区域进行单独分析、处理、显示。
这样的区域我们称为叫ROI区域,英文全称为Region of interest,中文名为“感兴趣区域”。

在OpenCV中主要是使用类Rect来实现对ROI区域的选择。

可以用类Rect的构造函数Rect()返回一个Rect对象,该对象表示一个矩形区域。

构造函数Rect()的带参数示例代码如下:
  1. cv::Rect(xRoi, yRoi, widthRoi,heightRoi)
复制代码

xRoi表示矩形区域左上顶点的x坐标;
yRoi表示矩形区域左上顶点的y坐标;
widthRoi表示矩形区域的宽度;
heightRoi表示表示矩形区域的高度。

完整的示例代码如下:
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

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

using namespace std;
using namespace cv;


int main()
{
	// 源图像载入及判断
	cv::Mat srcImage = cv::imread("F:/material/images/P0003-view-2.jpg");
	if (!srcImage.data)
		return 1;

	cv::imshow("srcImage", srcImage);
	
	// 利用Rect选择矩形区域(左上角的坐标为(0,200),宽度为200,高度为100)
	int xRoi = 0;
	int yRoi = 200;
	int widthRoi = 200;
	int heightRoi = 100;

	cv:Mat ROI_img(srcImage, cv::Rect(xRoi, yRoi, widthRoi, heightRoi));

	cv::imshow("ROI_img", ROI_img);

	cv::waitKey(0);

	return 0;
}

运行结果如下:


也可先构造一个不带参数的Rect对象,然后根据要选择的矩形区域设置对应的成员变量值。
此种方法的示例代码如下:
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

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

using namespace std;
using namespace cv;


int main()
{
	// 源图像载入及判断
	cv::Mat srcImage = cv::imread("F:/material/images/P0003-view-2.jpg");
	if (!srcImage.data)
		return 1;

	cv::imshow("srcImage", srcImage);

	// 利用Rect选择矩形区域(左上角的坐标为(0,200),宽度为200,高度为100)

	cv::Rect roiRect;
	
	roiRect.x = 0;
	roiRect.y = 200;
	roiRect.width = 200;
	roiRect.height = 100;

	cv:Mat ROI_img(srcImage, roiRect);

	cv::imshow("ROI_img", ROI_img);

	cv::waitKey(0);

	return 0;
}

运行结果如下:


为了提高对ROI区域选择的灵活性,我们还可以结合OpenCV的窗口鼠标事件实现用鼠标的拖动去选择感兴趣区域
关于合OpenCV的窗口鼠标事件的相关知识,可参考页面 https://www.hhai.cc/thread-99-1-1.html

用鼠标去选择感兴趣区域的示例代码如下:
[C++] 纯文本查看 复制代码
//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术

//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询

//OpenCV版本 OpenCV3.0

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

using namespace std;
using namespace cv;


// 全局变量图像源
cv::Mat srcImage;
// 所选矩形区域  
cv::Rect roiRect;
// 起始点
cv::Point startPoint;
// 终止点
cv::Point endPoint;
// 完成所选区域标志位
bool downFlag = false;
bool upFlag = false;
void MouseEvent(int event, int x, int y, int flags, void* data)
{
	// 鼠标左键按下 获取起始点 
	if (event == EVENT_LBUTTONDOWN)
	{
		downFlag = true;
		startPoint.x = x;
		startPoint.y = y;
	}
	// 鼠标拖到松开 获取终止点
	if (event == EVENT_LBUTTONUP)
	{
		upFlag = true;
		endPoint.x = x;
		endPoint.y = y;
	}
	// 显示鼠标选择的图像区域
	if (downFlag == true && upFlag == false)
	{
		Point tempPoint;
		tempPoint.x = x;
		tempPoint.y = y;
		// 用于显示图像生成
		cv::Mat tempImage = srcImage.clone();
		cv::rectangle(tempImage, startPoint, tempPoint,
			Scalar(255, 0, 0), 2, 3, 0);
		cv::imshow("ROIing", tempImage);
	}	// 选择区域生成
	if (downFlag == true && upFlag == true)
	{
		// 获取选择区域的ROI
		roiRect.width = abs(startPoint.x - endPoint.x);
		roiRect.height = abs(startPoint.y - endPoint.y);
		roiRect.x = min(startPoint.x, endPoint.x);
		roiRect.y = min(startPoint.y, endPoint.y);
		cv::Mat roiMat(srcImage, roiRect);
		imshow("ROI", roiMat);
		downFlag = false;
		upFlag = false;
	}
	cv::waitKey(0);
}
int main(int argc, char** argv)
{
	// 读取图像及判断是否正确读入
	srcImage = cv::imread("F:/material/images/P0003-view-2.jpg");
	if (srcImage.empty())
		return -1;
	// 回调事件响应
	cv::namedWindow("ROIing");
	cv::imshow("ROIing", srcImage);
	cv::setMouseCallback("ROIing", MouseEvent, 0);
	cv::waitKey(0);
	return 0;
}

在上面的代码中,roiRect就是我们用鼠标选择得到的感兴趣区域,而图像roiMat就是感兴趣区域对应的图像,大家可修改此代码使其适合自己使用。

运行结果如下:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|昊虹AI笔记网 ( 蜀ICP备2022024117号-1 )

GMT+8, 2024-5-6 05:34 , Processed in 0.026747 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表