findCounters函数是个重载函数,有两种声明方式:

普通声明:

findContours( InputOutputArray image, OutputArrayOfArrays contours,int mode, int method, Point offset=Point());

高级一点的:

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

高级一点的声明主要是多了一个 OutputArray hierarchy:

hierarchy的作用是说明各个轮廓的继承关系。

hierarchy也是一个向量,长度和contours相等,每个元素和contours的元素对应。hierarchy的每个元素是一个包含四个整型数的向量。即:

vector<Vec4i> hierarchy; //Vec4i is a vector contains four number of inthierarchy[i][0],hierarchy[i][1],hierarchy[i][2],hierarchy[i][3],分别表示的是第i条轮廓(contours[i])的下一条,前一条,包含的第一条轮廓(第一条子轮廓)和包含他的轮廓(父轮廓)。

我在使用时发现findcounters函数检测圆时,对同一个圆总是返回两个圆的点集,但是我只想要一个圆的点集,发现可以用hierarchy这个变量来解决问题,总是访问外面的圆就可以。

注意:要自己多看hierarchy函数变量的值就明白其用意了
OpenCV4.1.1+VS2017
author:Chenandong
time:2019.08.11
---------------------------------------------------------------
function:轮廓边缘查找,主要使用 findcounters
---------------------------------------------------------------#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>using namespace cv;
using namespace std;Mat src_gray;
int thresh = 200;RNG rng(12345);void thresh_callback(int, void*);int main(int argc, char** argv)
{   //加载图像并检测是否加载成功Mat src = imread("circle2.jpg");if (src.empty()){cout << "Could not open or find the image!\n" << endl;cout << "Usage: " << argv[0] << " <Input image>" << endl;return -1;}--------------图像前处理--------------------//转化为灰度图cvtColor(src, src_gray, COLOR_BGR2GRAY);//滤波blur(src_gray, src_gray, Size(3, 3));---------------------------------------------//展示前处理后的图像const char* source_window = "Source";namedWindow(source_window);imshow(source_window, src);//-----------------------------------------------------------------------------------------------------//先做边缘检测,用Canny函数完成二值化处理Mat canny_output;Canny(src_gray, canny_output, thresh, thresh * 2);//注意threash 是一个全局变量,滑动条引用了threash的地址//调用findCounter函数vector<vector<Point> > contours;vector<Vec4i> hierarchy;findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);//绘制轮廓Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);int count1 = 0;int count2 = 0;把所有轮廓都画出来//-------------------------------------------------------------------------------for (size_t i = 0; i < contours.size(); i++){count1 += 1;Scalar color = Scalar(0, 0, 255);drawContours(drawing, contours, (int)i, color, 1, LINE_AA, hierarchy, 0);}cout << "count1 is : \n" << count1 << endl;//------------------------------------------------------------------------只画顶层轮廓-------------------------------------------------------------------------------//for (int index = 0; index >= 0; index = hierarchy[index][0]) {//   count2 += 1;//    Scalar color = Scalar(255, 0, 0);//    drawContours(drawing, contours, (int)index, color, 1, LINE_AA, hierarchy, 0);//}//cout << "count2 is : \n" << count2 << endl;-----------------------------------------------------------------------------------imshow("Contours", drawing);waitKey();return 0;
}//--------------------------------------------------------------------------------------------------边缘查找,并调用滑动条函数,回调thresh_callback
//const int max_thresh = 255;
//createTrackbar("Canny thresh:", source_window, &thresh, max_thresh, thresh_callback);//注意&threash
//thresh_callback(0, 0);
//
查找边缘并绘制边缘
//void thresh_callback(int thresh, void*)
//{
//  //先做边缘检测,用Canny函数完成二值化处理
//  Mat canny_output;
//  Canny(src_gray, canny_output, thresh, thresh * 2);//注意threash 是一个全局变量,滑动条引用了threash的地址
//
//  //调用findCounter函数
//  vector<vector<Point> > contours;
//  vector<Vec4i> hierarchy;
//  findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
//
//  //绘制轮廓
//  Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
//  int count1 = 0;
//  int count2 = 0;
//
//  for (size_t i = 0; i < contours.size(); i++)
//  {
//      count1 += 1;
//      Scalar color = Scalar(0, 0, 255);
//      drawContours(drawing, contours, (int)i, color, 2, LINE_8, hierarchy, 0);
//  }
//
//  for (int index = 0; index >= 0; index = hierarchy[index][0]) {
//      count2 += 1;
//      Scalar color = Scalar(255,0,0);
//      drawContours(drawing, contours, (int)index, color, 2, LINE_8, hierarchy, 0);
//  }
//
//  printf("count1 is : \n", count1);
//  printf("count2 is : \n", count2);
//
//  imshow("Contours", drawing);
//}
//---------------------------------------------------------------------------------------------

不使用hierarchy变量时:

使用hierarchy变量的作用:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o7YmjmWy-1574154822710)(https://chenandongtime.github.io/img/findcounters2.jpg)]

参考:http://www.voidcn.com/article/p-pgtgzhaw-du.html

OpenCV学习笔记十一-findcounters函数相关推荐

  1. OpenCV学习笔记(二十一)——绘图函数core OpenCV学习笔记(二十二)——粒子滤波跟踪方法 OpenCV学习笔记(二十三)——OpenCV的GUI之凤凰涅槃Qt OpenCV学习笔记(二十

    OpenCV学习笔记(二十一)--绘图函数core 在图像中,我们经常想要在图像中做一些标识记号,这就需要绘图函数.OpenCV虽然没有太优秀的GUI,但在绘图方面还是做得很完整的.这里就介绍一下相关 ...

  2. OpenCV学习笔记(五十一)——imge stitching图像拼接stitching OpenCV学习笔记(五十二)——号外:OpenCV 2.4.1 又出来了。。。。。 OpenCV学习笔记(五

    OpenCV学习笔记(五十一)--imge stitching图像拼接stitching stitching是OpenCV2.4.0一个新模块,功能是实现图像拼接,所有的相关函数都被封装在Stitch ...

  3. OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co

    OpenCV学习笔记(四十一)--再看基础数据结构core 记得我在OpenCV学习笔记(四)--新版本的数据结构core里面讲过新版本的数据结构了,可是我再看这部分的时候,我发现我当时实在是看得太马 ...

  4. OpenCV学习笔记(三十一)——让demo在他人电脑跑起来 OpenCV学习笔记(三十二)——制作静态库的demo,没有dll也能hold住 OpenCV学习笔记(三十三)——用haar特征训练自己

    OpenCV学习笔记(三十一)--让demo在他人电脑跑起来 这一节的内容感觉比较土鳖.这从来就是一个老生常谈的问题.学MFC的时候就知道这个事情了,那时候记得老师强调多次,如果写的demo想在人家那 ...

  5. OpenCV学习笔记(十一)(十二)(十三)(十四)(十五)

    OpenCV学习笔记(十一)--谈谈像素的类型和对Templates的限制使用 Templates是c++的一个很强大的特征,可以是数据结构更加安全高效.但也会增加编译时间和代码的长度,当函数被频繁调 ...

  6. OpenCV学习笔记(十一):阈值化:threshold(),adaptivethreshold()

    OpenCV学习笔记(十一):阈值化:threshold(),adaptivethreshold() 一.定义: 1)固定阈值操作 double threshold( InputArray src, ...

  7. OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法...

    函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界. cv2.boundingRect(arr ...

  8. OpenCV学习笔记(三十六)——Kalman滤波做运动目标跟踪 OpenCV学习笔记(三十七)——实用函数、系统函数、宏core OpenCV学习笔记(三十八)——显示当前FPS OpenC

    OpenCV学习笔记(三十六)--Kalman滤波做运动目标跟踪 kalman滤波大家都很熟悉,其基本思想就是先不考虑输入信号和观测噪声的影响,得到状态变量和输出信号的估计值,再用输出信号的估计误差加 ...

  9. opencv学习笔记18:canny算子边缘检测原理及其函数使用

    canny边缘检测原理 去噪:边缘检测容易受到噪声的影响,在此之间,先去噪,通常采用高斯滤波器.opencv学习笔记11:图像滤波(均值,方框,高斯,中值) 梯度:对去噪后的图像采用sobel算子计算 ...

最新文章

  1. 如何在ArcMap中监听键盘鼠标事件
  2. Spring 事情具体详尽的解释
  3. uni-app——Vue3简单整合uView@1.8.4解决方案
  4. mysql left join 索引失效_MySQL索引列上做操作导致索引失效案例分析
  5. ios 贝塞尔曲线 颜色填充_iOS贝塞尔曲线(UIBezierPath)的基本使用方法
  6. 面试题:聊一聊设计模式的基本原则
  7. linux-查看用户id-查看文件目录所有者-查看进程操作者
  8. pytorch 之 imagefloder的用法
  9. 英特尔:已获得向华为供货许可;央视曝光“微信清粉”软件存风险;HHVM 4.75 发布|极客头条
  10. 华为员工 iPhone 发文遭罚;百度遭约谈勒令整改;锤子 1577 万元被法院保全 | 极客头条...
  11. Exploit Kit攻击工具包流量锐减96%!这段时间究竟发生了什么?
  12. iOS “项目名” has conflicting provisioning settings.
  13. 用友通总账问题维护精粹
  14. html5shiv不起作用,HTML5shiv不会对IE8
  15. FFMpeg-6、Libavdevice+SDL捕获显示摄像头、录屏
  16. 手披云雾开鸿蒙,有关泰山的古诗比叫熟悉的古诗来回吧~
  17. Kubernetes 认证
  18. tp5欢迎页 (获取系统信息)
  19. 移除元素---2022/03/16
  20. FL Studio21中文版免费下载,fl studio哪个版本好

热门文章

  1. 初识Entity Framework CodeFirst(2)
  2. POJ 2745 显示器 解题报告
  3. 关于flex布局的深入学习
  4. 谈谈我对js中闭包的理解
  5. windows安装go环境变量
  6. Vue2.x—理解vuex核心概念action(使用到ES6的变量的解构赋值)
  7. Caffe2:ubuntu修改链接方式ln
  8. 科学存储数据格式-HDF5
  9. 新版chrome调整开发者工具位置方式改变
  10. 菜鸟学SSH(八)——Hibernate对象的三种状态