opencv学习(四十)之寻找图像轮廓findContours()
1.概述
在这篇文章中介绍如何使用findContours()函数寻找图像中物体的轮廓,在OpenCV中没有给出findCountours()函数的原理,如果想了解查找轮廓原理,可以翻**墙出去Google”Topological structural analysis of digitized binary images by border following”,这里就不一一翻译了.
2.API
opencv中提供findContours()函数来寻找图像中物体的轮廓,并结合drawContours()函数将找到的轮廓绘制出。首先看一下findContours(),opencv中提供了两种定义形式
findContours()
void cv::findContours ( InputOutputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
参数解释
image:输入图像,图像必须为8-bit单通道图像,图像中的非零像素将被视为1,0像素保留其像素值,故加载图像后会自动转换为二值图像。我们同样可以使用cv::compare,cv::inRange,cv::threshold,cv::adaptiveThreshold,cv::Canny等函数来创建二值图像,,如果第四个参数为cv::RETR_CCOMP或cv::RETR_FLOODFILL,输入图像可以是32-bit整型图像(CV_32SC1)
contours:检测到的轮廓,每个轮廓都是以点向量的形式进行存储即使用point类型的vector表示
hierarchy:可选的输出向量(std::vector),包含了图像的拓扑信息,作为轮廓数量的表示hierarchy包含了很多元素,每个轮廓contours[i]对应hierarchy中hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓的索引,如果没有对应项,则相应的hierarchy[i]设置为负数。
mode轮廓检索模式,可以通过cv::RetrievalModes()查看详细信息,如下
其中
RETR_EXTERNAL:表示只检测最外层轮廓,对所有轮廓设置hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有轮廓,并放置在list中,检测的轮廓不建立等级关系
RETR_CCOMP:提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界
RETR_TREE:提取所有轮廓并重新建立网状轮廓结构
RETR_FLOODFILL:官网没有介绍,应该是洪水填充法
method:轮廓近似方法可以通过cv::ContourApproximationModes()查看详细信息
CHAIN_APPROX_NONE:获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,值保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS使用Teh-Chinl链逼近算法中的一种
offset:轮廓点可选偏移量,有默认值Point(),对ROI图像中找出的轮廓并要在整个图像中进行分析时,使用
opencv中提供的另一种定义形式如下:
void cv::findContours ( InputOutputArray image,
OutputArrayOfArrays contours,
int mode,
int method,
Point offset = Point()
)
- 1
- 2
- 3
- 4
- 5
- 6
drawContours()
void cv::drawContours ( InputOutputArray image,
InputArrayOfArrays contours,
int contourIdx,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX,
Point offset = Point()
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
参数解释
image:输入输出图像,Mat类型即可
contours:使用findContours检测到的轮廓数据,每个轮廓以点向量的形式存储,point类型的vector
contourIdx:绘制轮廓的只是变量,如果为负值则绘制所有输入轮廓
color:轮廓颜色
thickness:绘制轮廓所用线条粗细度,如果值为负值,则在轮廓内部绘制
lineTpye:线条类型,有默认值LINE_8,有如下可选类型
hierarchy:可选层次结构信息
maxLevel:用于绘制轮廓的最大等级
offset:可选轮廓便宜参数,用制定偏移量offset=(dx, dy)给出绘制轮廓的偏移量
3.示例代码
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <stdlib.h>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage, grayImage, dstImage;
srcImage = imread("HappyFish.jpg");
//判断图像是否加载成功
if (srcImage.empty())
{
cout << "图像加载失败" << endl;
return -1;
}
else
{
cout << "图像加载成功!" << endl << endl;
}
namedWindow("原图像", WINDOW_AUTOSIZE);
imshow("原图像", srcImage);
//转换为灰度图并平滑滤波
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
//定义变量
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
grayImage = grayImage > 100;
findContours(grayImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
//绘制轮廓图
dstImage = Mat::zeros(grayImage.size(), CV_8UC3);
for (int i = 0; i < hierarchy.size(); i++)
{
Scalar color = Scalar(rand() % 255, rand() % 255, rand() % 255);
drawContours(dstImage, contours, i, color, CV_FILLED, 8, hierarchy);
}
imshow("轮廓图", dstImage);
waitKey(0);
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
4.运行结果
相关文章
- 视频转图片(opencv+python)
- [轻笔记]CMakeLists指定opencv路径
- C++数据文件存储与加载(利用opencv)
- ubuntu安装opencv:ICV: Downloading ippicv_linux_20151201.tgz...|error: #error This file requires compil
- Emgu.CV/opencv 绘图 线面文字包括中文
- 高反差保留滤镜学习OpenCV:滤镜系列(11)——高反差保留
- opencv图像特效
- C# OpenCV人脸检测(三) DNN加载FaceDetectorYN模型做人脸检测
- C++ OpenCV基础视频教程---第01讲(OpenCV介绍与安装配置)
- 学习OpenCV需要哪些数学知识?
- OpenCV人工智能图像处理学习笔记 第6章 计算机视觉加强之机器学习下 Hog_SVM小狮子识别
- opencv--基于深度学习的人脸检测器
- python opencv 找到圆点标定板所有点后通过距离找两个角点3
- 使用OpenCV在图像和视频流中执行基于深度学习的超级分辨率
- OpenCV中的霍夫线变换、概率霍夫线变换
- 【OpenCV】- 模板匹配(浩瀚星空只为寻找那一抹明月)
- 【OpenCV】- 分水岭算法
- opencv学习(四十)之寻找图像轮廓findContours()
- OpenCV学习:找出人脸,同时比较两张图片中的人脸相似度
- opencv学习笔记五十九:图像融合之背景替换
- 【树莓派4B实现垃圾分类】Chap.0 项目概述 Tensorflow 1.14.0+Keras: 2.2.0+Opencv: 3.4+Python: 3.6+Numpy:1.16【深度学习 招式
- 1.1.6-学习Opencv与MFC混合编程之---播放WAV音乐和 alpha融合功能
- 1.1.3-学习Opencv与MFC混合编程之---画图工具 通过对话框进行工具的参数设置 画曲线 绘图校正
- opencv-empty是否为空
- 1.1.5-学习Opencv与MFC混合编程之---画图工具 输入文字和填充图像 修改光标
- 1.1.4-学习Opencv与MFC混合编程之---画图工具 画椭圆
- 1.1.3-学习Opencv与MFC混合编程之---画图工具 通过对话框进行工具的参数设置 画曲线 绘图校正
- 1.1-学习Opencv与MFC混合编程之---利用画图函数,生成视频,并写入视频文件
- 1.0.1-学习Opencv与MFC混合编程之---播放AVI视频