- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
在二值图像中查找轮廓。
该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具,可用于形状分析和对象检测与识别。参见 OpenCV 示例目录中的 squares.cpp。
findContours 是 OpenCV 库中的一个重要函数,用于从二值图像中检测并提取轮廓。轮廓是指图像中具有连续边界像素的集合,通常用于描述图像中的对象边界。findContours 函数可以从二值图像中找到所有连通的非零像素组成的轮廓,并返回一组轮廓点。
函数原型1
void cv::findContours
(
InputArray image,
OutputArrayOfArrays contours,
OutputArray hierarchy,
int mode,
int method,
Point offset = Point()
)
参数1
-
参数image Source, 源图像,一个8位单通道图像。非零像素被视为1。零像素保持为0,因此图像被视为二值图像。你可以使用 compare、inRange、threshold、adaptiveThreshold、Canny 等方法将灰度图像或彩色图像转换为二值图像。如果模式等于 RETR_CCOMP 或 RETR_FLOODFILL,输入也可以是一个32位整数标签图像(CV_32SC1)。
-
参数contours 检测到的轮廓。每个轮廓存储为一个点的向量(例如 std::vector<std::vectorcv::Point>)。
-
参数hierarchy 可选的输出向量(例如 std::vectorcv::Vec4i),包含有关图像拓扑结构的信息。它有与轮廓数量相同数量的元素。对于每个第 i 个轮廓 contours[i],元素 hierarchy[i][0]、hierarchy[i][1]、hierarchy[i][2] 和 hierarchy[i][3] 分别设置为在同一层次级别下的下一个轮廓和前一个轮廓在 contours 中的0基础索引,第一个子轮廓和父轮廓。如果对于轮廓 i 没有下一个轮廓、前一个轮廓、父轮廓或嵌套轮廓,hierarchy[i] 的相应元素将是负数。
-
参数mode 轮廓检索模式,参考RetrievalModes
-
参数method 轮廓近似方法,参考ContourApproximationModes。
-
参数offset 可选偏移量,用于移动轮廓上的每一个点。这对于从图像的感兴趣区域(ROI)中提取轮廓并在整个图像上下文中分析这些轮廓时非常有用。
函数原型2
这是一个重载成员函数,为方便提供。它与上述函数的不同之处仅在于它接受的参数
void cv::findContours
(
InputArray image,
OutputArrayOfArrays contours,
int mode,
int method,
Point offset = Point()
)
代码示例
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
// 读取图像
Mat img = imread( "/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg", IMREAD_GRAYSCALE );
if ( img.empty() )
{
cerr << "Error: Image not found." << endl;
return -1;
}
// 定义一个感兴趣区域
Rect roi( 260, 450, 250, 250 );
Mat imgROI = img( roi );
// 二值化处理
Mat binImg;
threshold( imgROI, binImg, 200,255, THRESH_BINARY_INV );
//imshow( "binary Image", binImg );
// 找到轮廓
vector< vector< Point > > contours;
vector< Vec4i > hierarchy;
findContours( binImg, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point( roi.x, roi.y ) ); // 应用偏移量
// 在原图上绘制轮廓
Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
for ( size_t i = 0; i < contours.size(); i++ )
{
Scalar color = Scalar( 0, 255, 0 ); // 绿色
drawContours( drawing, contours, i, color, 2, LINE_8, hierarchy, 0, Point() );
}
// 显示结果
imshow( "Original Image", img );
imshow( "Contours with Offset", drawing );
waitKey( 0 );
return 0;
}