zoukankan      html  css  js  c++  java
  • OpenCV2马拉松第24圈——轮廓提取

    计算机视觉讨论群162501053


    收入囊中
    • 在图片中找到轮廓而且描绘轮廓
    • 使用多边形。圆,椭圆来逼近我们的轮廓





    葵花宝典

    关于轮廓提取,几乎相同是一个连通域的推断。

    原理还是比較简单的。




    初识API

    C++: void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())
    C++: void findContours(InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset=Point())
     
    • image – 灰度图片.非0像素都被觉得是1.会被改动.
    • contours – 每个被检測到的轮廓都是points的集合
    • hierarchy – 可选输出, 跟轮廓数量大小一样.对每个contours[i]来说 ,hierarchy[i][0] , hiearchy[i][1] 分别表示与contours[i]同level的下一个。前一个轮廓索引hiearchy[i][2] , andhiearchy[i][3]分别表示contours[i]的子轮廓和父轮廓索引。

      假设不存在hierarchy[i] will be negative.

    • mode –
      • CV_RETR_EXTERNAL 仅仅获得最外面的轮廓,也就是说全部轮廓的hierarchy[i][2]=hierarchy[i][3]=-1 .
      • CV_RETR_LIST 获得全部的轮廓,无hierarchy
      • CV_RETR_CCOMP retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level.
      • CV_RETR_TREE 获得全部的轮廓,并输出hierarchy组织
    • method –
      • CV_CHAIN_APPROX_NONE 保存全部的点。max(abs(x1-x2),abs(y2-y1))==1.也就是说,不论什么轮廓上的两个点都处在一个九宫格内.
      • CV_CHAIN_APPROX_SIMPLE 进行了简单的水平竖直对角线压缩.对于一个矩形,仅仅保留了4个顶点. 
      • CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS  [TehChin89]
    • offset – 可选的轮廓位移.当分析图片ROI比較实用.


    找到轮廓后。就能够用drawContours画出来
    #include "cv.h"
    #include "highgui.h"
    
    using namespace cv;
    
    int main( int argc, char** argv )
    {
        Mat src;
        // the first command-line parameter must be a filename of the binary
        // (black-n-white) image
        if( argc != 2 || !(src=imread(argv[1], 0)).data)
            return -1;
    
        Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC3);
    
        src = src > 1;
        namedWindow( "Source", 1 );
        imshow( "Source", src );
    
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
    
        findContours( src, contours, hierarchy,
            CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
    
        // iterate through all the top-level contours,
        // draw each connected component with its own random color
        int idx = 0;
        for( ; idx >= 0; idx = hierarchy[idx][0] )
        {
            Scalar color( rand()&255, rand()&255, rand()&255 );
            drawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy );
        }
    
        namedWindow( "Components", 1 );
        imshow( "Components", dst );
        waitKey(0);
    }

    我们能够用矩形包围轮廓
    cv::Rect r0= cv::boundingRect(cv::Mat(contours[0]));
    cv::rectangle(result,r0,cv::Scalar(0),2);</span>

    也能够用圆
    float radius;
    cv::Point2f center;
    cv::minEnclosingCircle(cv::Mat(contours[1]),center,radius);
    cv::circle(result,cv::Point(center),static_cast<int>(radius),cv::Scalar(0),2);

    BRC_0     BRC_1


    也能够用多边形
    std::vector<cv::Point> poly;
    cv::approxPolyDP(cv::Mat(contours[2]), poly, 5,  true); 
    最左边那个

    也能够用还有一种多边形模拟convex hull
    std::vector<cv::Point> hull;
    cv::convexHull(cv::Mat(contours[3]),hull);

    Hull_0       Hull_1

    也能够用最小外接矩形
    vector<RotatedRect> minRect( contours.size() );
    for( int i = 0; i < contours.size(); i++ ) {
        minRect[i] = minAreaRect( Mat(contours[i]) );
    }
    


    也能够用椭圆
    vector<RotatedRect> minEllipse( contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        if( contours[i].size() > 5 )
            minEllipse[i] = fitEllipse( Mat(contours[i]) ); 
    

    BRE_0

    BRE_1



    还有非常多好用的函数

    cv::contourArea  预计一个轮廓的像素数

    cv::pointPolygonTest确定一个点是在轮廓内韩式轮廓外

    cv::matchShapes度量两个轮廓的相似度

    还有cv::moments用于计算重心等信息


    荷枪实弹

    參考1-轮廓提取 http://docs.opencv.org/master/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html#find-contours

    參考2-convexhull逼近 http://docs.opencv.org/master/doc/tutorials/imgproc/shapedescriptors/hull/hull.html#hull

    參考3-圆与矩形逼近 http://docs.opencv.org/master/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html

    參考4-最小外接矩形与椭圆逼近 http://docs.opencv.org/master/doc/tutorials/imgproc/shapedescriptors/bounding_rotated_ellipses/bounding_rotated_ellipses.html#bounding-rotated-ellipses
  • 相关阅读:
    SSM(六)JDK动态代理和Cglib动态代理
    SSM(三)Mybatis动态SQL
    MyBatis无限级分类实现的两种方法--自关联与map集合
    idea上MyBatis第一个例子
    idea 给maven项目添加依赖(二)
    idea 创建maven项目(一)
    Java学习笔记——三层架构
    MySQL实现自动使用uuid作为主键以及解决不能调用触发器的一点思路
    Java学习笔记——MySQL创建表结构
    jQuery入门——注册事件
  • 原文地址:https://www.cnblogs.com/llguanli/p/6760325.html
Copyright © 2011-2022 走看看