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函数相关推荐

  1. findcontours函数_opencv轮廓findContoursamp;drawContours

    本文目的 目的:学习使用opencv的findContours和drawContours函数 语言:java 版本:opencv-410 简介:通过findContours函数检测物体轮廓,并且用dr ...

  2. OpenCV findContours函数参数

    目录 OpenCV findContours函数参数 python检测外轮廓: c++轮廓检测: 一.mode取值"CV_RETR_EXTERNAL",method取值" ...

  3. 【图像处理】——Python+opencv实现二值图像的轮廓边界跟踪以及轮廓面积周长的求解(findcontours函数和contourArea函数)

    目录 一.函数 cv.findContours 二.轮廓层级(返回参数hierarchy) 三.轮廓寻找方式 1. RETR_LIST 2. RETR_TREE 3. RETR_EXTERNAL 4. ...

  4. Imgproc.findContours函数

    //**************************************************************** 转载于http://www.cnblogs.com/chenjia ...

  5. opencv cv.findContours 函数详解

    函数 cv.findContours contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy ...

  6. findContours函数报错:“将一个无效参数传递给了将无效参数视为严重错误的函数”解决方案之一

    在使用findContours函数时,release可以通过,debug一直在报错:"将一个无效参数传递给了将无效参数视为严重错误的函数". 这里有个大牛汇集的好多种解决方法: h ...

  7. python-opencv2利用cv2.findContours()函数来查找检测物体的轮廓

    轮廓检测 轮廓检测也是图像处理中经常用到的.OpenCV-Python接口中使用cv2.findContours()函数来查找检测物体的轮廓. 实现 使用方式如下: import cv2   img ...

  8. findContours函数详细解析

    1: image, cnts, hierarchy = cv2.findContours(a,b,c)//寻找图形中的轮廓 传入的参数:a:传入的图像(二值化图像)b:轮廓的检索模式,一般是检测外轮廓 ...

  9. findContours()函数存储在contours中的数据形式

    findcontou()函数的运用一般都与vector<vector<Point>>Contours;和vector<Vec4i> Hierarchy这两个函数一起 ...

最新文章

  1. mongodb--GridFS
  2. 自动躲避障碍物,微型蜂鸟机器人靠AI算法飞行
  3. 设置三个线程顺序打印数字问题(转载)
  4. [前缀和][dp] Jzoj P5873 小p的属性
  5. pytorch学习笔记(二十六):NIN
  6. 《C++ Primer》读书笔记
  7. 牛客练习赛31: D. 神器大师泰兹瑞与威穆(链表)
  8. 【android原生态RPG游戏框架源码】
  9. keras 中文文档学习一
  10. 2022年Java秋招面试必看的 | 微服务面试题
  11. java程序怎么混淆,使用混淆器,保护你的java程序,混淆java
  12. 移动端登录页样式错乱_手机登录界面样式设计启示
  13. Linux下使用Netfilter框架编写内核模块(统计协议层ping特定地址丢包数)
  14. 蚂蚁区块链第15课 JS SDK概述及API接口速查
  15. 远程桌面连接服务器时,键盘不能正常打字
  16. 基于Openwrt 拨号上网(SDX55) (PCIe)移植文档
  17. 黑盒测试与bug定位
  18. 在经济寒冬的乱七八糟的瞎说
  19. 计算机教室网络平面示意图,计算机机房平面布置图.doc
  20. 32位python和64位python区别_python32位和64位版本的区别是什么

热门文章

  1. 不动产登记进入倒计时 哪些房子必须要卖掉?
  2. 小米2+android版本,小米2S能刷Android4.4系统吗 小米2S刷Android4.4.2教程
  3. 阿里工作流引擎_免费开源,一款快速开发模块化脚手架,含工作流引擎
  4. [原] 探索 EventEmitter 在 Node.js 中的实现
  5. 冷启动问题:如何构建你的机器学习组合?
  6. app手机端连接tomcat电脑端服务器
  7. volitile关键字
  8. 安庆移动开展VoLTE网络测试
  9. ASP.NET MVC 5 實作 GridView 分頁
  10. RHCE 学习笔记(22) 网络用户