opencv轮廓外接矩形
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轮廓外接矩形的更多相关文章
- Opencv 最小外接矩形合并拼接
前一篇画出了最小外接矩形,但是有时候画出来的矩形由于中间像素干扰或者是其他原因矩形框并不是真正想要的 如图1是一个信号的雨图,被矩形框分割成了多个小框: 需要合并矩形框达到的效果: 主要思想: 扫描两 ...
- opencv画出轮廓外接矩形
Mat cannyImage; /// Detect edges using canny Canny(src, cannyImage, , , ); vector<vector<Point ...
- OpenCV 求外接矩形以及旋转角度
程序没有写完整,大概功能就是实现了,希望大家分享学习,把他改对 // FindRotation-angle.cpp : 定义控制台应用程序的入口点. // // findContours.cpp : ...
- opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形
一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...
- opencv学习之路(25)、轮廓查找与绘制(四)——正外接矩形
一.简介 二.外接矩形的查找绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //外接矩形的查找 ...
- OpenCV代码:画出轮廓的外接矩形,和中心点
#include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include & ...
- Opencv绘制最小外接矩形、最小外接圆
Opencv中求点集的最小外结矩使用方法minAreaRect,求点集的最小外接圆使用方法minEnclosingCircle. minAreaRect方法原型: RotatedRect minAre ...
- Opencv,腐蚀,膨胀,轮廓检测,轮廓外接多边形
//形态学腐蚀 cvErode(pDstImage,pDstImage,,); //形态学膨胀 cvDilate(pDstImage,pDstImage,,); //中值滤波 cvSmooth(pDs ...
- Opencv 改进的外接矩形合并拼接方法
上一篇中的方法存在的问题是矩形框不够精确,而且效果不能达到要求 这里使用凸包检测的方法,并将原来膨胀系数由20缩小到5,达到了更好的效果 效果图: 效果图: 代码: #include <open ...
随机推荐
- 三十八. 分库分表概述 配置mycat
1.搭建mycat 分片服务器 数据库主机 192.168.4.55 使用db1库存储数据 数据库主机 192.168.4.56 使用db2库存储数据 主机 192.168.4.54 运行myca ...
- [other] Div
https://www.luogu.org/problemnew/show/U16765 解法一 随机输出一组合法解. 复杂度 O(1) 预计得分 10~??? 解法二 看完题目基本能想到大力贪心,通 ...
- 【原创】导出aws ec2为csv
1.安装 pip install boto3 csv 2.使用脚本更新秘钥和地区 # 导出aws ec2列表为cvs import boto3 import csv ec2 = boto3.cl ...
- 二分算法题目训练(三)——Anton and Making Potions详解
codeforces734C——Anton and Making Potions详解 Anton and Making Potions 题目描述(google翻译) 安东正在玩一个非常有趣的电脑游戏, ...
- 牛客训练21674——牛牛与LCM
Problem 链接:https://ac.nowcoder.com/acm/problem/21674 来源:牛客网 牛牛最近在学习初等数论,他的数学老师给他出了一道题,他觉得太简单了, 懒得做,于 ...
- hive --metastore三种模式
在官网上对于这几种模式的介绍如下: 按Metastore数据库位置分: 1.本地/嵌入式Metastore数据库(Derby) 2.远程Metastore数据库(其他的关系型数据库,像mysql.or ...
- [ambari环境搭建](未完待续)
[安装] https://blog.csdn.net/Happy_Sunshine_Boy/article/details/86595945#commentBox https://www.jiansh ...
- 【Canvas】绘制几何级数Geometric series曲线 y=1+1/2+1/4+1/8+1/16+1/32+1/64+....
相关资料:https://baike.baidu.com/item/%E5%87%A0%E4%BD%95%E7%BA%A7%E6%95%B0/112584?fr=aladdin 图线: 代码: < ...
- [Java复习] 分布式高可用-Hystrix
什么是Hystrix? Hystrix 可以让我们在分布式系统中对服务间的调用进行控制,加入一些调用延迟或者依赖故障的容错机制. Hystrix 的设计原则 对依赖服务调用时出现的调用延迟和调用失败进 ...
- Node.js event loop 和 JS 浏览器环境下的事件循环的区别
Node.js event loop 和 JS 浏览器环境下的事件循环的区别: 1.线程与进程: JS 是单线程执行的,指的是一个进程里只有一个主线程,那到底什么是线程?什么是进程? 进程是 CPU ...