《学习openCV》例程解析 ex_8_2 (轮廓)

例:根据滑动条参数检测轮廓,在滑动条变化时候重新检测

效果图:

/**
  Our Example 8-2 is drawn from the OpenCV package. Here we create a window with an 
image in it. A trackbar sets a simple threshold, and the contours in the thresholded im-
age are drawn. The image is updated whenever the trackbar is adjusted.
Example 8-2. Finding contours based on a trackbar’s location; the contours are updated whenever 
the trackbar is moved                                                                     
*/


#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

IplImage* g_img = NULL;
IplImage* g_gray = NULL;
int g_thresh = 100;
CvMemStorage* g_storage = NULL;			//内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等
										//动态增长数据结构的底层结构。

void on_trackbar(int pos)
{
	if (g_storage == NULL)
	{
		g_gray = cvCreateImage(cvGetSize(g_img), 8, 1);
		g_storage = cvCreateMemStorage();//创建内存块默认值为64K
	}
	else
	{
		cvClearMemStorage(g_storage);	//清除储存块内容,并不释放内存
	}
	
	cvCvtColor(g_img, g_gray, CV_BGR2GRAY);
	//色彩空间转换, BGR到GRAY
	cvThreshold(g_gray, g_gray, g_thresh, 255, CV_THRESH_BINARY);
	//对数组元素进行固定阈值操作
	//该函数的典型应用是对灰度图像进行阈值操作得到二值图像。

	CvSeq* contours = 0;
	//可动态增长元素序列
	cvFindContours(						//在二值图像中寻找轮廓 
		g_gray,							//输入二值图像
		g_storage,						//得到的轮廓的存储容器 
		&contours						//指向第一个轮廓的指针
		);
	//coutours序列指针指向储存在g_storage 内存块中的轮廓

	cvZero(g_gray);						//等于cvSetZero,清空图像
	if (contours)						//如果序列非空
	{
		cvDrawContours(					//在图像中绘制外部和内部的轮廓
			g_gray,
			contours,					//指针指向第一个轮廓
			cvScalarAll(255),			//g_gray 为单通道颜色,只有一种颜色
			cvScalarAll(255),			//赋为白色
			100							//绘制轮廓的最大等级,如果为0 单独绘制轮廓
			);
		cvShowImage("Contours", g_gray);
	}
}

int main()
{	
	cvNamedWindow("g_img", CV_WINDOW_AUTOSIZE);
	g_img = cvLoadImage("lena.jpg");
	cvShowImage("g_img", g_img);

	cvNamedWindow("Contours", CV_WINDOW_AUTOSIZE);

	cvCreateTrackbar(
				 "Threshold",		//滑块名字
				 "Contours",		//滑块所在窗口名字
				 &g_thresh,			//指定创建时的滑块位置
				 255,				//滑块位置的最大值
				 on_trackbar		//每次滑块位置被改变的时候,被调用函数的指针。
									//这个函数应该被声明为void Foo(int); 
									//如果没有回调函数,这个值可以设为NULL。 
				 );

	on_trackbar(0);					//初始先调用一次,否者滑块变动时才显示
	cvWaitKey();

	cvDestroyAllWindows();
	cvReleaseImage(&g_img);
	cvReleaseImage(&g_gray);
	return 0;
}

(2) 效果图


改进单独加颜色绘制轮廓

/**
	扩展8_2使每个轮廓都随机颜色                                                               
*/


#include "stdafx.h"
#include "cv.h"
#include "highgui.h"

IplImage* g_img = NULL;
IplImage* g_gray = NULL;
int g_thresh = 100;
CvMemStorage* g_storage = NULL;			//内存存储器是一个可用来存储诸如序列,轮廓,图形,子划分等
										//动态增长数据结构的底层结构。

void on_trackbar(int pos)
{
	if (g_storage == NULL)
	{
		g_gray = cvCreateImage(cvGetSize(g_img), 8, 1);
		g_storage = cvCreateMemStorage();//创建内存块默认值为64K
	}
	else
	{
		cvClearMemStorage(g_storage);	//清除储存块内容,并不释放内存
	}
	
	cvCvtColor(g_img, g_gray, CV_BGR2GRAY);
	//色彩空间转换, BGR到GRAY
	cvThreshold(g_gray, g_gray, g_thresh, 255, CV_THRESH_BINARY);
	//对数组元素进行固定阈值操作
	//该函数的典型应用是对灰度图像进行阈值操作得到二值图像。

	CvSeq* contours = 0;
	//可动态增长元素序列
	cvFindContours(						//在二值图像中寻找轮廓 
		g_gray,							//输入二值图像
		g_storage,						//得到的轮廓的存储容器 
		&contours						//指向第一个轮廓的指针
		);
	//coutours序列指针指向储存在g_storage 内存块中的轮廓

	cvZero(g_gray);						//等于cvSetZero,清空图像

	IplImage* g_temp = cvCreateImage(cvGetSize(g_gray), 8, 3);
	//创建一个3通道图像,显示有颜色的轮廓
	cvZero(g_temp);						

	for(; contours != 0; contours = contours->h_next)
	{
		//因为要单独绘制轮廓,所以得用循环
		CvScalar color = CV_RGB(rand()&255, rand()&255, rand()&255);
		//随机取色
		cvDrawContours(					//在图像中绘制外部和内部的轮廓
			g_temp,
			contours,					//指针指向第一个轮廓
			color,
			color,
			0							//单独绘制轮廓
			);
	}
	cvShowImage("Contours", g_temp);
}

int main()
{	
	cvNamedWindow("g_img", CV_WINDOW_AUTOSIZE);
	g_img = cvLoadImage("lena.jpg");
	cvShowImage("g_img", g_img);

	cvNamedWindow("Contours", CV_WINDOW_AUTOSIZE);

	cvCreateTrackbar(
				 "Threshold",		//滑块名字
				 "Contours",		//滑块所在窗口名字
				 &g_thresh,			//指定创建时的滑块位置
				 255,				//滑块位置的最大值
				 on_trackbar		//每次滑块位置被改变的时候,被调用函数的指针。
									//这个函数应该被声明为void Foo(int); 
									//如果没有回调函数,这个值可以设为NULL。 
				 );

	on_trackbar(0);					//初始先调用一次,否者滑块变动时才显示
	cvWaitKey();

	cvDestroyAllWindows();
	cvReleaseImage(&g_img);
	cvReleaseImage(&g_gray);
	return 0;
}


原文地址:https://www.cnblogs.com/zcube/p/4196447.html