findContours函数
1、findContours函数
函数的作用:
查找图像的轮廓
2、findContours函数,这个函数的原型为:
void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierar-
chy, int mode, int method, Point offset=Point())
参数说明
输入图像image必须为一个2值单通道图像
contours参数为检测的轮廓数组,每一个轮廓用一个point类型的vector表示
hiararchy参数和轮廓个数相同,每个轮廓contours[ i ]对应4个hierarchy元素hierarchy[ i ][ 0 ] ~hierarchy[ i ][ 3 ],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,该值设置为负数。
mode表示轮廓的检索模式
CV_RETR_EXTERNAL表示只检测外轮廓
CV_RETR_LIST检测的轮廓不建立等级关系
CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
CV_RETR_TREE建立一个等级树结构的轮廓。具体参考contours.c这个demo
method为轮廓的近似办法
CV_CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
CV_CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
offset表示代表轮廓点的偏移量,可以设置为任意值。对ROI图像中找出的轮廓,并要在整个图像中进行分析时,这个参数还是很有用的。
3、
findContours后会对输入的2值图像改变,所以如果不想改变该2值图像,需创建新mat来存放,findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似
contourArea函数可以得到当前轮廓包含区域的大小,方便轮廓的筛选
findContours经常与drawContours配合使用,用来将轮廓绘制出来。
void drawContours(InputOutputArray image, InputArrayOfArrays contours, int contourIdx, const Scalar& color, intthickness=1, int lineType=8, InputArray hierarchy=noArray(), int maxLevel=INT_MAX, Point offset=Point() )
其中第一个参数image表示目标图像,
第二个参数contours表示输入的轮廓组,每一组轮廓由点vector构成,
第三个参数contourIdx指明画第几个轮廓,如果该参数为负值,则画全部轮廓,
第四个参数color为轮廓的颜色,
第五个参数thickness为轮廓的线宽,如果为负值或CV_FILLED表示填充轮廓内部,
第六个参数lineType为线型,
第七个参数为轮廓结构信息,
第八个参数为maxLevel
得到了复杂轮廓往往不适合特征的检测,这里再介绍一个点集凸包络的提取函数convexHull,输入参数就可以是contours组中的一个轮廓,返回外凸包络的点集
还可以得到轮廓的外包络矩形,使用函数boundingRect,如果想得到旋转的外包络矩形,使用函数minAreaRect,返回值为RotatedRect;也可以得到轮廓的外包络圆,对应的函数为minEnclosingCircle;想得到轮廓的外包络椭圆,对应的函数为fitEllipse,返回值也是RotatedRect,可以用ellipse函数画出对应的椭圆
如果想根据多边形的轮廓信息得到多边形的多阶矩,可以使用类moments,这个类可以得到多边形和光栅形状的3阶以内的所有矩,类内有变量m00,m10,m01,m20,m11,m02,m30,m21,m12,m03,比如多边形的质心为 x = m10 / m00,y = m01 / m00。
如果想获得一点与多边形封闭轮廓的信息,可以调用pointPolygonTest函数,这个函数返回值为该点距离轮廓最近边界的距离,为正值为在轮廓内部,负值为在轮廓外部,0表示在边界上。
opencv代码:
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> #include <stdlib.h>using namespace cv; using namespace std;Mat src; Mat src_gray; int thresh = 100; int max_thresh = 255; RNG rng(12345);/// Function header void thresh_callback(int, void* );/** @function main */ int main( int argc, char** argv ) {/// 加载源图像src = imread( argv[1], 1 );/// 转成灰度并模糊化降噪cvtColor( src, src_gray, CV_BGR2GRAY );blur( src_gray, src_gray, Size(3,3) );/// 创建窗体char* source_window = "Source";namedWindow( source_window, CV_WINDOW_AUTOSIZE );imshow( source_window, src );createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );thresh_callback( 0, 0 );waitKey(0);return(0); }/** @function thresh_callback */ void thresh_callback(int, void* ) {Mat canny_output;vector<vector<Point> > contours;vector<Vec4i> hierarchy;/// 用Canny算子检测边缘Canny( src_gray, canny_output, thresh, thresh*2, 3 );/// 寻找轮廓findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );/// 绘出轮廓Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );for( int i = 0; i< contours.size(); i++ ){Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );}/// 在窗体中显示结果namedWindow( "Contours", CV_WINDOW_AUTOSIZE );imshow( "Contours", drawing ); }
// test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "Math.h" int _tmain(int argc, _TCHAR* argv[])
{ IplImage *src = cvLoadImage("c:\\temp.jpg", 0); IplImage *dsw = cvCreateImage(cvGetSize(src), 8, 1); IplImage *dst = cvCreateImage(cvGetSize(src), 8, 3); CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *first_contour = NULL; //turn the src image to a binary image //cvThreshold(src, dsw, 125, 255, CV_THRESH_BINARY_INV); cvThreshold(src, dsw, 100, 255, CV_THRESH_BINARY); cvFindContours(dsw, storage, &first_contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); cvZero(dst); int cnt = 0; for(; first_contour != 0; first_contour = first_contour->h_next) { cnt++; CvScalar color = CV_RGB(rand()&255, rand()&255, rand()&255); cvDrawContours(dst, first_contour, color, color, 0, 2, CV_FILLED, cvPoint(0, 0)); CvRect rect = cvBoundingRect(first_contour,0);cvRectangle(dst, cvPoint(rect.x, rect.y), cvPoint(rect.x + rect.width, rect.y + rect.height),CV_RGB(255, 0, 0), 1, 8, 0);} printf("the num of contours : %d\n", cnt); cvNamedWindow( "Source", 1 ); cvShowImage( "Source", src ); cvNamedWindow( "dsw", 1 ); cvShowImage( "dsw", dsw ); cvNamedWindow( "Components", 1 ); cvShowImage( "Components", dst ); cvReleaseMemStorage(&storage); cvWaitKey(-1); return 0;
}
findContours函数相关推荐
- findcontours函数_opencv轮廓findContoursamp;drawContours
本文目的 目的:学习使用opencv的findContours和drawContours函数 语言:java 版本:opencv-410 简介:通过findContours函数检测物体轮廓,并且用dr ...
- OpenCV findContours函数参数
目录 OpenCV findContours函数参数 python检测外轮廓: c++轮廓检测: 一.mode取值"CV_RETR_EXTERNAL",method取值" ...
- 【图像处理】——Python+opencv实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(findcontours函数和contourArea函数)
目录 一.函数 cv.findContours 二.轮廓层级(返回参数hierarchy) 三.轮廓寻找方式 1. RETR_LIST 2. RETR_TREE 3. RETR_EXTERNAL 4. ...
- Imgproc.findContours函数
//**************************************************************** 转载于http://www.cnblogs.com/chenjia ...
- opencv cv.findContours 函数详解
函数 cv.findContours contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy ...
- findContours函数报错:“将一个无效参数传递给了将无效参数视为严重错误的函数”解决方案之一
在使用findContours函数时,release可以通过,debug一直在报错:"将一个无效参数传递给了将无效参数视为严重错误的函数". 这里有个大牛汇集的好多种解决方法: h ...
- python-opencv2利用cv2.findContours()函数来查找检测物体的轮廓
轮廓检测 轮廓检测也是图像处理中经常用到的.OpenCV-Python接口中使用cv2.findContours()函数来查找检测物体的轮廓. 实现 使用方式如下: import cv2 img ...
- findContours函数详细解析
1: image, cnts, hierarchy = cv2.findContours(a,b,c)//寻找图形中的轮廓 传入的参数:a:传入的图像(二值化图像)b:轮廓的检索模式,一般是检测外轮廓 ...
- findContours()函数存储在contours中的数据形式
findcontou()函数的运用一般都与vector<vector<Point>>Contours;和vector<Vec4i> Hierarchy这两个函数一起 ...
最新文章
- mongodb--GridFS
- 自动躲避障碍物,微型蜂鸟机器人靠AI算法飞行
- 设置三个线程顺序打印数字问题(转载)
- [前缀和][dp] Jzoj P5873 小p的属性
- pytorch学习笔记(二十六):NIN
- 《C++ Primer》读书笔记
- 牛客练习赛31: D. 神器大师泰兹瑞与威穆(链表)
- 【android原生态RPG游戏框架源码】
- keras 中文文档学习一
- 2022年Java秋招面试必看的 | 微服务面试题
- java程序怎么混淆,使用混淆器,保护你的java程序,混淆java
- 移动端登录页样式错乱_手机登录界面样式设计启示
- Linux下使用Netfilter框架编写内核模块(统计协议层ping特定地址丢包数)
- 蚂蚁区块链第15课 JS SDK概述及API接口速查
- 远程桌面连接服务器时,键盘不能正常打字
- 基于Openwrt 拨号上网(SDX55) (PCIe)移植文档
- 黑盒测试与bug定位
- 在经济寒冬的乱七八糟的瞎说
- 计算机教室网络平面示意图,计算机机房平面布置图.doc
- 32位python和64位python区别_python32位和64位版本的区别是什么
热门文章
- 不动产登记进入倒计时 哪些房子必须要卖掉?
- 小米2+android版本,小米2S能刷Android4.4系统吗 小米2S刷Android4.4.2教程
- 阿里工作流引擎_免费开源,一款快速开发模块化脚手架,含工作流引擎
- [原] 探索 EventEmitter 在 Node.js 中的实现
- 冷启动问题:如何构建你的机器学习组合?
- app手机端连接tomcat电脑端服务器
- volitile关键字
- 安庆移动开展VoLTE网络测试
- ASP.NET MVC 5 實作 GridView 分頁
- RHCE 学习笔记(22) 网络用户