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. 超过20g的文件+上传

    demo下载地址:jsp-Eclipse,jsp-MyEclipse,PHP,ASP.NET 教程:ASP.NET,JSP,PHP 一. 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件 ...

  2. 【luogu3950】部落冲突--树剖

    题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...

  3. jQuery多选和单选下拉框插件select.js

    一.插件描述 可通过参数设置多选或者单选,多选返回数组结果,单选返回字符串,如图: 下载地址:https://pan.baidu.com/s/1JjVoK89_ueVVpfSlMDJwUQ   提取码 ...

  4. Python操作Jira

    目录 认证 项目(Project) 问题(Issue) 配置域(Fields) 关注者/评论/附件 创建/分配/转换问题 搜索 Jira提供了完善的RESTful API,如果不想直接请求API接口可 ...

  5. hashCode 的常规协定是:

    hashCode 的常规协定是:  . 在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改 ...

  6. ICEM-圆柱与长方体相切

    原视频下载地址:https://yunpan.cn/cqvgLe39ZU4Ke  访问密码 c1c9

  7. Spring和Quartz整合实现定时任务调度

    在Spring中可以很方便的使用Quartz来实现定时任务等功能,Quartz主要就是Schedule(任务调度器),Job(作业任务)和Trigger(触发器)三者的关系. 实现方式有多种,在此就介 ...

  8. 阿里云OSS的 存储包、下行流量包、回流流量包 三者有啥关系

    阿里云OSS的 存储包.下行流量包.回流流量包 三者有啥关系 一.总结 一句话总结: 你把文件放 oss,会占用存储空间,存储包覆盖这部分费用 你访问存储在 oss 里面的文件,会产生下行流量,就是从 ...

  9. 分区工具parted的使用方法

    一.         parted的用途及说明 概括使用说明: parted用于对磁盘(或RAID磁盘)进行分区及管理,与fdisk分区工具相比,支持2TB以上的磁盘分区,并且允许调整分区的大小.   ...

  10. android.mk-include

    -- include $(BUILD_STATIC_LIBRARY)表示编译成静态库 include $(BUILD_SHARED_LIBRARY)表示编译成动态库. include $(BUILD_ ...