opencv3/C++轮廓的提取与筛选方式
轮廓提取
findContours发现轮廓
findContours( InputOutputArray binImg, //输入8bit图像,0值像素值不变,非0的像素看成1;(变为二值图像) OutputArrayOfArrays contours,//输出找到的轮廓对象 OutputArray, hierachy// 图像的拓扑结构 int mode, //轮廓返回的模式(RETR_TREE等) int method,//发现方法(CHAIN_APPROX_SIMPLE等) Point offset=Point()//轮廓像素的位移(默认没有位移(0, 0)) )
【报错问题】
findContours()有时会报告“已触发了一个断点”等错误,尝试过y有效的解决方法有:
1.为vector提前申请一定的空间,如
std::vector<std::vector<Point>> contours(500)
2.Debug版切换为Release版;
drawContours绘制轮廓
drawContours( InputOutputArray binImg, // 输出图像 OutputArrayOfArrays contours,//找到的全部轮廓对象 Int contourIdx//轮廓索引号 const Scalar & color,//绘制颜色 int thickness,//绘制线宽 int lineType ,//线的类型(默认8) InputArray hierarchy,//拓扑结构图 int maxlevel,//最大层数(0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓) Point offset=Point()//轮廓位移 )
示例:
#include<opencv2/opencv.hpp> using namespace cv; int main() { Mat src,dst; src = imread("E:/image/image/shape.jpg"); if(src.empty()) { printf("can not load image \n"); return -1; } namedWindow("input", CV_WINDOW_AUTOSIZE); imshow("input", src); dst = Mat::zeros(src.size(), CV_8UC3); blur(src,src,Size(3,3)); cvtColor(src,src,COLOR_BGR2GRAY); Canny(src, src, 20, 80, 3, false); std::vector<std::vector<Point>> contours; std::vector<Vec4i> hierarchy; findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); RNG rng(0); for(int i = 0; i < contours.size(); i++) { Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)); drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0,0)); } namedWindow("output", CV_WINDOW_AUTOSIZE); imshow("output",dst); waitKey(); return 0; }
使用opencv3时(测试用opencv3.1.0)发现,cv命名空间下没有了vector,而在opencv2中(测试用opencv2.4.10)还存在。后查看各自的头文件发现:
opencv.hpp头文件中包含着core.hpp(#include “opencv2/core.hpp”);
而在opencv2的core.hpp中包含有
........ #include <map> #include <new> #include <string> #include <vector> .......
等头文件,但在opencv3的core.hpp中删去这些包含项。
因此在使用opencv3时cv命名空间下没有了vector。
使用opencv2.4.10时可以写:
#include<opencv2/opencv.hpp> using namespace cv; int main() { Mat src,dst; src = imread("E:/image/image/shape.jpg"); if(src.empty()) { printf("can not load image \n"); return -1; } namedWindow("input", CV_WINDOW_AUTOSIZE); imshow("input", src); dst = Mat::zeros(src.size(), CV_8UC3); blur(src,src,Size(5,5)); Canny(src, src, 20, 80, 3, false); vector<vector<Point>>contours; vector<Vec4i> hierarchy; findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); RNG rng(0); for(int i = 0; i < contours.size(); i++) { Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)); drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0,0)); } namedWindow("output", CV_WINDOW_AUTOSIZE); imshow("output",dst); waitKey(); return 0; }
绘制轮廓外矩形框
常用绘制轮廓外形状的函数:
cv::boundingRect(InputArray points)绘制一个矩形(轮廓周围最小矩形左上角点和右下角点)
cv::minAreaRect(InputArray points)绘制轮廓周围最小旋转矩形
cv::minEnclosingCircle(InputArray points, Point2f& center, float& radius)//绘制轮廓周围最小圆形
cv::fitEllipse(InputArray points)绘制轮廓周围最小椭圆
绘制轮廓外矩形框:
#include<opencv2/opencv.hpp> using namespace cv; int main() { Mat src,dst; src = imread("E:/image/shape.jpg"); if(src.empty()) { printf("can not load image \n"); return -1; } namedWindow("input", CV_WINDOW_AUTOSIZE); imshow("input", src); dst = Mat::zeros(src.size(), CV_8UC3); std::vector<std::vector<Point>>contours; std::vector<Vec4i> hierarchy; blur(src,src,Size(3,3)); cvtColor(src,src,COLOR_BGR2GRAY); Canny(src, src, 20, 80, 3, false); findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); RNG rng(0); std::vector<std::vector<Point>> contoursPloy(contours.size()); std::vector<RotatedRect> minRects(contours.size()); for(int i = 0; i < contours.size(); i++) { minRects[i] = minAreaRect(Mat(contours[i])); Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)); drawContours(dst, contoursPloy, i, color, 1,8,std::vector<Vec4i>(), 0, Point(0, 0)); Point2f rectPoints[4]; minRects[i].points(rectPoints); for (int j = 0; j < 4; j++) { line(dst, rectPoints[j], rectPoints[(j+1)%4], color, 1, 8, 0); } } namedWindow("output", CV_WINDOW_AUTOSIZE); imshow("output",dst); waitKey(); return 0; }
轮廓筛选
moments( InputArray array,//输入数据 bool binaryImage=false //是否为二值图像 ) contourArea( InputArray contour,//输入轮廓数据 bool oriented//返回绝对值(默认false) ) arcLength( InputArray curve,//输入轮廓 bool closed// 轮廓否是封闭曲线 )
轮廓筛选示例:
使用轮廓的面积和长度特征对轮廓进行筛选后用外接矩形将筛选后的轮廓框选出来。
#include<opencv2/opencv.hpp> using namespace cv; void trackBar(int,void*); Mat src,dst; std::vector<std::vector<Point>>contours; int area = 0, length = 0; int main() { src = imread("E:/image/shape.jpg"); if(src.empty()) { printf("can not load image \n"); return -1; } namedWindow("input", CV_WINDOW_AUTOSIZE); imshow("input", src); dst = Mat::zeros(src.size(), CV_8UC3); std::vector<Vec4i> hierarchy; blur(src,dst,Size(3,3)); cvtColor(dst,dst,COLOR_BGR2GRAY); Canny(dst, dst, 20, 80, 3, false); findContours(dst, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0)); namedWindow("output", CV_WINDOW_AUTOSIZE); createTrackbar("area:", "output", &area,150,trackBar); createTrackbar("length:", "output", &length,150,trackBar); waitKey(); return 0; } void trackBar(int,void*) { Mat src1 = src.clone(); RNG rng(0); std::vector<std::vector<Point>> contoursPloy(contours.size()); std::vector<RotatedRect> minRects(contours.size()); for(int i = 0; i < contours.size(); i++) { if(contourArea(contours[i]) > area && arcLength(contours[i], false) > length) { minRects[i] = minAreaRect(Mat(contours[i])); Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)); //drawContours(dst, contoursPloy, i, color, 1,8,vector<Vec4i>(), 0, Point(0, 0)); Point2f rectPoints[4]; minRects[i].points(rectPoints); for (int j = 0; j < 4; j++) { line(src1, rectPoints[j], rectPoints[(j+1)%4], color, 2, 8, 0); } } } imshow("output",src1); src1 = src; }
以上这篇opencv3/C++轮廓的提取与筛选方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要为大家详细介绍了js实现商品筛选功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-01
python 利用jieba.analyse进行 关键词提取
这篇文章主要介绍了python 利用jieba.analyse进行关键词提取的方法,帮助大家更好的利用python,感兴趣的朋友可以了解下...2020-12-18- 今天小编就为大家分享一篇opencv3/C++轮廓的提取与筛选方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 本篇文章为大家介绍了PHP利用ffmpeg提取视频中音频与视频画面的相关资料,很有参考价值,一起来看一看吧。 前言FFmpeg的名称来自MPEG视频编码标准,前面的“FF”代表...2017-07-06
- 这篇文章主要介绍了Python提取视频中图片的示例,分别按帧和按秒提取,帮助大家利用python处理视频,获取素材,感兴趣的朋友可以了解下...2020-10-23
- 平常工作生活中,boos可能会给我们很多网站取提取信息,这些网站有的无法响应,有的404,有的501…真的需要所有网站都访问再提取信息吗?今天写一个小工具用于筛选网站中能访问的网站,在此仅举一例,即状态码为200。...2021-01-22
- 今天小编就为大家分享一篇opencv3/C++ 直方图反向投影实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了c语言通过opencv实现轮廓处理与切割,具有一定借鉴价值,需要的朋友可以参考下...2020-04-25
- 今天小编就为大家分享一篇opencv3/C++实现光流点追踪,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了Python实现图片查找轮廓、多边形拟合、最小外接矩形代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-14
OpenCV-Python使用分水岭算法实现图像的分割与提取
在图像的处理过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来。本文就介绍了使用分水岭算法实现图像的分割与提取,感兴趣的可以了解一下...2021-06-08- 提取链接是一个很简单的做法了,下面这个例子相对来讲是比较全面了,下面我们一起来看看这个php curl采集页面内容并提取所有的链接例子. 本文承接上面两篇,本篇中的示...2016-11-25
- 今天小编就为大家分享一篇opencv3/C++ HOG特征提取方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 今天小编就为大家分享一篇opencv3/C++基于颜色的目标跟踪方式,具有很好的参考价值,希望对的有所帮助。一起跟随小编过来看看吧...2020-04-25
- 今天小编就为大家分享一篇opencv3/C++ FLANN特征匹配方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了pandas按条件筛选数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-20
- 这篇文章主要介绍了pandas 按日期范围筛选数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-20
- 这篇文章主要介绍了python批量提取图片信息并保存的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-06
- 这篇文章主要为大家详细介绍了基于Opencv实现对象提取与测量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
- 这篇文章主要介绍了R语言-实现提取包含某字符串的行变量,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06