• OpenCV图像轮廓检测


    轮廓检测:

    轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点。那么就可以将中间的那一点去掉。

    一.关键函数
    1.1  cvFindContours
    函数功能:对图像进行轮廓检测,这个函数将生成一条链表以保存检测出的各个轮廓信息,并传出指向这条链表表头的指针。
    函数原型:
    int cvFindContours(
      CvArr* image,                              第一个参数表示输入图像,必须为一个8位的二值图像
      CvMemStorage* storage,            第二参数表示存储轮廓的容器。为CvMemStorage类型,定义在OpenCV的core ypes_c.h中
      CvSeq** first_contour,             第三个参数为输出参数,这个参数将指向用来存储轮廓信息的链表表头 

      int header_size=sizeof(CvContour),     第四个参数表示存储轮廓链表的表头大小,当第六个参数传入CV_CHAIN_CODE时,
                                                                        要设置成sizeof(CvChain),其它情况统一设置成sizeof(CvContour)。

      int mode=    CV_RETR_LIST,                  第五个参数为轮廓检测的模式,有如下取值:
          CV_RETR_EXTERNAL :     只检索最外面的轮廓;
                            CV_RETR_LIST:                   检索所有的轮廓,并将其保存到一条链表当中;
                            CV_RETR_CCOMP:             检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
                            CV_RETR_TREE:                 检索所有的轮廓,并重构嵌套轮廓的整个层次;

      int method=   CV_CHAIN_APPROX_SIMPLE,              第六个参数用来表示轮廓边缘的近似方法的,常用值如下所示:
                              CV_CHAIN_CODE:                                 以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
                              CV_CHAIN_APPROX_SIMPLE:           压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。

      CvPoint offset=cvPoint(0,0)                       第七个参数表示偏移量,比如你要从图像的(100, 0)开始进行轮廓检测,那么就传入(100, 0)。

    );

    --->使用cvFindContours函数能检测出图像的轮廓,将轮廓绘制出来则需要另一函数——cvDrawContours来配合了。下面介绍cvDrawContours函数。

    1.2  cvDrawContours
    函数功能:在图像上绘制外部和内部轮廓

    函数原型:
    void cvDrawContours(
      CvArr *img,                              第一个参数表示输入图像,函数将在这张图像上绘制轮廓。
      CvSeq* contour,                       第二个参数表示指向轮廓链表的指针
      CvScalar external_color,
      CvScalar hole_color,                第三个参数和第四个参数表示颜色,绘制时会根据轮廓的层次来交替使用这二种颜色
      int max_level,                           第五个参数表示绘制轮廓的最大层数,如果是0,只绘制contour;如果是1,追加绘制和
                                                         contour同层的所有轮廓;如果是2,追加绘制比contour低一层的轮廓,以此类推;如果

                                                        值是负值,则函数并不绘制contour后的轮廓,但是将画出其子轮廓,一直到abs(max_level) - 1层。


      int thickness=1,                       第六个参数表示轮廓线的宽度,如果为CV_FILLED则会填充轮廓内部
      int line_type=8,                       第七个参数表示轮廓线的类型。
      CvPoint offset=cvPoint(0,0)  第八个参数表示偏移量,如果传入(10,20),那绘制将从图像的(10,20)处开始
    );

    // ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "iostream"
    using namespace std;
    #include "opencv2/opencv.hpp"
    
    const char *pImagePath = "E:/C_VC_code/Text_Photo/girl005.jpg";
    const char *pWindowsTitle = "原图";
    const char *pWindowsGrayTitle = "灰度图";
    const char *pWindowsBinaryTitle = "二值图";
    const char *pWindowsOutLineTitle = "轮廓图";
    const char *pWindowsToolBar = "阀值";
    IplImage *pImage=NULL,*pGrayImage, *pBinaryImage, *pOutLineImage;
    CvMemStorage *pMemStorage;
    CvSeq *pSeq;
    int nLevels = 3;
    void functionCallback(int pos)
    {
        cvThreshold(pGrayImage, pBinaryImage, pos, 255, CV_THRESH_BINARY);
        cvFindContours(pBinaryImage, pMemStorage, &pSeq ,sizeof(CvContour), CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
        cvDrawContours(pOutLineImage, pSeq, CV_RGB(0,255,255), CV_RGB(255,0,0), nLevels, 2, 2);
        cvShowImage(pWindowsBinaryTitle, pBinaryImage);
        cvShowImage(pWindowsOutLineTitle, pOutLineImage);
    }
    void main()
    {
        
        //SourceImage turn to GrayImage
        
        pImage = cvLoadImage(pImagePath, CV_LOAD_IMAGE_UNCHANGED);
    
        pGrayImage = cvCreateImage(cvGetSize(pImage), IPL_DEPTH_8U, 1);
        cvCvtColor(pImage, pGrayImage, CV_BGR2GRAY);
    
        //create window
        cvNamedWindow(pWindowsTitle, CV_WINDOW_AUTOSIZE);
        cvNamedWindow(pWindowsGrayTitle, CV_WINDOW_AUTOSIZE);
        cvNamedWindow(pWindowsBinaryTitle, CV_WINDOW_AUTOSIZE);
        cvNamedWindow(pWindowsOutLineTitle, CV_WINDOW_AUTOSIZE);
    
        //为二值图创建滑动条
        int nPos = 0;
        cvCreateTrackbar(pWindowsToolBar,pWindowsBinaryTitle,&nPos,100,functionCallback);
    
        //GrayImage turn into BinaryImage
        pBinaryImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);
    
        //检索轮廓并返回检测到的轮廓的个数
        pMemStorage = cvCreateMemStorage();
        pSeq = NULL;
        
        //Create and show OutLineImage
        pOutLineImage = cvCreateImage(cvGetSize(pBinaryImage), IPL_DEPTH_8U, 3);
        
        //填充成白色
        cvRectangle(pOutLineImage, cvPoint(0,0),cvPoint(pImage->width,pImage->height), CV_RGB(255,255,255), CV_FILLED);
        cvDrawContours(pOutLineImage, pSeq, CV_RGB(0,255,255), CV_RGB(255,0,0), nLevels, 2);
    
    
        cvShowImage(pWindowsTitle, pImage);
        cvShowImage(pWindowsGrayTitle, pGrayImage);
        cvShowImage(pWindowsBinaryTitle, pBinaryImage);
        cvShowImage(pWindowsOutLineTitle, pOutLineImage);
    
        functionCallback(100);
    
        //destroy object and release space
        cvWaitKey(0);
        cvDestroyWindow(pWindowsTitle);
        cvDestroyWindow(pWindowsGrayTitle);
        cvDestroyWindow(pWindowsBinaryTitle);
        cvDestroyWindow(pWindowsOutLineTitle);
        cvReleaseImage(&pImage);
        cvReleaseImage(&pGrayImage);
        cvReleaseImage(&pBinaryImage);
        cvReleaseImage(&pOutLineImage);
    
    }

  • 相关阅读:
    EasyUI
    intellij idea打包maven项目
    struts2框架详解
    java电子书
    查看mysql安装路径
    springboot 集成 vue
    C#中的属性
    C#中的时间戳
    int.TryParse非预期执行引发的思考
    IQueryable 和 IEnumerable 的区别
  • 原文地址:https://www.cnblogs.com/mypsq/p/4984731.html
Copyright © 2020-2023  润新知