图像感兴趣区域(ROI)提取主要使用掩模来进行。掩模是二值图像,感兴趣区域的掩模值设置为255,非感兴趣区域的掩模值为0
获取掩模的方法主要有两种

方法一 使用opencv中Mat函数方法,调用Mat(Rect).setTo方法设置掩模

 Mat Mat::operator()( const Rect& roi ) const//调用Mat(Rect).setTo方法mask(rect).setTo(255);

方法二 在全为0的原始掩模中画一个封闭区域,使用漫水填充算法填充封闭区域,将封闭区域的值都设置为255,实现掩模的提取

方法三 将边界转换为轮廓,使用cv::drawContours(mask, contours, -1, cv::Scalar::all(255),CV_FILLED);
函数提取感兴趣区域(ROI)。
下文对矩形、椭圆,有方向的矩形,轮廓进行提取

1.矩形感兴趣区域提取

1.1 调用Mat(Rect).setTo方法设置掩模

使用方法一对矩形感兴趣区域进行提取示例代码如下:

#include<cv.h>
#include<highgui.h>
using namespace cv;
//方法1,假如区域为长方形,使用MAT 构造函数设置区域内的值为255
int main()
{Mat image=imread("lena.jpg");//初始化掩模矩阵Mat mask = Mat::zeros(image.size(), CV_8UC1);Rect rect;rect.x = 100;rect.y = 100;rect.width = 100;rect.height = 100; //设置矩形掩模mask(rect).setTo(255);Mat img2;image.copyTo(img2, mask);imshow("mask", mask);imshow("img2", img2);waitKey();return 0;
}

1.2 使用漫水填充算法获取矩形ROI

思路:
1)新建一个值全为零的掩模图像(全是黑的,值为0)
2)在掩模图像上用白色画出矩形的边界(边界值为255)
3)选取矩形的中心作为种子点,使用漫水填充算法将矩形的内部填充为白色(255),最后得到掩模图像,使用掩模实现感兴趣区域提取。

#include<cv.h>
#include<highgui.h>
using namespace cv;
int main()
{Mat image = imread("lena.jpg");Mat mask = Mat::zeros(image.size(), CV_8UC1);Rect rect;rect.x = 100;rect.y = 100;rect.width = 100;rect.height = 100;//画矩形rectangle(mask, rect, Scalar(255));//设置种子点位置Point seed;seed.x = 150;seed.y = 150;//pi的值表示为 v(pi),if  v(seed)-loDiff<v(pi)<v(seed)+upDiff,将pi的值设置为newVal//使用漫水填充算法填充floodFill(mask, seed, 255, NULL, cvScalarAll(0), cvScalarAll(0), CV_FLOODFILL_FIXED_RANGE);//mask(rect).setTo(255);Mat img2;image.copyTo(img2, mask);imshow("mask", mask);imshow("img2", img2);waitKey();return 0;
}

2.任意几何形状ROI提取

任意几何形状感兴趣区域的提取主要使用方法二和方法三。提取的关键是画出几何形状的边界或获得轮廓。

2.1 旋转的矩形(CvBox2D)、椭圆(RotatedRect)、圆的感兴趣区域的提取

示例代码如下:

#include<cv.h>
#include<highgui.h>
using namespace cv;
#define WIDTH 256
#define HEIGHT 256
void DrawBox(CvBox2D box, IplImage* img)
{CvPoint2D32f point[4];int i;for (i = 0; i<4; i++){point[i].x = 0;point[i].y = 0;}cvBoxPoints(box, point); //计算二维盒子顶点CvPoint pt[4];for (i = 0; i<4; i++){pt[i].x = (int)point[i].x;pt[i].y = (int)point[i].y;}cvLine(img, pt[0], pt[1], cvScalar(255), 2, 8, 0);cvLine(img, pt[1], pt[2], cvScalar(255), 2, 8, 0);cvLine(img, pt[2], pt[3], cvScalar(255), 2, 8, 0);cvLine(img, pt[3], pt[0], cvScalar(255), 2, 8, 0);}//方法3.在掩模图像中画旋转的矩形(CvBox2D)、椭圆(RotatedRect)、圆,使用漫水填充算法将几何图形内部的值设置为255
int main()
{Mat image = imread("dot_link_11.jpg");Mat mask = Mat::zeros(image.size(), CV_8UC1);CvBox2D box;box.size.width = 100;box.size.height = 50;box.angle = 30;box.center.x = 200;box.center.y = 200;情况1.画旋转的矩形(CvBox2D)//opencv 2.4.9//IplImage* imask = &IplImage(mask);//opencv 3.0//IplImage* imask = new IplImage(mask);//DrawBox(box,imask);//Point seed;//seed.x = box.center.x;//seed.y = box.center.y;//情况2.画椭圆//RotatedRect roRect;//roRect.angle = 30;//roRect.center.x = 200;//roRect.center.y = 200;//roRect.size.width = 100;//roRect.size.height = 50;//ellipse(mask, roRect, cvScalar(255));//Point seed;//seed.x = roRect.center.x;//seed.y = roRect.center.y;情况3.画圆Point center;center.x = 100;center.y = 100;float radius = 50;circle(mask, center, radius, Scalar(255));Point seed;seed.x = center.x;seed.y = center.y;//漫水填充//pi的值表示为 v(pi),if  v(seed)-loDiff<v(pi)<v(seed)+upDiff,将pi的值设置为newValfloodFill(mask, seed, 255, NULL, cvScalarAll(0), cvScalarAll(0), CV_FLOODFILL_FIXED_RANGE);//mask(rect).setTo(255);Mat maskImage;image.copyTo(maskImage, mask);imshow("mask", mask);imshow("img2", maskImage);waitKey();return 0;
}

2.2 感兴趣区域为轮廓的提取

(1)漫水填充算法思路:
1)调用opencv的画图函数cvLine将轮廓中相邻的点连接为区域
2)获取轮廓中心,使用漫水填充算法填充
示例代码如下:

void draw_external_contour_gray(CvSeq *seq, Mat grayImage)
{if (seq->total < 2){return;}Point* prePoint = (Point*)cvGetSeqElem(seq, 0);Point* lastPoint = (Point*)cvGetSeqElem(seq, seq->total - 1);cv::line(grayImage, *prePoint, *lastPoint,cvScalar(255), 1, 8, 0);for (int i = 1; i<seq->total; i++) {Point* p=(Point*)cvGetSeqElem(seq,i);cv::line(grayImage, *prePoint, *p, cvScalar(255), 1, 8, 0);*prePoint = *p;}
}
//方法4,假如区域边界为轮廓,使用掩模图像中画轮廓,使用漫水填充算法将几何图形内部的值设置为255
int main()
{Mat image=imread("lena.jpg");if(image.empty()){cout<<"image is empty"<<endl;return 0;}Mat mask = Mat::zeros(image.size(), CV_8UC1);CvMemStorage* storage = cvCreateMemStorage(0);
//  CvSeq* contour = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), storage);CvSeqWriter writer;cvStartWriteSeq(CV_32SC2, sizeof(CvSeq), sizeof(CvPoint),storage,&writer);CvPoint p1 = { 25, 60 };  CvPoint p2 = { 50, 110 };  CvPoint p4 = { 100, 60 }; CvPoint p3 = { 100, 110 }; CvPoint p5 = { 50, 10 };CV_WRITE_SEQ_ELEM(p1, writer);CV_WRITE_SEQ_ELEM(p2, writer);CV_WRITE_SEQ_ELEM(p3, writer);CV_WRITE_SEQ_ELEM(p4, writer);CV_WRITE_SEQ_ELEM(p5, writer);cvFlushSeqWriter(&writer);CvSeq* contour = cvEndWriteSeq(&writer);printf("contour.size=%d", contour->total);draw_external_contour_gray(contour, mask);Point seed;seed.x = 35;seed.y = 60;//漫水填充floodFill(mask, seed, 255, NULL, cvScalarAll(0), cvScalarAll(0), CV_FLOODFILL_FIXED_RANGE);Mat maskImage;image.copyTo(maskImage, mask);imshow("mask", maskImage);waitKey();return 0;
}

(2)将边界转换为轮廓,使用cv::drawContours(mask, contours, -1, cv::Scalar::all(255),CV_FILLED);
函数提取感兴趣区域(ROI)

代码如下:

#include <opencv2/core/core.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
#include <string>
using namespace cv;
using namespace std;
int main()
{Mat image=imread("lena.jpg");if(image.empty()){cout<<"image is empty"<<endl;return 0;}Mat mask = Mat::zeros(image.size(), CV_8UC1);Point p1 = { 25, 60 };  Point p2 = { 50, 110 };  Point p4 = { 100, 60 }; Point p3 = { 100, 110 }; Point p5 = { 50, 10 };vector<Point> contour;contour.push_back(p1);contour.push_back(p2);contour.push_back(p3);contour.push_back(p4);contour.push_back(p5);vector<vector<Point> > contours;contours.push_back(contour);cv::drawContours(mask, contours, -1, cv::Scalar::all(255),CV_FILLED);imshow("maskRegion",mask);waitKey();Mat maskImage;image.copyTo(maskImage, mask);imshow("getMaskImage", maskImage);waitKey();return 0;
}

注意:drawContours方法也是通用的提取感兴趣区域的方法

openCV任意几何形状感兴趣区域(ROI)提取相关推荐

  1. python二值化 感兴趣区域_Python+OpenCV感兴趣区域ROI提取方法

    方法一:使用轮廓 步骤1 """src为原图""" ROI = np.zeros(src.shape, np.uint8) #感兴趣区域RO ...

  2. C/C++ OpenCV设置感兴趣区域ROI

    设置感兴趣区域(ROI,region of interest),来专注或者简化工作过程,也就是从图像中选择一个图像区域,这个区域是 图像分析所关注的重点.我们圈定的这个区域,以便进行进一步处理 定义R ...

  3. python提取图片感兴趣区域_Python+OpenCV感兴趣区域ROI提取方法

    方法一:使用轮廓 步骤1 """src为原图""" ROI = np.zeros(src.shape, np.uint8) #感兴趣区域RO ...

  4. 【QtOpenCV 图像的感兴趣区域ROI】

    图像的ROI(region of interest)是指图像中感兴趣区域.在OpenCV中图像设置图像ROI区域,实现只对ROI区域操作. 文章目录 前言 一.GUI 二.实现代码 1.Rubber ...

  5. matlab如何手动选择图像目标区域,如何用MATLAB实现感兴趣区域ROI的选取

    描述 感兴趣区域 感兴趣区域(Regions of Interest,ROI)这一概念,是指图像中最能引起用户兴趣.最能表现图像内容的区域.感兴趣区域(Regions of Interest,ROI) ...

  6. ITK:在一幅图像中提取感兴趣区域ROI

    ITK:在一幅图像中提取感兴趣区域ROI 内容提要 输出结果 C++实现代码 内容提要 在给定图像中提取给定的关注区域(ROI) 输出结果 C++实现代码 #include "itkImag ...

  7. Python-OpenCV选择、提取感兴趣区域(ROI区域)

    Python-OpenCV选择.提取感兴趣区域(ROI区域) 在图像处理中,我们常常要对某个区域进行选择.提取,然后对这个区域进行单独分析.处理.显示. 这样的区域我们称为叫ROI区域,英文全称为Re ...

  8. C# opencvSharp实现鼠标移动选择感兴趣区域(ROI)

    C# opencvSharp实现鼠标移动选择感兴趣区域(ROI)主要通过鼠标响应事件来实现. 1.鼠标按下响应 MouseDown() 获取鼠标按下的开始坐标. private void pictur ...

  9. Opencv 图像处理-Contours函数提取轮廓及感兴趣区域ROI的必用且实用操作技巧-(涵盖Contours的一切使用基础,附代码段)

            需求目的:一般都是做项目时使用opencv的findcontours和drawcontours搭配使用抓取图像内感兴趣区域. 1.Contours函数轮廓点大小排序 当使用findco ...

最新文章

  1. Oracle存储过程(增、删、改)写法
  2. 网络缓存 峰值 linux,Linux Page Cache调优在Kafka中的应用
  3. 深度学习(四十五)条件对抗网络
  4. 中移4G模块-ML302-OpenCpu开发-(固件编译和烧录)
  5. basename函数 中文问题
  6. 《HTML5+JavaScript动画基础》——2.4 JavaScript对象
  7. JS JQ 页面加载顺序方法的区别
  8. [渝粤教育] 西南科技大学 会计学原理 在线考试复习资料(2)
  9. libc.so.6: version 'GLIBC_2.14' not found报错提示的解决方案
  10. .htaccess 语法以及应用
  11. 几个比较好的app开发框架
  12. Jpg格式图片如何缩小?怎么把jpg格式图片变小?
  13. 穷爸爸与富爸爸读后感 (2)
  14. Python全栈开发【基础-09】深浅拷贝+while循环
  15. HDU 6148 Valley Numer [数位dp]
  16. VB 从零开始编外挂(完整实践版)
  17. C++实现随机点名器(支持文件读入、手动输入、不重复点名)
  18. 影视解说短视频如何配音?三个文字转语音小技巧,配音其实也不难
  19. 回文序列是指正读反读均相同的字符序列,如“abba”和“abdba”均是 回文,但“good”不是回文。试写一个算法判定给定的字符串是否为回文序列。
  20. 有限状态机(FSM)的深入理解

热门文章

  1. 【Fluent Meshing】03 多段翼面重构流程操作
  2. Dozer-Mapping
  3. HJS-DE1/2时间继电器
  4. ps磨皮插件Portraiture分享
  5. 风光互补路灯系统实验设备QY-T12
  6. 【论文简述】EPP-MVSNet: Epipolar-assembling based Depth Prediction for Multi-view Stereo(ICCV 2021)
  7. python爬取csdn上的包含整人关键词的阅读量并且存入表格里
  8. 软件收集-结构计算与分析软件
  9. 必备的c语言入门自学教程2021新版!
  10. 小程序+springboot+vue技术构建分帐式多商户入驻商城系统开发,引入lombok简化项目代码