OpenCV学习代码记录——轮廓(contour)检测

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录。

代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>  // cvtColor

int contours_test();

int ContourDetection()
{

    //return contours_test();
    cv::Mat image;  // 加载原始图片
    cv::Mat gary;   // 存储灰度图像
    cv::Mat dstimg; // 绘制轮廓目标图片 

    // 创建两个窗口
    cv::namedWindow("src"); // 原始图片显示窗口
    cv::namedWindow("dst"); // 轮廓图片显示窗口

    // 载入原始图片
    image = cv::imread("../Image/sisy.jpg");
    if (image.empty()) {
        puts("图片加载失败");
        return -1;
    }
    cv::imshow("src", image);   // 显示原始图片

    gary.create(image.size(), CV_8U);   // 申请灰度图存储空间
    cv::cvtColor(image, gary, CV_BGR2GRAY); // 转换原始图为灰度图
    cv::threshold(gary, gary, 128, 255, cv::THRESH_BINARY); // 转换为二值图   

    std::vector<std::vector<cv::Point> >    contours;   // 检测的轮廓数组
    std::vector<cv::Vec4i>                  hierarchy;  //
    int mode = CV_RETR_EXTERNAL;    // 轮廓检测模式
    //mode表示轮廓的检索模式
    //  CV_RETR_EXTERNAL表示只检测外轮廓
    //  CV_RETR_LIST检测的轮廓不建立等级关系
    //  CV_RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
    //  CV_RETR_TREE建立一个等级树结构的轮廓。具体参考contours.c这个demo

    int method = CV_CHAIN_APPROX_SIMPLE;
    //method为轮廓的近似办法
    //  CV_CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1 - x2),abs(y2 - y1)) == 1
    //  CV_CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
    //  CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法

    // 查找contour
    cv::findContours(gary/*输入图像(必须为一个2值单通道图像)*/,
        contours/*, hierarchy*/, mode, method);

    // 为轮廓显示图片申请空间
    dstimg = cv::Mat(image.size(), CV_8UC3); // 3通道图像,以便彩色显示
    image.copyTo(dstimg);                    // 拷贝源图像

    // 将轮廓画出
    cv::drawContours(dstimg/*目标图像*/,
        contours/*输入的轮廓组*/,
        -1 /*指明画第几个轮廓(负值表示全部轮廓)*/,
        cv::Scalar(0,0,255)/*轮廓颜色BGR(此处以红色绘制)*/,
        2 /*轮廓线宽*/,
        8 /*轮廓线型*/,
        cv::noArray()/*轮廓结构信息*/);

    // 显示轮廓图片
    cv::imshow("dst", dstimg);

    // 等待按键
    cv::waitKey();
}

int contours_test()
{
    std::string image_name = "../Image/sisy.jpg";

    cv::Mat src = cv::imread(image_name);
    cv::imshow("src", src);

    cv::Mat gray(src.size(), CV_8U);
    cv::cvtColor(src, gray, CV_BGR2GRAY);//转换成灰度图  

    cv::imshow("gray", gray);

    cv::threshold(gray, gray, 128, 255, cv::THRESH_BINARY);//转换成2值图像
    cv::imshow("binary", gray);

    /////////////////////////////////////////////////////////////////////
    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(gray,
        contours, // a vector of contours
        CV_RETR_EXTERNAL, // retrieve the external contours
        CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours  

                               // Print contours‘ length
    // std::cout << "Contours: " << contours.size() << std::endl;
    std::vector<std::vector<cv::Point>>::const_iterator itContours = contours.begin();
    for (; itContours != contours.end(); ++itContours)
    {

        //std::cout << "Size: " << itContours->size() << std::endl;
    }

    // draw black contours on white image
    cv::Mat result(gray.size(), CV_8U, cv::Scalar(255));
    cv::drawContours(result, contours,
        -1, // draw all contours
        cv::Scalar(0), // in black
        2); // with a thickness of 2  

    cv::namedWindow("Contours");
    cv::imshow("Contours", result);

    // draw contours on the original image
    cv::Mat original = cv::imread(image_name);
    cv::drawContours(original, contours,
        -1, // draw all contours
        cv::Scalar(255, 255, 255), // in white
        -1); // with a thickness of 2  

    cv::namedWindow("Contours on Animals");
    cv::imshow("Contours on Animals", original);

    // Let‘s now draw black contours on white image
    result.setTo(cv::Scalar(255));
    cv::drawContours(result, contours,
        -1, // draw all contours
        cv::Scalar(0), // in black
        -1); // with a thickness of 1
             //image= cv::imread("test.png",0);  

    cv::waitKey(0);

    return 0;
}

原文地址:https://www.cnblogs.com/oloroso/p/8721994.html

时间: 2024-11-08 18:22:09

OpenCV学习代码记录——轮廓(contour)检测的相关文章

OpenCV学习代码记录——Hough线段检测

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> // http://blog.csdn.net/zh

OpenCV学习代码记录—— Snake轮廓

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/legac

OpenCV学习代码记录——人脸检测

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/objdetect.hpp> #include <opencv2/img

OpenCV学习代码记录——canny边缘检测

很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tree/master/OpenCVTest. #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> // c

opencv学习---运动目标(前景)检测

opencv学习---运动目标(前景)检测 1.帧差法 原理:视频序列相邻两帧或三帧间采用基于像素的时间差分,通过闭值化来提取出图像中的运动区域. 优点:算法简单.计算量小,无需训练背景,对缓慢变换的光照不是很敏感. 缺点:容易受天气.阴影及杂乱背景干扰,阈值T的选择相当关键,稳定性差. 2.背景差分法 原理:用背景的参数模型来近似背景图像,将当前帧与背景图像进行差分比较实现对运动区域的检测 优点:计算量小,较高的实时性,利用已有帧信息进行背景动态更新 缺点:如何建立对于不同场景的动态变化均具有

Opencv学习笔记--Harris角点检测

image算法测试iteratoralgorithmfeatures 原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/7391511 文章目录: 一.Harris角点检测基本理论 二.opencv代码实现 三.改进的Harris角点检测 四.FAST角点检测 五.参考文献 六.附录(资料和源码) 一.Harris角点检测基本理论(要讲清楚东西太多,附录提供文档详细说明) 1.1 简略表达: 角点:最直观的印象就是在水平

利用opencv中的级联分类器进行人脸检测-opencv学习(1)

OpenCV支持的目标检测的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本的C++接口除了Haar特征以外也可以使用LBP特征. 先介绍一下相关的结构,级联分类器的计算特征值的基础类FeatureEvaluator,功能包括读操作read.复制clone.获得特征类型getFeatureType,分配图片分配窗口的操作setImage.setWindow,计算有序特征calcOrd,计算绝对特征calcC

OpenCV学习笔记[5]FLANN特征匹配

OpenCV学习笔记:FLANN特征匹配 本次给出FLANN特征匹配的Java实现. [简介] 特征匹配记录下目标图像与待匹配图像的特征点(KeyPoint),并根据特征点集合构造特征量(descriptor),对这个特征量进行比较.筛选,最终得到一个匹配点的映射集合.我们也可以根据这个集合的大小来衡量两幅图片的匹配程度. 特征匹配与模板匹配不同,由于是计算特征点集合的相关度,转置操作对匹配影响不大,但它容易受到失真.缩放的影响. [特征匹配] FeatureMatching.java: imp

OpenCV+OpenVINO实现人脸Landmarks实时检测

缘由 自从OpenCV3.3版本引入深度神经网络(DNN)模块之后,OpenCV对DNN模块支持最好的表现之一就是开始支持基于深度学习人脸检测,OpenCV本身提供了两个模型分别是基于Caffe与Tensorflow的,Caffe版本的模型是半精度16位的,tensorflow版本的模型是8位量化的.同时OpenCV通过与OpenVINO IE模型集成实现了底层硬件对对象检测.图像分割.图像分类等常见模型加速推理支持.OpenVINO框架本身提供直接快速开发应用原型的模型库,对很多常见视觉任务都