【练习8.1】查找轮廓、寻找关键点cvFindDominantPoints、访问序列中的元素

 

页内索引
题目要求 程序代码 结果图片 要言妙道 借鉴参考

 

 

  

题目要求:

 查找轮廓并使用 cvFindDominantPoints 寻找关键点,看缩放图像和旋转图像会否影响到IPAN算法的结果

 

程序代码:

 

  1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
  2 //
  3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg
  4 
  5 
  6 #include "stdafx.h"
  7 #include<string>
  8 #include <cv.h>
  9 #include <highgui.h>
 10 #include <iostream>
 11 
 12 #include <opencv2/legacy/legacy.hpp>
 13 //#pragma comment(lib, "opencv_legacy2411.lib")
 14 
 15 using namespace cv;
 16 using namespace std;
 17 
 18 //函数声明-->--->-->--->-->--->-->--->//
 19 
 20 string itos(int i) // 将int 转换成string
 21 {
 22     stringstream s;
 23     s << i;
 24     return s.str();
 25 }
 26 
 27 //<--<--<--<--<--<--<--<--<--函数声明//
 28 
 29 int _tmain(int argc, _TCHAR* argv[])
 30 {
 31     IplImage * image_Resource;
 32 
 33     string window_name;
 34 
 35     string image_full_name[8];
 36     image_full_name[0] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask.jpg";
 37     image_full_name[1] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_80%.jpg";
 38     image_full_name[2] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_120%.jpg";
 39     image_full_name[3] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_15度.jpg";
 40     image_full_name[4] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_-15度60%.jpg";
 41     image_full_name[5] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_-15度.jpg";
 42     image_full_name[6] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_-75度.jpg";
 43     image_full_name[7] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_105度.jpg";
 44 
 45     for (int file_name_i = 0; file_name_i < 8; ++file_name_i)
 46     {
 47         image_Resource = cvLoadImage(image_full_name[file_name_i].c_str(), CV_LOAD_IMAGE_GRAYSCALE);
 48         assert(image_Resource);
 49 
 50         IplImage * image_binary = cvCloneImage(image_Resource);
 51         cvZero(image_binary);
 52 
 53         //二值化图像
 54         double thread_ReturnValue;;
 55         thread_ReturnValue = cvThreshold(image_Resource, image_binary, 200, 255, CV_THRESH_BINARY);
 56 
 57         //window_name = "二值图像";
 58         //window_name = window_name + itos(file_name_i);
 59         //cvNamedWindow(window_name.data(), CV_WINDOW_AUTOSIZE);
 60         //cvShowImage(window_name.data(), image_binary);
 61 
 62         //查找轮廓
 63         CvMemStorage * storage = cvCreateMemStorage();
 64         CvSeq * first_contour;
 65         int contourNum;
 66         contourNum = cvFindContours(image_binary, storage, &first_contour, sizeof(CvContour), CV_RETR_EXTERNAL);
 67 
 68         //显示原始二值图像轮廓
 69         IplImage * image_contours = cvCreateImage(cvGetSize(image_binary), IPL_DEPTH_8U, 1);
 70         cvZero(image_contours);
 71         cvDrawContours(image_contours, first_contour, cvScalar(255), cvScalar(125), 0);
 72         window_name = "原始二值图轮廓图像";
 73         window_name = window_name + itos(file_name_i);
 74         cvNamedWindow(window_name.data(), CV_WINDOW_AUTOSIZE);
 75         cvShowImage(window_name.data(), image_contours);
 76 
 77         //寻找关键点
 78         CvSeq *dominant = NULL;
 79         CvMemStorage *storate_dominant = cvCreateMemStorage();
 80         dominant = cvFindDominantPoints(first_contour, storate_dominant);
 81 
 82         IplImage *image_dominant = cvCreateImage(cvGetSize(image_contours), IPL_DEPTH_8U, 1);
 83         cvZero(image_dominant);
 84 
 85         for (int i = 0; i < dominant->total; ++i)
 86         {
 87             //cvFindDominantPoints返回的只是索引,所以,用下面两行代码无法画出关键点
 88             //CvPoint *point = (CvPoint*)cvGetSeqElem(dominant, i);
 89             //    cvCircle(image_dominant, *point, 5, cvScalar(255));
 90 
 91             int idx = *(int *)cvGetSeqElem(dominant, i);
 92             CvPoint pt = *(CvPoint *)cvGetSeqElem(first_contour, idx);
 93             cvDrawCircle(image_dominant, pt, 1, cvScalar(255));
 94         }
 95 
 96         window_name = "寻找到的关键点";
 97         window_name = window_name + itos(file_name_i);
 98         cvNamedWindow(window_name.c_str(), CV_WINDOW_AUTOSIZE);
 99         cvShowImage(window_name.c_str(), image_dominant);
100 
101         cvReleaseImage(&image_binary);
102         cvReleaseImage(&image_contours);
103         cvReleaseImage(&image_dominant);
104     }
105 
106     cvWaitKey(0);
107 
108     cvReleaseImage(&image_Resource);
109 
110     cvDestroyAllWindows();
111 
112     return 0;
113 }

 

 

结果图片:

 

要言妙道:

  ①:cvFindContours的输入图像必须是8位单通道图像,并且应该被转化为二值的;注意:cvFindContours运行时,这个图像会被直接涂改,所以,注意使用副本。

②cvFindContours的first_contours参数时一个指向CvSeq* 的指针,只需传一个指针即可,无需动手分配内存,也不要分配和释放,cvFindContours函数会自动设置它的值 CvSeq* firstContour = NULL;  cvFindContours( …, &firstContour, … ); 

③ 注意 cvFindDominantPoints 返回的只是关键点在轮廓中的索引,而不是点的序列,如果需要得到关键点的坐标,还需要将该索引传入到 cvGetSeqElem 才可以

④从测试的结果看,缩放会影响IPAN算法返回的结果,特别是当图像的轮廓线不是水平或垂直的时候,旋转也会影响。 

 

借鉴参考:

 

posted on 2015-05-16 17:48  毋忆典藏  阅读(994)  评论(0编辑  收藏  举报