效果图:
/** 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; }