【opencv 450 Image Processing】Creating Bounding boxes and circles for contours为轮廓创建边界框和圆
Goal
在本教程中,您将学习如何:
使用 OpenCV 函数 cv::boundingRect
使用 OpenCV 函数 cv::minEnclosureCircle
Theory
Code
本教程代码如下所示。 你也可以从这里下载 https://github.com/opencv/opencv/tree/4.x/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp
/*** @function generalContours_demo1.cpp* @brief 在图像中查找轮廓的演示代码* @author OpenCV team*/#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>using namespace cv;
using namespace std;Mat src_gray;
int thresh = 100;
RNG rng(12345);/// Function header
void thresh_callback(int, void* );/*** @function main*/
int main( int argc, char** argv )
{//! [setup]/// 加载源图像CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );if( src.empty() ){cout << "Could not open or find the image!\n" << endl;cout << "usage: " << argv[0] << " <Input image>" << endl;return -1;}/// 将图像转换为灰度图并模糊它cvtColor( src, src_gray, COLOR_BGR2GRAY );blur( src_gray, src_gray, Size(3,3) );//均值滤波//! [setup]//! [createWindow]/// 创建窗口const char* source_window = "Source";namedWindow( source_window );imshow( source_window, src );//显示源图像//! [createWindow]//! [trackbar]const int max_thresh = 255;createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );//创建滑动条thresh_callback( 0, 0 );//回调//! [trackbar]waitKey();return 0;
}/*** @function thresh_callback*/
void thresh_callback(int, void* )
{//! [Canny]/// 使用 Canny 检测边缘 Detect edges using CannyMat canny_output;Canny( src_gray, canny_output, thresh, thresh*2 );//! [Canny]//! [findContours]/// 寻找轮廓 Find contoursvector<vector<Point> > contours;findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );//! [findContours]//! [allthework]/// 近似轮廓到多边形 + 获得边界矩形和圆形 Approximate contours to polygons + get bounding rects and circlesvector<vector<Point> > contours_poly( contours.size() );//近似轮廓多边形vector<Rect> boundRect( contours.size() );//边界矩形vector<Point2f>centers( contours.size() );//边界圆圆心vector<float>radius( contours.size() );//边界圆半径for( size_t i = 0; i < contours.size(); i++ )//遍历轮廓点{approxPolyDP( contours[i], contours_poly[i], 3, true );//对图像轮廓点进行多边形拟合boundRect[i] = boundingRect( contours_poly[i] );//boundingRect来对指定的点集进行包含,使得形成一个最合适的正向矩形框把当前指定的点集都框住.计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的minEnclosingCircle( contours_poly[i], centers[i], radius[i] );//寻找包裹轮廓的最小圆}//! [allthework]//! [zeroMat]Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );//黑色背景图//! [zeroMat]//! [forContour]/// 绘制多边形轮廓+边界矩形+圆形 Draw polygonal contour + bonding rects + circlesfor( size_t i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );//随机颜色drawContours( drawing, contours_poly, (int)i, color );//轮廓多边形rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2 );//矩形circle( drawing, centers[i], (int)radius[i], color, 2 );//圆}//! [forContour]//! [showDrawings]/// 显示结果Show in a windowimshow( "Contours", drawing );//! [showDrawings]
}
Explanation
main 函数比较简单,从注释中我们做了如下:
- 打开图像,将其转换为灰度并对其进行模糊处理以消除噪点。
CommandLineParser parser( argc, argv, "{@input | stuff.jpg | input image}" );
Mat src = imread( samples::findFile( parser.get<String>( "@input" ) ) );
if( src.empty() )
{
cout << "Could not open or find the image!\n" << endl;
cout << "usage: " << argv[0] << " <Input image>" << endl;
return -1;
}
cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
2. 创建一个带有标题“Source”的窗口并在其中显示源文件。
const char* source_window = "Source";
namedWindow( source_window );
imshow( source_window, src );
3.在 source_window 上创建一个跟踪栏并为其分配一个回调函数。 一般来说,回调函数用于对某种信号做出反应,在我们的例子中是滑动条的状态变化。 要同时显示“轮廓”窗口和“源”窗口,需要显式地一次性调用 thresh_callback。
const int max_thresh = 255;
createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
回调函数完成了所有有趣的工作。
4. 使用 cv::Canny 检测图像中的边缘。
Mat canny_output;
Canny( src_gray, canny_output, thresh, thresh*2 );
5. 查找轮廓并将它们保存到向量轮廓和层次结构中。
vector<vector<Point> > contours;
findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
6. 对于每个找到的轮廓,我们现在将近似值应用于精度为 +-3 的多边形,并声明曲线必须是闭合的。 之后,我们为每个多边形找到一个边界矩形并将其保存到 boundRect。 最后,我们为每个多边形找到一个最小包围圆,并将其保存到中心和半径向量。
vector<vector<Point> > contours_poly( contours.size() );
vector<Rect> boundRect( contours.size() );
vector<Point2f>centers( contours.size() );
vector<float>radius( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{
approxPolyDP( contours[i], contours_poly[i], 3, true );
boundRect[i] = boundingRect( contours_poly[i] );
minEnclosingCircle( contours_poly[i], centers[i], radius[i] );
}
我们找到了我们需要的一切,我们所要做的就是画画。
7. 创建新的无符号 8 位字符 Mat,用零填充。 它将包含我们要制作的所有图纸(矩形和圆圈)。
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
8. 对于每个轮廓:选择一种随机颜色,用它绘制轮廓、边界矩形和最小的封闭圆。
for( size_t i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
drawContours( drawing, contours_poly, (int)i, color );
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2 );
circle( drawing, centers[i], (int)radius[i], color, 2 );
}
9. 显示结果:创建一个新窗口“轮廓”并在其上显示我们添加到图纸中的所有内容。
imshow( "Contours", drawing );
Result
参考:
cv.approxPolyDP多边拟合函数
cv.approxPolyDP() 的参数1是源图像的某个轮廓;参数2(epsilon)是一个距离值,表示多边形的轮廓接近实际轮廓的程度,值越小,越精确;参数3表示是否闭合。
C++: void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed)
参数详解;
InputArray curve:一般是由图像的轮廓点组成的点集
OutputArray approxCurve:表示输出的多边形点集,当前点集是能最小包容指定点集的。draw出来即是一个多边形;
double epsilon:主要表示输出的精度,也即是原始曲线与近似曲线之间的最大距离。
bool closed:表示输出的多边形是否封闭
openCV之approxPolyDP()多边拟合函数_zhangweiwei1516的博客-CSDN博客_approxpolydp 获取四个角点
寻找包裹轮廓的最小圆:minEnclosingCircle 函数
返回圆应满足:① 轮廓上的点均在圆形空间内。② 没有面积更小的满足条件的圆。
void minEnclosingCircle(InputArray points, Point2f& center, float& radius);
points,输入的二维点集,可以是 vector 或 Mat 类型。
center,圆的输出圆心。
radius,圆的输出半径。
opencv —— minEnclosingCircle、fitEllipse 寻找包裹轮廓的最小圆、点集拟合椭圆 - 老干妈就泡面 - 博客园 (cnblogs.com)
OpenCV—Python 轮廓检测 绘出矩形框(findContours\ boundingRect\rectangle)_javastart的博客-CSDN博客_findcontours 矩形
Opencv视觉学习--Rect、RotatedRect类与boundingRect( )、minAreaRect( )、fitEllipse( )函数_佳佳鸽的博客-CSDN博客
minAreaRect( )函数返回参数如图:
角点顺序是固定以最下面的点为P[0],顺时针依次递增编号的。将水平轴逆时针旋转,最先与水平轴平行的边作为宽width,另外一条边则为高height,并非长的就是height,短的就是width。而角度则直接取最先与水平轴平行的边与水平轴的夹角,取值范围[-90~0]。
fitEllipse( )函数返回参数如图:
角度参数angle 是椭圆中心center发出的平行于x轴的射线,顺时针旋转,与椭圆短轴的夹角,取值范围 [ 0 ~ 180 ]。椭圆的短轴为参数宽width,长轴为参数长height。
【opencv 450 Image Processing】Creating Bounding boxes and circles for contours为轮廓创建边界框和圆相关推荐
- OpenCV为轮廓创建边界框和圆
OpenCV为轮廓创建边界框和圆 为轮廓创建边界框和圆 目标 代码 解释 结果 为轮廓创建边界框和圆 目标 在本教程中,您将学习如何: 使用OpenCV函数cv :: boundingRect 使用O ...
- OpenCV为轮廓创建边界旋转框和椭圆
OpenCV为轮廓创建边界旋转框和椭圆 为轮廓创建边界旋转框和椭圆 目标 代码 结果 为轮廓创建边界旋转框和椭圆 目标 在本教程中,您将学习如何: 使用OpenCV函数cv :: minAreaRec ...
- 【opencv 450 Image Processing】Image Moments 图像矩
Goal 在本教程中,您将学习如何: 使用 OpenCV 函数 cv::moments 使用 OpenCV 函数 cv::contourArea 使用 OpenCV 函数 cv::arcLength ...
- 【opencv 450 Image Processing】Periodic Noise Removing Filter周期性去噪滤波器
Periodic Noise Removing Filter 周期性去噪滤波器 OpenCV: Periodic Noise Removing Filter Goal 在本教程中,您将学习: 如 ...
- 【opencv 450 Image Processing】Hit-or-Miss
Goal 在本教程中,您将学习如何使用 Hit-or-Miss 变换(也称为 Hit-and-Miss 变换)在二进制图像中找到给定的配置或模式(-1对应背景,1对应前景.找到邻域与内核模式一样的像素 ...
- 【opencv 450 Image Processing】Anisotropic image segmentation by a gradient structure tensor
Anisotropic image segmentation by a gradient structure tensor 梯度结构张量的各向异性图像分割 Goal 在本教程中,您将学习: 梯度结构张 ...
- 【NIPS 2020】Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for...译读笔记
论文名称 Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Dete ...
- (NeurIPS 2019) Learning Object Bounding Boxes for 3D Instance Segmentation on Point Clouds
Abstract 我们提出了一种新颖的.概念上简单的通用框架,用于在3D点云上进行实例分割.我们的方法称为3D-BoNet,遵循每点多层感知器(MLP)的简单设计理念.该框架直接回归点云中所有实例的3 ...
- [GFL]Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Dete
Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Detection ...
- 目标、物体识别(检测)object detection 中的 bounding boxes 是什么? 边界区域、边界框、边界盒
边界区域.边界框.边界盒 参考文章:人脸检测中的bounding box regression详解
最新文章
- 生物信息学 Python 入门之源码安装
- SpringSecurity实战:基于mysql自定义SpringSecurity权限认证规则
- 7 种常用的排序算法直观感受
- java getaccessflags_Java Method.getAccessFlags方法代码示例
- 【IM】关于监督降维的理解
- 创建和准备Oracle样例数据库
- 关于Unable to execute dex: Java heap space 解决办法
- 高斯白噪声下基于EM的多径时延估计
- 前端学习(1152):let经典面试题2
- java 序列化保存_保存到二进制/序列化Java
- celery-01-异步任务模块-解决发送邮件的延时问题
- PHP-Open Flash Chart注意事项
- cisco 基本命令
- Akamai:三季度DDoS攻击总数同比上涨138% 规模超100 Gbps
- 计算机专业窗体的事件何时触发,高三计算机专业VB试题(六)1
- 医学生学计算机建议,医学生计算机能力的培养
- Java基础 DAY15
- 基于js的网页计算器实现
- Lenovo Thinkpad BIOS中开启VT虚拟化后无法生效?
- 计算机打字手怎么放,打字时如何正确放置手指