【练习8.6】使用不同参数值观察cvFindDominantPoints寻找关键点的效果
题目要求 | 程序代码 | 结果图片 | 要言妙道 | 借鉴参考 |
画一个圆
a、改变d_min和d_max距离并画出结果
b、接着改变相邻距离并描述结果的改变
c、最后改变最大角度的阈值并计算结果
1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。 2 // 3 // string file_full_name = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\r20.jpg"; 4 5 6 #include "stdafx.h" 7 #include<string> 8 #include <cv.h> 9 #include <highgui.h> 10 #include <iostream> 11 #include<math.h> 12 13 #include <opencv2/legacy/legacy.hpp> 14 //#pragma comment(lib, "opencv_legacy2411.lib") 15 16 using namespace cv; 17 using namespace std; 18 19 //函数声明-->--->-->--->-->--->-->--->// 20 21 22 //<--<--<--<--<--<--<--<--<--函数声明// 23 24 int _tmain(int argc, _TCHAR* argv[]) 25 { 26 string file_full_name = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\圆.jpg"; 27 28 IplImage * image_source = cvLoadImage(file_full_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE); 29 CV_Assert(image_source); 30 31 IplImage * image_binary = cvCloneImage(image_source); 32 cvZero(image_binary); 33 34 cvThreshold(image_source, image_binary, 125, 255, CV_THRESH_BINARY); 35 36 //找轮廓 37 CvMemStorage *storage = cvCreateMemStorage(); 38 CvSeq* first_contour = NULL; 39 int contour_num; 40 contour_num = cvFindContours(image_binary, storage, &first_contour, sizeof(CvContour), CV_RETR_LIST); 41 42 //找关键点 43 IplImage *image_dominant[4]; 44 //cvZero(image_dominant); 45 46 CvMemStorage* storage_dominant[4]; 47 48 double difference[4] = { -1, -2, -3,-100 }; 49 CvSeq * dominant_idxs[4] ; 50 51 //int dif_indx = 0; 52 for (int dif_indx = 0; dif_indx < 4; ++dif_indx) 53 { 54 string window_name = "E:\\Testing\\image\\Approx窗口"; 55 image_dominant[dif_indx] = cvCloneImage(image_binary); 56 cvZero(image_dominant[dif_indx]); 57 58 dominant_idxs[dif_indx] = NULL; 59 storage_dominant[dif_indx] = cvCreateMemStorage(); 60 61 double param0 = 7; 62 double param1 = 9; 63 double param2 = 9; 64 double param3= 150; 65 66 switch (dif_indx) 67 { 68 case 0: 69 param0 = param0 + difference[0]; 70 window_name = window_name + "。"; 71 break; 72 case 1: 73 param0 = param0 + difference[0]; 74 param1 = param1 + difference[1]; 75 param2 = param2 + difference[2]; 76 window_name = window_name + "。。"; 77 break; 78 case 2: 79 window_name = window_name + "。。。"; 80 81 break; 82 case 3: 83 param0 = param0 + difference[0]; 84 param1 = param1 + difference[1]; 85 param2 = param2 + difference[2]; 86 param3 = param3 + difference[3]; 87 window_name = window_name + "。。。。"; 88 break; 89 default: 90 break; 91 } 92 93 //CvSeq * dominant_idx = NULL; 94 dominant_idxs[dif_indx] = cvFindDominantPoints(first_contour, storage_dominant[dif_indx], CV_DOMINANT_IPAN, param0, param1, param2, param3); 95 96 for (int i = 0; i < dominant_idxs[dif_indx]->total; ++i) 97 { 98 int idx = *(int *)cvGetSeqElem(dominant_idxs[dif_indx], i); 99 CvPoint pt = *(CvPoint *)cvGetSeqElem(first_contour, idx); 100 cvDrawCircle(image_dominant[dif_indx], pt, 1, cvScalar(255)); 101 } 102 103 cvShowImage(window_name.c_str(), image_dominant[dif_indx]); 104 window_name = window_name + ".jpg"; 105 cvSaveImage(window_name.c_str(), image_dominant[dif_indx]); 106 } 107 108 109 cvWaitKey(0); 110 111 cvReleaseImage(&image_source); 112 cvReleaseImage(&image_binary); 113 //cvReleaseImage(&image_dominant); 114 cvDestroyAllWindows(); 115 116 return 0; 117 }
①使用cvFindDominantPoints得到结果后,得到的是索引,这个索引可以强制转换为int型,但注意 cvGetSeqElem 的返回值是 schar* 类型,所以,要用解引用的方式转为int型,例如: int idx = *(int *)cvGetSeqElem(dominant_idx, i); ,不然得到的结果会是错误的。
②在这个例子中,改变 cvFindDominantPoints 的参数parameter4似乎对结果没有影响
③注意 cvFindDominantPoints 的parameter2不能小于parameter1,parameter3不能大于parameter2
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖