【练习5.11】图像分割、cvPyrSegmentagtion、图像金字塔
题目要求 |
程序代码 |
结果图片 |
要言妙道 |
载入一张风景图,执行cvPyrSegmentation操作
a、threshold1=threshold2=200
b、threshold1=200,threshold2=50
c、threshold1=200,threshold2=100
1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。 2 // 3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg 4 5 6 #include "stdafx.h" 7 #include <cv.h> 8 #include <highgui.h> 9 #include <iostream> 10 11 #include <opencv2/legacy/legacy.hpp> 12 //#pragma comment(lib, "opencv_legacy2411.lib") 13 14 using namespace cv; 15 using namespace std; 16 17 //函数声明-->--->-->--->-->--->-->--->// 18 19 bool IsCanBeUsedForImagePyramid(IplImage * img, uint32_t layerCount, int PyrType = 0); 20 21 //<--<--<--<--<--<--<--<--<--函数声明// 22 23 24 int _tmain(int argc, _TCHAR* argv[]) 25 { 26 const char * soutceFile = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第5章\\雪屋.jpg"; 27 IplImage * image_Resource = cvLoadImage(soutceFile, CV_LOAD_IMAGE_UNCHANGED); 28 assert(image_Resource); 29 30 cvNamedWindow("原始图像", 0); 31 cvNamedWindow("题目_a", 0); 32 cvNamedWindow("题目_b", 0); 33 cvNamedWindow("题目_c", 0); 34 35 IplImage * image_Gray = cvCreateImage(cvSize(image_Resource->width, image_Resource->height), IPL_DEPTH_8U, 1); 36 37 //使用cvCvtColor和cvCopy这些函数前,都应该对参数进行验证再使用 38 if (image_Resource->nChannels != 3) 39 { 40 cout << "加载的图像必须为彩色图片" << endl; 41 return 0; 42 } 43 44 cvCvtColor(image_Resource, image_Gray, CV_RGB2GRAY); 45 46 cvShowImage("原始图像", image_Gray); 47 48 //---------------------------a:开始--------------------------------// 49 50 //●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●/: 51 //这次见证了这个函数的重要性,一个4912×2760的图片,很大,但是只适合≤三层的金字塔处理,到第四层已经不是偶数 52 //如果并使用IsCanBeUsedForImagePyramid验证图片可用性,后面将在“cvPyrSegmentation”函数处报错 53 //遇到调用OpenCV函数报错的时候,就去看官方说明或《学习OpenCV》或中文文档等全文文档的说明,一定是对函数调用有什么条件限制 54 //●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●/。 55 bool isTheImageCanUse = IsCanBeUsedForImagePyramid(image_Gray, 4); 56 if (isTheImageCanUse == false) 57 { 58 cout << "图片不可用" << endl; 59 return 0; 60 } 61 62 IplImage * image_Result_a = cvCloneImage(image_Gray); 63 cvZero(image_Result_a); 64 65 CvMemStorage * storage = cvCreateMemStorage(0); 66 CvSeq *comp = NULL; 67 cvPyrSegmentation(image_Gray, image_Result_a, storage, &comp,1, 200, 200); 68 69 cvShowImage("题目_a", image_Result_a); 70 71 //---------------------------a:结束--------------------------------// 72 73 //---------------------------b:开始--------------------------------// 74 75 IplImage * image_Result_b = cvCloneImage(image_Gray); 76 cvZero(image_Result_b); 77 78 storage = cvCreateMemStorage(0); 79 comp = NULL; 80 cvPyrSegmentation(image_Gray, image_Result_b, storage, &comp, 1, 200, 50); 81 82 cvShowImage("题目_b", image_Result_b); 83 84 //---------------------------b:结束--------------------------------// 85 86 //---------------------------c:开始--------------------------------// 87 88 IplImage * image_Result_c = cvCloneImage(image_Gray); 89 cvZero(image_Result_c); 90 91 storage = cvCreateMemStorage(0); 92 comp = NULL; 93 cvPyrSegmentation(image_Gray, image_Result_c, storage, &comp, 1, 200, 100); 94 95 cvShowImage("题目_c", image_Result_c); 96 97 //---------------------------c:结束--------------------------------// 98 99 cvWaitKey(0); 100 101 cvReleaseImage(&image_Resource); 102 cvReleaseImage(&image_Result_a); 103 /*cvReleaseImage(&imgCopy_b); 104 cvReleaseImage(&imgCopy_c);*/ 105 106 cvDestroyWindow("原始图像"); 107 cvDestroyWindow("题目_a"); 108 cvDestroyWindow("题目_b"); 109 cvDestroyWindow("题目_c"); 110 111 return 0; 112 } 113 114 //cvPyrType表示操作类型,cvPyrDown和cvPyrUp,0代表cvPyrDown和cvPyrSetmentation,暂时只针对cvPyrDown判断层数。相关参数见书中对cvPyrSetmentation的说明 115 bool IsCanBeUsedForImagePyramid(IplImage * img, uint32_t layerCount, int PyrType) 116 { 117 int imgWidth = img->width; 118 int imgHeight = img->height; 119 120 if (imgWidth % 2 != 0 || imgHeight % 2 != 0) 121 { 122 return false; 123 } 124 125 uint32_t tempWidth = imgWidth / 2; 126 uint32_t tempHeight = imgHeight / 2; 127 uint32_t canUsedCount = 0; 128 129 while (tempWidth % 2 == 0) 130 { 131 canUsedCount++; 132 tempWidth = tempWidth / 2; 133 } 134 135 if (canUsedCount < layerCount) 136 { 137 return false; 138 } 139 140 canUsedCount = 0; 141 142 while (tempHeight % 2 == 0) 143 { 144 canUsedCount++; 145 tempHeight = tempHeight / 2; 146 } 147 148 if (canUsedCount < layerCount) 149 { 150 return false; 151 } 152 153 return true; 154 }
①使用cvPyrSegmentation函数的时候见证使用IsCanBeUsedForImagePyramid验证图像的重要性,特别是金字塔层数比较多的时候
②threshold1:建立连接的错误阈值,当一些值小于这个值时就把这些值相连结;threshold2:分割簇的错误阈值,当一些值小于这个值时就把这些值当做是一个区域,所以
③使用cvPyrSegmentation函数,必须加入#include <opencv2/legacy/legacy.hpp>,另附加依赖项可以使用一行代码代替,见下图
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖