您的位置:首页 > 编程语言 > PHP开发

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

2015-05-16 17:48 716 查看
页内索引

题目要求程序代码结果图片要言妙道借鉴参考
题目要求:

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

程序代码:

// OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点。
//
//D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg

#include "stdafx.h"
#include<string>
#include <cv.h>
#include <highgui.h>
#include <iostream>

#include <opencv2/legacy/legacy.hpp>
//#pragma comment(lib, "opencv_legacy2411.lib")

using namespace cv;
using namespace std;

//函数声明-->--->-->--->-->--->-->--->//

string itos(int i) // 将int 转换成string
{
stringstream s;
s << i;
return s.str();
}

//<--<--<--<--<--<--<--<--<--函数声明//

int _tmain(int argc, _TCHAR* argv[])
{
IplImage * image_Resource;

string window_name;

string image_full_name[8];
image_full_name[0] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask.jpg";
image_full_name[1] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_80%.jpg";
image_full_name[2] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_120%.jpg";
image_full_name[3] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_15度.jpg";
image_full_name[4] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_-15度60%.jpg";
image_full_name[5] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_-15度.jpg";
image_full_name[6] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_-75度.jpg";
image_full_name[7] = "D:\\Work\\Work_Programming\\Source\\Image\\OpenCVExerciseImage\\第8章\\bracket_mask_105度.jpg";

for (int file_name_i = 0; file_name_i < 8; ++file_name_i)
{
image_Resource = cvLoadImage(image_full_name[file_name_i].c_str(), CV_LOAD_IMAGE_GRAYSCALE);
assert(image_Resource);

IplImage * image_binary = cvCloneImage(image_Resource);
cvZero(image_binary);

//二值化图像
double thread_ReturnValue;;
thread_ReturnValue = cvThreshold(image_Resource, image_binary, 200, 255, CV_THRESH_BINARY);

//window_name = "二值图像";
//window_name = window_name + itos(file_name_i);
//cvNamedWindow(window_name.data(), CV_WINDOW_AUTOSIZE);
//cvShowImage(window_name.data(), image_binary);

//查找轮廓
CvMemStorage * storage = cvCreateMemStorage();
CvSeq * first_contour;
int contourNum;
contourNum = cvFindContours(image_binary, storage, &first_contour, sizeof(CvContour), CV_RETR_EXTERNAL);

//显示原始二值图像轮廓
IplImage * image_contours = cvCreateImage(cvGetSize(image_binary), IPL_DEPTH_8U, 1);
cvZero(image_contours);
cvDrawContours(image_contours, first_contour, cvScalar(255), cvScalar(125), 0);
window_name = "原始二值图轮廓图像";
window_name = window_name + itos(file_name_i);
cvNamedWindow(window_name.data(), CV_WINDOW_AUTOSIZE);
cvShowImage(window_name.data(), image_contours);

//寻找关键点
CvSeq *dominant = NULL;
CvMemStorage *storate_dominant = cvCreateMemStorage();
dominant = cvFindDominantPoints(first_contour, storate_dominant);

IplImage *image_dominant = cvCreateImage(cvGetSize(image_contours), IPL_DEPTH_8U, 1);
cvZero(image_dominant);

for (int i = 0; i < dominant->total; ++i)
{
//cvFindDominantPoints返回的只是索引,所以,用下面两行代码无法画出关键点
//CvPoint *point = (CvPoint*)cvGetSeqElem(dominant, i);
//    cvCircle(image_dominant, *point, 5, cvScalar(255));

int idx = *(int *)cvGetSeqElem(dominant, i);
CvPoint pt = *(CvPoint *)cvGetSeqElem(first_contour, idx);
cvDrawCircle(image_dominant, pt, 1, cvScalar(255));
}

window_name = "寻找到的关键点";
window_name = window_name + itos(file_name_i);
cvNamedWindow(window_name.c_str(), CV_WINDOW_AUTOSIZE);
cvShowImage(window_name.c_str(), image_dominant);

cvReleaseImage(&image_binary);
cvReleaseImage(&image_contours);
cvReleaseImage(&image_dominant);
}

cvWaitKey(0);

cvReleaseImage(&image_Resource);

cvDestroyAllWindows();

return 0;
}


结果图片:

















要言妙道:

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

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

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

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

借鉴参考:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: