1.寻找轮廓

api

 void cv::findContours( InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point() 

各个参数详解如下:

  • Image表示输入图像,必须是二值图像,二值图像可以threshold输出、Canny输出、inRange输出、自适应阈值输出等。
  • Contours获取的轮廓,每个轮廓是一系列的点集合
  • Hierarchy轮廓的层次信息,每个轮廓有四个相关信息,分别是同层下一个、前一个、第一个子节点、父节点
  • mode 表示轮廓寻找时候的拓扑结构返回 -RETR_EXTERNAL表示只返回最外层轮廓 -RETR_TREE表示返回轮廓树结构
    • CV_RETR_EXTERNAL:只检测外轮廓。忽略轮廓内部的洞

    • CV_RETR_LIST:检测所有轮廓,但不建立继承(包含)关系

    • CV_RETR_TREE:检测所有轮廓,并且建立所有的继承(包含)关系。也就是说用CV_RETR_EXTERNAL和CV_RETR_LIST方法的时候hierarchy这个变量是没用的,因为前者没有包含关系,找到的都是外轮廓,后者仅仅是找到所哟的轮廓但并不把包含关系区分。用TREE这种检测方法的时候我们的hierarchy这个参数才是有意义的

    • CV_RETR_CCOMP:检测所有轮廓,但是仅仅建立两层包含关系。外轮廓放到顶层,外轮廓包含的第一层内轮廓放到底层,如果内轮廓还包含轮廓,那就把这些内轮廓放到顶层去。

  • Method表示轮廓点集合取得是基于什么算法,常见的是基于CHAIN_APPROX_SIMPLE链式编码方法

注意,如果图像底色是白色,则检测最外层的轮廓为图像边框

2.绘制轮廓外接矩形

绘制外接矩形包括两种:

  • 绘制最大外接矩形
(Rect cv::boundingRect( InputArray points ))

其中,输入参数points为一系列点的集合(findContours中contours中的一个元素),对轮廓来说就是该轮廓的点集 返回结果是一个矩形,x, y, w, h

  • 绘制最小外接矩形
RotatedRect cv::minAreaRect( InputArray points )

其中,输入参数points为一系列点的集合(findContours中contours中的一个元素) ,对轮廓来说就是该轮廓的点集 返回结果是一个旋转矩形,包含下面的信息: - 矩形中心位置 - 矩形的宽高 - 旋转角度。

3.代码

EdgeDetection.h

 #pragma once
#include<opencv2/opencv.hpp>
#include<iostream> using namespace std;
using namespace cv; class EdgeDetection
{
cv::Mat m_img;
cv::Mat m_canny;
public:
EdgeDetection(cv::Mat iamge);
bool cannyProcess(unsigned int downThreshold,unsigned int upThreshold);
bool getContours(); ~EdgeDetection();
};

EdgeDetection.cpp

 #include "EdgeDetection.h"

 EdgeDetection::EdgeDetection(cv::Mat image)
{
m_img = image;
} bool EdgeDetection::cannyProcess(unsigned int downThreshold, unsigned int upThreshold)
{
bool ret=true; if (m_img.empty())
{
ret = false;
} cv::Canny(m_img, m_canny, downThreshold, upThreshold);
cv::imshow("Canny", m_canny); return ret;
} bool EdgeDetection::getContours()
{
bool ret = true;
if (m_canny.empty())
{
ret = false;
} cv::Mat k = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(, ), cv::Point(-, -));
cv::dilate(m_canny, m_canny, k);
imshow("dilate", m_canny); // 轮廓发现与绘制
vector<vector<cv::Point> > contours;
vector<Vec4i> hierarchy;
findContours(m_canny, contours, cv::RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point()); for (size_t i = ; i < contours.size();++i)
{
// 最大外接轮廓
cv::Rect rect = cv::boundingRect(contours[i]);
cv::rectangle(m_img,rect,cv::Scalar(,,),,LINE_8); // 最小外接轮廓
RotatedRect rrt = minAreaRect(contours[i]);
Point2f pts[];
rrt.points(pts);
// 绘制旋转矩形与中心位置
for (int i = ; i < ; i++) {
line(m_img, pts[i % ], pts[(i + ) % ], Scalar(, , ), , , );
}
Point2f cpt = rrt.center;
circle(m_img, cpt, , Scalar(, , ), , , );
} imshow("contours", m_img);
return ret;
} EdgeDetection::~EdgeDetection()
{
}

main.cpp

#include"EdgeDetection.h"
using namespace std;
using namespace cv; int main(int argc, char* argv[])
{
Mat src = imread("rect.jpg");
if (src.empty())
{
cout << "image is empty" << endl;
return -;
} imshow("input", src); EdgeDetection ed(src); ed.cannyProcess(,);
ed.getContours(); waitKey();
return ;
}

原图

canny

目标图

opencv轮廓外接矩形的更多相关文章

  1. Opencv 最小外接矩形合并拼接

    前一篇画出了最小外接矩形,但是有时候画出来的矩形由于中间像素干扰或者是其他原因矩形框并不是真正想要的 如图1是一个信号的雨图,被矩形框分割成了多个小框: 需要合并矩形框达到的效果: 主要思想: 扫描两 ...

  2. opencv画出轮廓外接矩形

    Mat cannyImage; /// Detect edges using canny Canny(src, cannyImage, , , ); vector<vector<Point ...

  3. OpenCV 求外接矩形以及旋转角度

    程序没有写完整,大概功能就是实现了,希望大家分享学习,把他改对 // FindRotation-angle.cpp : 定义控制台应用程序的入口点. // // findContours.cpp : ...

  4. opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形

    一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...

  5. opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形

    一.简介 二.外接矩形的查找绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //外接矩形的查找 ...

  6. OpenCV代码:画出轮廓的外接矩形,和中心点

    #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include & ...

  7. Opencv绘制最小外接矩形、最小外接圆

    Opencv中求点集的最小外结矩使用方法minAreaRect,求点集的最小外接圆使用方法minEnclosingCircle. minAreaRect方法原型: RotatedRect minAre ...

  8. Opencv,腐蚀,膨胀,轮廓检测,轮廓外接多边形

    //形态学腐蚀 cvErode(pDstImage,pDstImage,,); //形态学膨胀 cvDilate(pDstImage,pDstImage,,); //中值滤波 cvSmooth(pDs ...

  9. Opencv 改进的外接矩形合并拼接方法

    上一篇中的方法存在的问题是矩形框不够精确,而且效果不能达到要求 这里使用凸包检测的方法,并将原来膨胀系数由20缩小到5,达到了更好的效果 效果图: 效果图: 代码: #include <open ...

随机推荐

  1. vue上传大文件控件

    文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹.今天研究了一下这个问题,在 ...

  2. 发布新的模型类包(用于上传到 NuGet 服务器上)

    生成包文件: 1.修改了模型类之后,在项目上点击右键,在列表菜单中选择 “编辑 …….csproj”,然后将里面的三个版本号都换成新的版本号. 2.右键项目,点击“打包” 3.复制输出信息中生成的包的 ...

  3. NetworkX系列教程(4)-设置graph的信息

    小书匠Graph图论 要画出美观的graph,需要对graph里面的节点,边,节点的布局都要进行设置,具体可以看官方文档:Adding attributes to graphs, nodes, and ...

  4. ZR#999

    ZR#999 解法: 一道计数题,看到要求必须 $ m $ 个标号,所有标号至少出现一次的方案. 很容易想到可以容斥,但容斥这个东西是一种很神奇的东西,你可以看出来一道题需要容斥,但你就是不知道怎么容 ...

  5. Tkinter 之Canvas画布

    一.参数说明 参数 作用 background(bg) 指定 Canvas 的背景颜色 borderwidth(bd) 指定 Canvas 的边框宽度 closeenough 指定一个距离,当鼠标与画 ...

  6. python3编程基础之一:注释模块和包

    1.注释 python中的注释和其他任何编程语言中的注释都不一样,有的注释有特殊要求,而是还是有用的. 1).单行注释:注释以#开始到语句结尾,#号后一般跟一个空格 2).多行注释:文档注释,以&qu ...

  7. Apache日志详解

    在渗透测试的工作中,WEB网站的日志是非常重要的,今天总结了一些关于调配Apache日志的一些东西. 0x00 Apache日志文件名称及路径介绍 我们安装好Apache后,Apache的配置文件(h ...

  8. vue 路由传参的三种方法

    API在这里  https://router.vuejs.org/guide/essentials/navigation.html 第一种传参 通过路由属性中的name来确定匹配的路由,通过param ...

  9. 使用Adivisor配置增强处理,来实现数据库读写分离

    一.先写一个demo来概述Adivisor的简单使用步骤 实现步骤: 1.通过MethodBeforeAdivice接口实现前置增强处理 public class ServiceBeforeAdvis ...

  10. EXCEL公式中如何表示回车符?

    问题: 将 id credttm cdno cdamt cashbrid cashrole note 转换为 "id  credttm  cdno   cdamt  cashbrid  ca ...