zoukankan      html  css  js  c++  java
  • OopenCV复习及函数深入理解(轮廓查询及绘图)

    核心函数:(后面标明号的,下面有解析)
    int cvFindContours(
    Iplimage* img,//这是输入函数,必须是8bit,单通道的图像---1
    CvMemStorage* storage,// 已分配的内存,用来存这个函数所搜索到的轮廓 ---2
    CvSeq** firstContour,//此处的指针不需要自己分配,只需在外面定义一个该类型的指针即可--3
    int headerSize=sizeof(CvContour),//--4
    CvContourRetrievalMode mode= CV_RETR_LIST,//--4
    CvChainApproxMethod method=CV_CHAI_APPROX_SIMPLE//--4
    CvPoint offset=cvPoint(0,0) //设置查询起点
    );
    //本函数的返回值是找到的轮廓(contour)的个数(total);
    Notice:这个函数在图像上搜索的时候,会更改图像(因为计算图像需要) ,
    所以 如果还要把这个图像用到其他地方,最后做一个复制本传递到这个函数里面处理。

    1--Iplimage* img=cvCreateImage(CvSize(),8,1);
    中间参数 代表八位,最后的1代表单通道。

    2--CvMemStorage* storage=CvCreateStorage(int storageSize); 默认为0,分配64kb空间

    MemStorage基础知识补充:
    它是为动态对象处理内存的。它是允许快速分配和销毁内存。
    CvMemStorage* cvCreateMemStorage(int blocksize=0);
    void cvReleaseMemStorage(CvMemStorage* storage);//销毁释放内存, 不可再次使用
    void cvClearMemStorage(CvmemStorage* storage); //清空内存,可以再次使用
    void cvMemStorageAlloc(CvMemStorage* storage,size_t size) ;//分配指定大小内存

    3--CvSeq* pointer=NULL;将这个指针传入函数,然后函数会自动分配内存并将所找到的序列的头给这个指针
    将&pointer传入函数(因为函数中是CvSeq** 类型)


    4--这几个默认参数一般不许设置,他们是为了告诉函数更多的信息
    headersize是为了告诉参数应该分配个firstcontour指针的元素类型
    后面的mode和method参数是为了告诉函数应该怎样计算,主要是和headersize进行配合
    可以能够更精确的返回自己所需要的值


    mode可以被设置成任何下列四个选项中的任何一个:
    CV_RETR_EXTERNAL
    CV_RETR_LIST
    CV_RETR_CCOMP
    CV_RETR_TREE
    这四个值主要是指明:
    1--我们所需要的找到的轮廓(contour)
    2--返回结果应该呈现结果的方式


    method可以被设置成下面五个中的任何一个:
    CV_CHAIN_CODE
    CV_CHAIN_APPROX_NONE
    CV_CHAIN_APPROX_SIMPLE
    CV_CHAIN_APPROX_TC89_L1 或 CV_CHAIN_APPROX_TC89_KCOS
    CV_LINK_RUNS
    这些是告诉函数的算法方式 ,只支持mode中的CV_RETR_TREE方法
    以下两个是CvSeq里面的四个指针 ,如同我们自己写的链表一样使用就行
    horizontal links(横向链表连接指针):h_pre(指向上一个元素),h_next(指向下一个元素)
    vertical links(垂直链表链接指针) :v_pre(指向上一个元素),v_next(指向下一个元素)

    cvFindContours()查找出来的轮廓序列 是一个个的点,确切的说是轮廓。
    理解轮廓的关键是轮廓是一种特殊的序列。
    它们是一系列的点呈现出图像中的曲线 。
    下面是一些操作这些序列的函数:

    CvContourScanner cvStartFindContours(
    CvArr* image,
    CvMemStorage* storage,
    int header_size=sizeof(CvContour),
    int mode=CV_RETR_LIST,
    int method=CV_CHAIN_APPROX_SIMPLE
    ) ;
    //它返回CvContourScanner

    CvSeq *cvFindNextContour(
    CvContourScanner scanner
    ) ;
    //能够把scanner里面的所有轮廓读取出来,当返回NULL时说明无轮廓在里面


    void cvSubstitute(
    CvContourScanner scanner,
    CvSeq* new_contour);
    //能够将scanner 里面的contours替换掉

    CvSeq* cvEndFindContour(
    CvContourScanner* scanner);
    //关闭scanner,返回值是这个序列的第一个元素的地址

    CvSeq* cvApproxChains(
    CvSeq* cvApproxChains,
    CvMemStorage* storage,
    int method=CV_CHIAN_APPROX_SIMPLE,
    double parameter=0,
    int minimal_permeter=0,
    int recursive=0
    );//此函数涉及freechain


    ///////////////////////////////////////////////////////
    //图像中影响轮廓查询后应当要做的是在屏幕上呈现轮廓形状
    void cvDrawContours(
    CvArr* img,//这个图像要呈现轮廓形状 ,即在这个图象上画图
    CvSeq* contour,//the root node of contour tree(unclear)
    CvScalar external_color,
    CvScalar hole_color, //@
    int max_level, //
    int thickness=1,//划线的厚度
    int line_type=8,// 线的类型,具体百度
    CvPoint offset=cvPoint(0,0)//还未涉及,表示不理解,以后修改
    ) ;

    Explaination:

    @:-->OpenCV distinguishes between contours that are exterior contours
    and those are hole contours就是指的外轮廓内的非常小的轮廓,然后成为一个点了。就是为它们设定颜色。

     1 #include“highgui.h"
     2 #include"cv.h"
     3 using namespace cv;
     4 int main()
     5 {
     6     cvNamedWindow("Contour", 1);
     7     
     8     
     9     IplImage* img = cvLoadImage("h:\picture\tree.jpg",CV_LOAD_IMAGE_GRAYSCALE);
    10     IplImage* img_8uc1 = cvCreateImage(cvSize(300, 400), 8, 1);
    11     cvResize(img,img_8uc1);
    12     IplImage* img_edge = cvCreateImage(cvGetSize(img_8uc1),8,1);
    13 
    14     IplImage* img_8uc3 = cvCreateImage(cvGetSize(img_8uc1),8,3);
    15     cvThreshold(img_8uc1,img_edge,100,255,CV_THRESH_BINARY);
    16     CvMemStorage* storage = cvCreateMemStorage(0);
    17     CvSeq* firstcontour = NULL;
    18     int Nc = cvFindContours(img_edge,storage,&firstcontour,sizeof(CvContour),CV_RETR_LIST);
    19     int n = 0;
    20     printf("Total Contours Detected:%d
    ",Nc);
    21     
    22     for (CvSeq* c = firstcontour; c != NULL; c = c->h_next)
    23     {
    24         cvCvtColor(img_8uc1, img_8uc3, CV_GRAY2BGR);
    25         cvDrawContours(img_8uc3,c,cvScalar(200,100,50),cvScalarAll(255),256,2,8);
    26         printf("Contour#%d
    ",n);
    27         cvShowImage("Contour",img_8uc3);
    28         printf("%d elements:
    ", c->total);
    29         for (int i = 0; i < c->total; i++)
    30         {
    31             CvPoint* p = CV_GET_SEQ_ELEM(CvPoint,c,i);
    32             printf("  (%d, %d)
    ", p->x, p->y);
    33         }
    34         cvWaitKey(100);
    35         n++;
    36     }
    37     cvWaitKey(0);
    38     printf("Finished All contours.
    ");
    39     cvCvtColor(img_8uc1,img_8uc3,CV_GRAY2BGR);
    40     cvShowImage("Contour",img_8uc3);
    41     cvWaitKey();
    42     return 0;
    43 }

    执行结果:

     1  #include"highgui.h"
     2 #include"cv.h"
     3 using namespace cv;
     4 IplImage* g_image=NULL;
     5 IplImage* g_gray = NULL;
     6 int g_thresh = 100;
     7 CvMemStorage *g_storage = NULL;
     8 void on_trackbar(int)
     9 {
    10     if (g_storage == NULL)
    11     {
    12         g_storage = cvCreateMemStorage(0);
    13         g_gray = cvCreateImage(cvGetSize(g_image),8,1);
    14     }
    15     else
    16     {
    17         cvClearMemStorage(g_storage);
    18     }
    19     CvSeq* contours = 0;//置为空
    20     cvCvtColor(g_image,g_gray,CV_BGR2GRAY);
    21     cvThreshold(g_gray,g_gray,g_thresh,255,CV_THRESH_BINARY);
    22     cvFindContours(g_gray,g_storage,&contours);
    23     cvZero(g_gray);
    24     if (contours)
    25     {
    26         cvDrawContours(g_gray,contours,cvScalarAll(255),cvScalarAll(255),100);
    27         
    28     }
    29     cvShowImage("Contours",g_gray);
    30 }
    31 int main()
    32 {
    33     IplImage* g = cvLoadImage("h:\picture\tree.jpg");
    34     CvSize size= cvGetSize(g);
    35     CvSize sz = cvSize(size.width/5,size.height/5);
    36     g_image = cvCreateImage(sz,8,g->nChannels);
    37     cvResize(g,g_image);
    38     
    39     
    40     //if (g_image == NULL)
    41     cvNamedWindow("Contours",1);
    42     //cvCreateTrackbar("Threshod","Contours",&g_thresh,255,on_trackbar);
    43     on_trackbar(0);
    44     cvWaitKey(0);
    45     return 0; 
    46 }
    47 
    48  

    执行结果:

  • 相关阅读:
    HBase 高性能加入数据
    Please do not register multiple Pages in undefined.js 小程序报错的几种解决方案
    小程序跳转时传多个参数及获取
    vue项目 调用百度地图 BMap is not defined
    vue生命周期小笔记
    解决小程序背景图片在真机上不能查看的问题
    vue项目 菜单侧边栏随着右侧内容盒子的高度实时变化
    vue项目 一行js代码搞定点击图片放大缩小
    微信小程序进行地图导航使用地图功能
    小程序报错Do not have xx handler in current page的解决方法
  • 原文地址:https://www.cnblogs.com/sytu/p/4131754.html
Copyright © 2011-2022 走看看