zoukankan      html  css  js  c++  java
  • 查找并绘制轮廓[OpenCV 笔记XX]

    好久没有更新了,原谅自己放了个假最近又在赶进度,所以。。。更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号。。。加油加油!

     

    在二值图像中寻找轮廓

    void cv::findContours    (    InputOutputArray     image,
                            OutputArrayOfArrays     contours,
                            OutputArray     hierarchy,
                            int     mode,
                            int     method,
                            Point     offset = Point() 
                          )    
    • image: 输入图像,需为8位单通道图像,图像非0像素视为1。 可以用compare(), imrange(), threshold(), adaptivethreshold(), canny()等函数创建,注意:此函数会在提取图像轮廓的同时修改图像内容。
      • If mode equals to RETR_CCOMP or RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1).
    • contours: 检测到的轮廓,每个轮廓存储为一个点向量,即用point类型的vector,例如可为类型vector<vector<Point> >。
    • hierarchy: 可选的输出向量,包含图像的拓扑信息。 每个轮廓contours[i],
      • hierarchy[i][0] , 后一个轮廓,
      • hierarchy[i][1] , 前一个轮廓,
      • hierarchy[i][2] , 父轮廓,
      • hierarchy[i][3], 内嵌轮廓的索引编号。
      • 如果没有对应项,hierarchy[i]中的对应项设为负数。
    • mode: 检索模式,可选模式包括
      • RETR_EXTERNAL: 只监测最外层轮扩。hierarchy[i][2] = hierarchy[i][3] = -1
      • RETR_LIST: 提取所有轮廓,并放置在list中。检测的轮廓不建立等级关系。
      • RETR_CCOMP: 提取所有轮廓,并将其组织为双层结构,顶层为联通域的外围边界,次层为空的内层边界。
      • RETR_TREE: 提取所有轮廓,并重新建立网状的轮廓结构。
    • method: 轮廓的近似办法,包括
      • CHAIN_APPROX_NONE: 获取每个轮廓的每个像素,相邻两点像素位置差不超过1,max(abs(x1-x2),abs(y1-y2)) == 1
      • CHAIN_APPROX_SIMPLE: 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标
      • CHAIN_APPROX_TC89_LI /CHAIN_APPROX_TC89_KCOS: 使用Teh-Chinl链逼近算法中的一个
        • [135] C-H Teh and Roland T. Chin. On the detection of dominant points on digital curves. Pattern Analysis and Machine Intelligence, IEEE Transactions on, 11(8):859–872, 1989.
    • offSet: 每个轮廓点的可选偏移量,默认Point(), 当ROI图像中找出的轮廓需要在整个图中进行分析时,可利用这个参数。

    绘制轮廓

    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() 
                          )    
    • image: 目标图像
    • contours: 输入轮廓,每个轮廓存储为一个点向量
    • contourIdx: 需要绘制的轮廓的编号,如果为负,绘制所有轮廓
    • color: 轮廓颜色
    • thickness: 轮廓线条粗细度,如果为负值(如thickness==cv_filled),绘制在轮廓内部
    • lineType: 线条类型
      • 8: 8连通线型
      • 4: 4连通线型
      • LINE_AA (OpenCV2: CV_AA): 抗锯齿线型
    • hierarchy: 可选层次结构
    • maxLevel: 绘制轮廓的最大等级
    • offset: 可选轮廓偏移参数

    事例程序1

    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <vector>
    
    // main
    int main( int argc, char** argv )
    {
        // loading image
        cv::Mat srcImage = cv::imread("1.jpg", 0);
        imshow("original image", srcImage);
        
        // initialize result image
        cv::Mat dstImage = cv::Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
        
        // thresholding image
        srcImage = srcImage > 119;
        imshow("thresholding image", srcImage);
        
        // finding contours
        std::vector<std::vector<cv::Point> > contours;
        std::vector<cv::Vec4i> hierarchy;
        // for opencv 2
        // cv::findContours(srcImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
        // for opencv 3
        cv::findContours(srcImage, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
        
        // iterate through all levels, and draw contours in random color
        int index = 0;
        for (; index>=0; index = hierarchy[index][0]) {
            cv::Scalar color(rand()&255, rand()&255, rand()&255);
            // for opencv 2
            // cv::drawContours(dstImage, contours, index, color,  CV_FILLED, 8, hierarchy);
            // for opencv 3
            cv::drawContours(dstImage, contours, index, color,  cv::FILLED, 8, hierarchy);
            
            imshow("contours", dstImage);
            cv::waitKey(150);
        }
        cv::imwrite("result.jpg", dstImage);
        return 0;
    }

    1.jpg

     

    result.jpg

    事例程序2

    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <iostream>
    #include <vector>
    
    #define WINDOW_NAME1 "original image"
    #define WINDOW_NAME2 "contours"
    
    // global variables
    cv::Mat g_srcImage;
    cv::Mat g_grayImage;
    cv::Mat g_cannyMat_output;
    int g_nThresh = 80;
    int g_nThresh_max = 255;
    cv::RNG g_rng(12345);
    std::vector<std::vector<cv::Point> > g_vContours;
    std::vector<cv::Vec4i> g_vHierarchy;
    
    // functions
    void on_ThreshChange(int, void*);
    
    // main
    int main( int argc, char** argv )
    {
        // change the text color of console
        system("color 1F");
        
        // loading image
        g_srcImage = cv::imread("1.jpg", 1);
        if (!g_srcImage.data){
            std::cerr << "ERROR while loading image." << std::endl;
            return false;
        }
        
        // convert to gray-scale and blur
        cv::cvtColor(g_srcImage, g_grayImage, cv::COLOR_BGR2GRAY);
        cv::blur(g_grayImage, g_grayImage, cv::Size(3,3));
        
        // create window
        cv::namedWindow(WINDOW_NAME1, cv::WINDOW_AUTOSIZE);
        imshow(WINDOW_NAME1, g_srcImage);
        
        // create tracker bar
        cv::createTrackbar("Canny Threshold", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);
        on_ThreshChange(0, 0);
        
        cv::waitKey(0);
        return 0;
    }
    
    void on_ThreshChange(int, void*)
    {
        cv::Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh*2, 3);
        
        cv::findContours(g_cannyMat_output, g_vContours, g_vHierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
        
        cv::Mat drawing = cv::Mat::zeros(g_cannyMat_output.size(), CV_8UC3);
        for (int i = 0; i<g_vContours.size(); i++) {
            cv::Scalar color(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));
            cv::drawContours(drawing, g_vContours, i, color,  2, 8, g_vHierarchy);
        }
        imshow(WINDOW_NAME2, drawing);
    }

    结果图:

     

     

      

  • 相关阅读:
    OE_ORDER_PUB.PROCESS_ORDER to Apply hold on a sales order
    父母
    更新价目表价格
    Netbeans6.8 主题美化及去掉红线
    IIS宿主wcf时的错误解决
    ubuntu安装deb,rpm安装包方法
    高效程序员的45个习惯
    数据库无法保存中文的解决
    1366*768 play game full screen
    项目管理部分随笔索引
  • 原文地址:https://www.cnblogs.com/Xiaoyan-Li/p/5761510.html
Copyright © 2011-2022 走看看