【练习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 的结果

 

借鉴参考:

 

posted on 2015-05-24 16:45  毋忆典藏  阅读(2009)  评论(0编辑  收藏  举报