Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体。所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓。

OpenCV中有一个很强大的函数,它可以从二值图像中找到轮廓:findContours函数。

有时我们还需要把找到的轮廓画出来,那就要用到函数drawContours了。

findContours函数和那就要用到函数drawContours函数一般配套使用。

#include "opencv2/imgproc.hpp"#include "opencv2/highgui.hpp"#include <iostream>using namespace cv;using namespace std;void main() 
{
    Mat original = imread("test5.jpg");
    namedWindow("My original");
    imshow("My original", original);
    Mat gray = original;
    cvtColor(gray, gray, CV_RGB2GRAY);//灰度化

    int thresh_size = (100 / 4) * 2 + 1; //自适应二值化阈值
    adaptiveThreshold(gray, gray, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, thresh_size, thresh_size / 3);    //morphologyEx(gray, gray, MORPH_OPEN, Mat());//形态学开运算去噪点

    imshow("gray", gray);

    vector<vector<Point> > contours;
    findContours(gray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //找轮廓
    vector<vector<Point>> contours1;    for (int i = 0; i < contours.size(); ++i)
    {
        contours1.push_back(contours[i]);
    }    Mat hole(gray.size(), CV_8U, Scalar(0)); //遮罩图层
    drawContours(hole, contours1, -1, Scalar(255), CV_FILLED); //在遮罩图层上,用白色像素填充轮廓,得到MASK
    namedWindow("My hole");
    imshow("My hole", hole);    Mat crop(original.rows, original.cols,&n