zoukankan      html  css  js  c++  java
  • 【OpenCV函数】轮廓提取;轮廓绘制;轮廓面积;外接矩形

    FindContours

    在二值图像中寻找轮廓
    int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour,
    int header_size=sizeof(CvContour), int mode=CV_RETR_LIST,
    int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) );

    • image  输入的 8-比特、单通道图像. 非零元素被当成 1, 0 象素值保留为 0 - 从而图像被看成二值的。为了从灰度图像中得到这样的二值图像,可以使用 cvThreshold, cvAdaptiveThreshold 或 cvCanny. 本函数改变输入图像内容。
    • storage  得到的轮廓的存储容器
    • first_contour  输出参数:包含第一个输出轮廓的指针
    • header_size   如果 method=CV_CHAIN_CODE,则序列头的大小 >=sizeof(CvChain),否则 >=sizeof(CvContour) .
    • mode  提取模式.
      CV_RETR_EXTERNAL - 只提取最外层的轮廓
      CV_RETR_LIST - 提取所有轮廓,并且放置在 list 中
      CV_RETR_CCOMP - 提取所有轮廓,并且将其组织为两层的 hierarchy: 顶层为连通域的外围边界,次层为洞的内层边界。
      CV_RETR_TREE - 提取所有轮廓,并且重构嵌套轮廓的全部 hierarchy
    • method  逼近方法 (对所有节点, 不包括使用内部逼近的 CV_RETR_RUNS).
      CV_CHAIN_CODE - Freeman 链码的输出轮廓. 其它方法输出多边形(定点序列).
      CV_CHAIN_APPROX_NONE - 将所有点由链码形式翻译(转化)为点序列形式
      CV_CHAIN_APPROX_SIMPLE - 压缩水平、垂直和对角分割,即函数只保留末端的象素点;
      CV_CHAIN_APPROX_TC89_L1,
      CV_CHAIN_APPROX_TC89_KCOS - 应用 Teh-Chin 链逼近算法. CV_LINK_RUNS - 通过连接为 1 的水平碎片使用完全不同的轮廓提取算法。仅有 CV_RETR_LIST 提取模式可以在本方法中应用.
    • offset  每一个轮廓点的偏移量. 当轮廓是从图像 ROI 中提取出来的时候,使用偏移量有用,因为可以从整个图像上下文来对轮廓做分析.


    函数 cvFindContours 从二值图像中提取轮廓,并且返回提取轮廓的数目。指针 first_contour 的内容由函数填写。它包含第一个最外层轮廓的指针,如果指针为 NULL,则没有检测到轮廓(比如图像是全黑的)。其它轮廓可以从 first_contour 利用 h_next 和 v_next 链接访问到。 在 cvDrawContours 的样例显示如何使用轮廓来进行连通域的检测。轮廓也可以用来做形状分析和对象识别 - 见CVPR2001 教程中的 squares 样例。该教程可以在 SourceForge 网站上找到。


    DrawContours

    在图像中绘制外部和内部的轮廓。 
    
    void 
    cvDrawContours
    ( CvArr *img, CvSeq* contour,
                         CvScalar external_color, CvScalar hole_color,
                         int max_level, int thickness=1,
                         int line_type=8, CvPoint offset=cvPoint(0,0) );
    • img 用以绘制轮廓的图像。和其他绘图函数一样,边界图像被感兴趣区域(ROI)所剪切。
    • contour 指针指向第一个轮廓。 external_color 外层轮廓的颜色。
    • hole_color 内层轮廓的颜色。
    • max_level 绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。
    • thickness 绘制轮廓时所使用的线条的粗细度。如果值为负(e.g. =CV_FILLED),绘制内层轮廓。
    • line_type 线条的类型。参考cvLine.
    • offset 按照给出的偏移量移动每一个轮廓点坐标.当轮廓是从某些感兴趣区域(ROI)中提取的然后需要在运算中考虑ROI偏移量时,将会用到这个参数。

    当thickness>=0,函数cvDrawContours在图像中绘制轮廓,或者当thickness<0时,填充轮廓所限制的区域。

    #include "cv.h"
    #include "highgui.h"
    
    int main( int argc, char** argv )
    {
        IplImage* src;
        // 第一条命令行参数确定了图像的文件名。
        if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
        {
            IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
            CvMemStorage* storage = cvCreateMemStorage(0);
            CvSeq* contour = 0;
    
            cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );
            cvNamedWindow( "Source", 1 );
            cvShowImage( "Source", src );
    
            cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
            cvZero( dst );
    
            for( ; contour != 0; contour = contour->h_next )
            {
                CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
                /* 用1替代 CV_FILLED  所指示的轮廓外形 */
                cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );
            }
    
            cvNamedWindow( "Components", 1 );
            cvShowImage( "Components", dst );
            cvWaitKey(0);
        }
    }

    在样本中用1替代 CV_FILLED 以指示的得到外形。


    ContourArea

    double cvContourArea( const CvArr* contour, CvSliceslice=CV_WHOLE_SEQ );

    • contour:轮廓(顶点的序列或数组)。
    • slice:感兴趣区轮廓部分的起点和终点,默认计算整个轮廓的面积。

    函数cvContourArea计算整个或部分轮廓的面积。在计算部分轮廓的情况时,由轮廓弧线和连接两端点的弦
    围成的区域总面积被计算,如下图所示:

    cvContourArea

    NOTE:

    轮廓的位置将影响区域面积的符号,因此函数范围的有可能是负值。可以使用C运行时函数fabs()来
    得到面积的绝对值。

    e.g. double area = fabs(cvContourArea(contour));


    BoundingRect

    计算点集的最外面(up-right)矩形边界
    CvRect cvBoundingRect( CvArr* points, int update=0 );

    • points
      二维点集,点的序列或向量 (CvMat)
    • update
      更新标识。下面是轮廓类型和标识的一些可能组合:
      update=0, contour ~ CvContour*: 不计算矩形边界,但直接由轮廓头的 rect 域得到。
      update=1, contour ~ CvContour*: 计算矩形边界,而且将结果写入到轮廓头的 rect 域中 header.
      update=0, contour ~ CvSeq* or CvMat*: 计算并返回边界矩形
      update=1, contour ~ CvSeq* or CvMat*: 产生运行错误 (runtime error is raised)

    函数 cvBoundingRect 返回二维点集的最外面 (up-right)矩形边界。

  • 相关阅读:
    Chandy-Lamport_algorithm
    3 differences between Savepoints and Checkpoints in Apache Flink
    列数 行数 表数 限制
    数据收集、传输、元数据管理、作业流调度、海量数据查询引擎、数据可视化
    分析云负载均衡产品
    端口被占用通过域名的处理 把www.domain.com均衡到本机不同的端口 反向代理 隐藏端口 Nginx做非80端口转发 搭建nginx反向代理用做内网域名转发 location 规则
    JSON Web Token
    查看开启端口的应用
    If the parts of an organization (e.g., teams, departments, or subdivisions) do not closely reflect the essential parts of the product, or if the relationship between organizations do not reflect the r
    微服务架构的理论基础
  • 原文地址:https://www.cnblogs.com/KC-Mei/p/4324142.html
Copyright © 2011-2022 走看看