【练习8.11】等级匹配cvMatchContourTrees、凸缺陷计算cvConvexityDefects
题目要求 | 程序代码 | 结果图片 | 要言妙道 | 借鉴参考 |
缩放旋转字符A,然后保存
用cvMatchContourTrees和cvConvexityDefects处理这些图像,查看匹配效果
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 CvSeq * ApproxImage(IplImage * image_source); 22 double UseContourTreesToMatch(IplImage * image_1, IplImage * image_2); 23 void CalcConvexityDefects(IplImage * image); 24 25 //<--<--<--<--<--<--<--<--<--函数声明// 26 27 int _tmain(int argc, _TCHAR* argv[]) 28 { 29 string file_full_name[9] = { "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A.jpg" 30 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A_-30度.jpg" 31 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A_50%.jpg" 32 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A_120度.jpg" 33 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A_150%_-60度.jpg" 34 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A_200%.jpg" 35 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符F.jpg" 36 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\字符A.jpg" 37 , "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\Other.jpg" }; 38 39 IplImage * image_source[9]; 40 41 image_source[0] = cvLoadImage(file_full_name[0].c_str(), CV_LOAD_IMAGE_GRAYSCALE); 42 CV_Assert(image_source[0]); 43 cvShowImage("原始图像", image_source[0]); 44 45 string window_name = ""; 46 for (int i = 1; i < 9; ++i) 47 { 48 image_source[i] = cvLoadImage(file_full_name[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE); 49 CV_Assert(image_source[i]); 50 51 window_name = window_name + "。"; 52 cvShowImage(window_name.c_str(), image_source[i]); 53 54 double cTree = UseContourTreesToMatch(image_source[0], image_source[i]); 55 56 cout << cTree << endl; 57 } 58 59 //输出凸缺陷的信息 60 cout << endl << endl<<"凸缺陷计算:"<<endl; 61 CalcConvexityDefects(image_source[5]); 62 63 cvWaitKey(0); 64 //system("pause"); 65 66 cvDestroyAllWindows(); 67 68 return 0; 69 } 70 71 double UseContourTreesToMatch(IplImage * image_1, IplImage * image_2) 72 { 73 CvSeq * approx_seq1 = ApproxImage(image_1); 74 75 CvMemStorage *storage1 = cvCreateMemStorage(); 76 CvContourTree * contoruTree1=NULL; 77 contoruTree1 = cvCreateContourTree(approx_seq1, storage1, 0); 78 79 CvSeq * approx_seq2 = ApproxImage(image_2); 80 CvMemStorage *storage2 = cvCreateMemStorage(); 81 CvContourTree * contoruTree2 = NULL; 82 contoruTree2 = cvCreateContourTree(approx_seq2, storage2, 0); 83 84 double result = cvMatchContourTrees(contoruTree1, contoruTree2, CV_CONTOUR_TREES_MATCH_I1, 100); 85 return result; 86 } 87 88 CvSeq * ApproxImage(IplImage * image_source) 89 { 90 CV_Assert(image_source); 91 92 IplImage * image_binary = cvCloneImage(image_source); 93 cvZero(image_binary); 94 95 cvThreshold(image_source, image_binary, 128, 255, CV_THRESH_BINARY); 96 97 CvMemStorage *storage = cvCreateMemStorage(); 98 CvSeq* first_contour = NULL; 99 int contour_num; 100 contour_num = cvFindContours(image_binary, storage, &first_contour, sizeof(CvContour), CV_RETR_TREE);//注意:cvMatchContourTrees匹配的时候,cvFindContours如果用CV_RETR_LIST得不到结果 101 102 double contour_length; 103 contour_length = cvContourPerimeter(first_contour); 104 105 double perimeter = contour_length / 66; 106 CvMemStorage* storage_approx = cvCreateMemStorage(); 107 108 CvSeq *seq_approx = NULL; 109 110 seq_approx = cvApproxPoly(first_contour, sizeof(CvContour), storage_approx, CV_POLY_APPROX_DP, perimeter, 0); 111 112 cvReleaseImage(&image_binary); 113 114 return seq_approx; 115 } 116 117 void CalcConvexityDefects(IplImage * image) 118 { 119 //查找轮廓 120 IplImage * image_temp = cvCloneImage(image); 121 cvZero(image_temp); 122 cvThreshold(image, image_temp, 128, 255, CV_THRESH_BINARY); 123 124 CvMemStorage * storage = cvCreateMemStorage(); 125 CvSeq * first_contour; 126 int contour_num = cvFindContours(image_temp, storage, &first_contour, sizeof(CvContour), CV_RETR_EXTERNAL); 127 128 //IplImage *image_contour = cvCloneImage(image); 129 //cvZero(image_contour); 130 //cvDrawContours(image_contour, first_contour, cvScalar(255), cvScalar(255), 0); 131 //cvShowImage("轮廓", image_contour); 132 133 134 //检查是否是凸轮廓 135 int isContourConvexity = cvCheckContourConvexity(first_contour); 136 137 //计算凸包 138 CvMemStorage * storage_hull = cvCreateMemStorage(); 139 CvSeq * seq_convex = cvConvexHull2(first_contour, storage_hull); 140 141 //计算凸缺陷 142 //cvFixPointOrder(polyOutline, hull); 143 CvMemStorage * storage_defects = cvCreateMemStorage(); 144 CvSeq * seq_defects = cvConvexityDefects(first_contour, seq_convex, storage_defects); 145 146 for (int i = 0; i < seq_defects->total; ++i) 147 { 148 CvConvexityDefect * defect = (CvConvexityDefect *)cvGetSeqElem(seq_defects, i); 149 150 cout << defect->start->x << " " << defect->start->y << " " 151 << defect->end->x << " " << defect->end->y << " " 152 << defect->depth_point->x << " " << defect->depth_point->y << " " 153 << defect->depth << endl; 154 } 155 156 cvReleaseMemStorage(&storage); 157 cvReleaseMemStorage(&storage_hull); 158 cvReleaseMemStorage(&storage_defects); 159 cvReleaseImage(&image_temp); 160 }
①建立轮廓树前,为了得到较好的描述,需要首先使用函数cvApproxPoly,之后将轮廓排列(运用循环移动)成最初的三角形不怎么受到旋转影响的状态。
②注意,如果查找轮廓时 cvFindContours 的mode参数选择 CV_RETR_LIST或 CV_RETR_FLOODFILL ,则最后使用 cvMatchContourTrees 匹配的时候得不到有效的值
③再次强调, cvFindContours 查找轮廓前记得使用 cvCanny 或 cvThreshold 或 cvAdaptiveThreshold 处理图像
④ cvConvexityDefects 的参数是 cvFindContours 和 cvConvexHull2 的结果
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖