zoukankan      html  css  js  c++  java
  • 《学习openCV》例程解析 ex_8_3 (轮廓)

    /*

    效果图:


    我本人感觉例程有误,下面是修改后的英文(如:max_level)和例程,
    运行时按住除ESC 键以外任意一个按键,可观察到轮廓从下往上的顺序
    依次画出。外部轮廓为红色,内部轮廓为蓝色。

    */

    /**
    In this example, we find contours on an input image and then proceed to draw them 
    one by one. This is a good example to play with yourself and see what effects result from 
    changing either the contour finding mode (CV_RETR_LIST in the code) or the max_level 
    that is used to draw the contours (0 in the code). If you set max_level to a larger number, 
    notice that the example code steps through the contours returned by cvFindContours() 
    by   means   of  h_next.   Thus,  for  some   topologies   (CV_RETR_TREE, CV_RETR_CCOMP,  etc.),   you 
    may see the same contour more than once as you step through. See Example 8-3. 
    
    Example 8-3. Finding and drawing contours on an input image 
    */
    
    
    #include "stdafx.h"
    #include "cv.h"
    #include "highgui.h"
    #include "stdio.h"
    
    #define CVX_RED CV_RGB(0xff, 0x00, 0x00)
    #define CVX_GREEN CV_RGB(0x00, 0xff, 0x00)
    #define CVX_BLUE CV_RGB(0x00, 0x00, 0xff)
    
    int main()
    {
    	IplImage* img_8uc1 = NULL;
    	cvNamedWindow("img_contour", CV_WINDOW_AUTOSIZE);
    
    	if (img_8uc1 = cvLoadImage("lena.jpg", 0))		
    		//CV_LOAD_IMAGE_GRAYSCALE == 0 加载lena.jpg 灰度图
    	{
    		IplImage* img_edge = cvCreateImage(cvGetSize(img_8uc1), 8, 1);
    		IplImage* img_8uc3 = cvCreateImage(cvGetSize(img_8uc1), 8, 3);
    
    		cvThreshold(img_8uc1, img_edge, 128, 255, CV_THRESH_BINARY);
    		//对灰度图img_8uc1 像进行阈值操作得到二值图像 img_edge
    
    		CvMemStorage* storage = cvCreateMemStorage();
    		//创建一个内存储存器 默认为 64K
    
    		CvSeq* first_contour = NULL;
    		//创建一个动态序列指针,用其指向第一个存储轮廓单元地址
    
    		int NC = cvFindContours(	
    			//cvFindContours从二值图像中检索轮廓,并返回检测到的轮廓的个数
    			img_edge,		
    			storage,				//存储轮廓元素的储存容器
    			&first_contour,			//指向第一个输出轮廓
    			sizeof (CvContour),		
    			CV_RETR_LIST			//提取所有轮廓,并且放置在 list 中
    			);
    		
    		printf("Total Contours Detected: %d\n", NC);
    
    		cvCvtColor(img_8uc1, img_8uc3, CV_GRAY2BGR);
    		//色彩空间转换,将img_8uc1 转换为BGR空间,img_8uc3 为转换后结果
    		
    		int n = 0;
    		//用于下面轮廓的记数
    		for (CvSeq* c=first_contour; c!=NULL; c = c->h_next)
    		{	//从第一个轮廓开始遍历,直到所有轮廓都遍历结束
    			cvDrawContours(
    				img_8uc3,	//用于绘制轮廓的图像
    				c,			//指向目前轮廓所在地址空间
    				CVX_RED,	//外层轮廓颜色
    				CVX_BLUE,	//内层轮廓颜色
    				0,			//等级为0,绘制单独的轮廓
    				1,			//轮廓线条粗细
    				8			//线段类型为(8邻接)连接线
    				);
    
    			printf("Contour #%d\n", n);
    			//输出第 n 个轮廓
    
    			cvShowImage("img_contour", img_8uc3);
    			//显示目前已绘制的轮廓图像
    
    			printf("%d elements:\n", c->total);
    			//输出构成目前轮廓点的个数
    
    			for (int i=0; i<c->total; i++)
    			{
    				CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, c, i);
    				//查找轮廓序列中索引所指定的点,并返回指向该点的指针
    				printf("  (%d, %d)\n", p->x, p->y);
    				//输出该点坐标
    			}
    			
    			if (cvWaitKey() == 27)		
    				//按下ESC 键退出循环
    				break;
    			n++;
    		}
    		printf("Finished all contours. Hit ESC to finish\n");
    
    		while (cvWaitKey() != 27);
    		
    		cvReleaseImage(&img_edge);
    		cvReleaseImage(&img_8uc3);
    	}
    	cvDestroyWindow("img_contour");
    	cvReleaseImage(&img_8uc1);
    	return 0;
    }


  • 相关阅读:
    java 可伸缩阻塞队列实现
    java mysql大数据量批量插入与流式读取分析
    innodb next-key lock引发的死锁
    jremoting的功能扩展点
    java开源项目jremoting
    Linux下搭建gtk+2.0开发环境
    《程序员的办公室日常》第二回 拜师
    《程序员的办公室日常》第一回 相识
    【限时免费】近1000G JAVA学习视频下载
    裁员之后,我才明白它的重要性
  • 原文地址:https://www.cnblogs.com/zcube/p/4196446.html
Copyright © 2011-2022 走看看