OpenCV(cv::findContours())
cv::findContours() 是 OpenCV 中用于检测图像中的轮廓的函数。
1. 函数定义
void findContours(
    InputOutputArray image, 
    OutputArrayOfArrays contours, 
    OutputArray hierarchy, 
    int mode, 
    int method, 
    Point offset = Point()
);
参数:
- 
image:- 类型: 
InputOutputArray(通常是二值化后的图像) - 描述: 输入图像,通常是灰度图像或二值图像。该图像会被函数修改,因此如果你想保留原始图像,建议传入其副本。可以使用 
cv::Canny()或cv::threshold()生成适合轮廓检测的二值图像。 
 - 类型: 
 - 
contours:- 类型: 
OutputArrayOfArrays - 描述: 输出的轮廓。每个轮廓是一个点的列表。例如,
contours[i]表示第 i 个轮廓,它是图像中一系列连接的点集。 
 - 类型: 
 - 
hierarchy:- 类型: 
OutputArray - 描述: 输出的轮廓层次结构。它是一个包含四个整数的向量,分别表示同一级别的前一个轮廓、下一个轮廓、父轮廓和子轮廓。通过该层次结构可以了解轮廓之间的嵌套关系。
 
 - 类型: 
 - 
mode:- 类型: 
int - 描述: 轮廓的检索模式,决定如何组织轮廓数据。取值可以是:
cv::RETR_EXTERNAL: 只提取外部轮廓,即不考虑嵌套的轮廓。cv::RETR_LIST: 提取所有的轮廓,但不创建层次关系。cv::RETR_CCOMP: 提取所有的轮廓并将它们组织成两级层次。顶层是外部轮廓,第二层是内部轮廓。cv::RETR_TREE: 提取所有轮廓并重构完整的嵌套轮廓的层次结构。
 
 - 类型: 
 - 
method:- 类型: 
int - 描述: 轮廓的近似方法。取值可以是:
cv::CHAIN_APPROX_NONE: 存储所有的轮廓点,不进行压缩。cv::CHAIN_APPROX_SIMPLE: 仅存储拐点信息(去除冗余的中间点)。cv::CHAIN_APPROX_TC89_L1,cv::CHAIN_APPROX_TC89_KCOS: 使用 Teh-Chin 链逼近算法。
 
 - 类型: 
 - 
offset:- 类型: 
Point - 描述: 轮廓中所有点的偏移量。这在需要对轮廓点进行平移时非常有用。
 
 - 类型: 
 
返回值:
该函数没有返回值。轮廓信息通过 contours 和 hierarchy 输出。
2. 示例
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main() {
    Mat src = imread("image.png", IMREAD_GRAYSCALE);
    Mat binarized;
    threshold(src, binarized, 128, 255, THRESH_BINARY);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    // 检测轮廓
    findContours(binarized, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
    // 绘制轮廓
    Mat output = Mat::zeros(src.size(), CV_8UC3);
    for (size_t i = 0; i < contours.size(); i++) {
        drawContours(output, contours, static_cast<int>(i), Scalar(0, 255, 0), 2, 8, hierarchy);
    }
    imshow("Contours", output);
    waitKey(0);
    return 0;
}
功能解析:
- 
二值化图像: 为了使
cv::findContours()正常工作,输入图像通常需要二值化(即背景和前景分离)。通过cv::threshold()或cv::Canny()可以生成二值图像。 - 
轮廓近似: 使用
CHAIN_APPROX_SIMPLE会显著减少存储轮廓的点数,因为它只会存储关键点,如直线段的拐点。这在处理复杂图像时,可以显著减少内存消耗。 - 
层次结构:
hierarchy数组能够提供轮廓的嵌套关系。例如,可以通过层次结构分析一个轮廓是否是另一个轮廓的子轮廓(例如洞内的对象)。这在分析复杂的图像时很有用。 
3. 常见应用
- 对象检测: 检测并标记图像中的物体轮廓。
 - 形状分析: 使用轮廓数据进行形状匹配和分析,例如计算轮廓的周长、面积等。
 - 目标分割: 通过检测并处理轮廓,可以将图像中的对象分割出来用于后续处理。
 
4. 注意事项
- 输入图像: 
cv::findContours()会修改输入图像,因此如果需要保留原始图像,应该传递图像的副本。 - 轮廓检测模式: 根据应用场景选择合适的 
mode,例如在需要层次结构时选择RETR_TREE,而只需要外部轮廓时选择RETR_EXTERNAL。 - 图像预处理: 确保输入图像经过适当的预处理(如二值化),以获得正确的轮廓结果。
 
                    
                
                
            
        
浙公网安备 33010602011771号