SURF源码分析之main.cpp
main.cpp主要由几个主函数组成,通过选择PROCEDURE的值可进行下列6个操作:
1、特征点检测
2、视频特征点检测
3、图像与视频匹配
4、动点查询
5、图像与图像匹配
6、特征点聚类-Kmeas算法
/*********************************************************** * --- OpenSURF --- * * This library is distributed under the GNU GPL. Please * * use the contact form at http://www.chrisevansdev.com * * for more information. * * * * C. Evans, Research Into Robust Visual Features, * * MSc University of Bristol, 2008. * * * ************************************************************/ #include "surflib.h" #include "kmeans.h" #include <ctime> #include <iostream> //------------------------------------------------------- // In order to you use OpenSURF, the following illustrates // some of the simple tasks you can do. It takes only 1 // function call to extract described SURF features! // Define PROCEDURE as: // - 1 and supply image path to run on static image // - 2 to capture from a webcam // - 3 to match find an object in an image (work in progress) // - 4 to display moving features (work in progress) // - 5 to show matches between static images #define PROCEDURE 2 //------------------------------------------------------- // 视频特征点检测 int mainImage(void) { // Declare Ipoints and other stuff IpVec ipts;//特征点容器 IplImage *img=cvLoadImage("imgs/sf.jpg");//待提取特征点图像 // Detect and describe interest points in the image clock_t start = clock();//特征点提取计时开始 surfDetDes(img, ipts, false, 5, 4, 2, 0.0004f);//特征点提取函数 clock_t end = clock();//特征点提取计时结束 std::cout<< "OpenSURF found: " << ipts.size() << " interest points" << std::endl; std::cout<< "OpenSURF took: " << float(end - start) / CLOCKS_PER_SEC << " seconds" << std::endl; // Draw the detected points drawIpoints(img, ipts);//在图像中画出特征点 // Display the result showImage(img);//显示图像 return 0; } //------------------------------------------------------- // 视频图像特征点检测 int mainVideo(void) { // Initialise capture device CvCapture* capture = cvCreateFileCapture( "E:\\photo\\毕业照\\杀人.mov " ); //CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );//从摄像头获取视频 if(!capture) error("No Capture");//检测是否获取视频 // Initialise video writer //cv::VideoWriter vw("c:\\out.avi", CV_FOURCC('D','I','V','X'),10,cvSize(320,240),1); //vw << img; // Create a window cvNamedWindow("OpenSURF", CV_WINDOW_AUTOSIZE );//创建显示窗口 // Declare Ipoints and other stuff IpVec ipts;//特征点容器 IplImage *img=NULL;//获取帧图像 // Main capture loop while( 1 ) { // Grab frame from the capture source img = cvQueryFrame(capture);//将帧图像赋值给img // Extract surf points surfDetDes(img, ipts, false, 4, 4, 2, 0.004f);//获取图像SURF特征值 // Draw the detected points drawIpoints(img, ipts);//在图像中画出特征点 // Draw the FPS figure drawFPS(img);// 显示帧数 // Display the result cvShowImage("OpenSURF", img);//显示图片 // If ESC key pressed exit loop if( (cvWaitKey(10) & 255) == 27 ) break; } cvReleaseCapture( &capture );//释放视频 cvDestroyWindow( "OpenSURF" );//摧毁窗口 return 0; } //------------------------------------------------------- int mainMatch(void) { // Initialise capture device CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );//从摄像头获取图像 if(!capture) error("No Capture");//检测是否成功获取视频 // Declare Ipoints and other stuff IpPairVec matches;//匹配特征点容器 IpVec ipts, ref_ipts;//特征点容器 // This is the reference object we wish to find in video frame // Replace the line below with IplImage *img = cvLoadImage("imgs/object.jpg"); // where object.jpg is the planar object to be located in the video IplImage *img = cvLoadImage("imgs/object.jpg"); //待检测的图像 if (img == NULL) error("Need to load reference image in order to run matching procedure"); CvPoint src_corners[4] = {{0,0}, {img->width,0}, {img->width, img->height}, {0, img->height}}; CvPoint dst_corners[4]; // Extract reference object Ipoints surfDetDes(img, ref_ipts, false, 3, 4, 3, 0.004f); drawIpoints(img, ref_ipts); showImage(img); // Create a window cvNamedWindow("OpenSURF", CV_WINDOW_AUTOSIZE ); // Main capture loop while( true ) { // Grab frame from the capture source img = cvQueryFrame(capture); // Detect and describe interest points in the frame surfDetDes(img, ipts, false, 3, 4, 3, 0.004f); // Fill match vector getMatches(ipts,ref_ipts,matches); // This call finds where the object corners should be in the frame if (translateCorners(matches, src_corners, dst_corners)) { // Draw box around object for(int i = 0; i < 4; i++ ) { CvPoint r1 = dst_corners[i%4]; CvPoint r2 = dst_corners[(i+1)%4]; cvLine( img, cvPoint(r1.x, r1.y), cvPoint(r2.x, r2.y), cvScalar(255,255,255), 3 ); } for (unsigned int i = 0; i < matches.size(); ++i) drawIpoint(img, matches[i].first); } // Draw the FPS figure drawFPS(img); // Display the result cvShowImage("OpenSURF", img); // If ESC key pressed exit loop if( (cvWaitKey(10) & 255) == 27 ) break; } // Release the capture device cvReleaseCapture( &capture ); cvDestroyWindow( "OpenSURF" ); return 0; } //------------------------------------------------------- //动点检测 int mainMotionPoints(void) { // Initialise capture device CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY ); if(!capture) error("No Capture"); // Create a window cvNamedWindow("OpenSURF", CV_WINDOW_AUTOSIZE ); // Declare Ipoints and other stuff IpVec ipts, old_ipts, motion; IpPairVec matches; IplImage *img; // Main capture loop while( 1 ) { // Grab frame from the capture source img = cvQueryFrame(capture); // Detect and describe interest points in the image old_ipts = ipts; surfDetDes(img, ipts, true, 3, 4, 2, 0.0004f); // Fill match vector getMatches(ipts,old_ipts,matches); for (unsigned int i = 0; i < matches.size(); ++i) { const float & dx = matches[i].first.dx; const float & dy = matches[i].first.dy; float speed = sqrt(dx*dx+dy*dy); if (speed > 5 && speed < 30) drawIpoint(img, matches[i].first, 3); } // Display the result cvShowImage("OpenSURF", img); // If ESC key pressed exit loop if( (cvWaitKey(10) & 255) == 27 ) break; } // Release the capture device cvReleaseCapture( &capture ); cvDestroyWindow( "OpenSURF" ); return 0; } //------------------------------------------------------- int mainStaticMatch() { IplImage *img1, *img2; clock_t start = clock(); //img1 = cvLoadImage("data/landscape-a.jpg"); //img2 = cvLoadImage("data/landscape-b.jpg"); img1 = cvLoadImage("E:\\photo\\测试\\test1.jpg"); img2 = cvLoadImage("E:\\photo\\测试\\test2.jpg"); IpVec ipts1, ipts2; surfDetDes(img1,ipts1,false,4,4,2,0.0001f); surfDetDes(img2,ipts2,false,4,4,2,0.0001f); IpPairVec matches; getMatches(ipts1,ipts2,matches); for (unsigned int i = 0; i < matches.size(); ++i) { drawPoint(img1,matches[i].first); drawPoint(img2,matches[i].second); const int & w = img1->width; cvLine(img1,cvPoint(matches[i].first.x,matches[i].first.y),cvPoint(matches[i].second.x+w,matches[i].second.y), cvScalar(255,255,255),1); cvLine(img2,cvPoint(matches[i].first.x-w,matches[i].first.y),cvPoint(matches[i].second.x,matches[i].second.y), cvScalar(255,255,255),1); } std::cout<< "Matches: " << matches.size(); clock_t end = clock(); std::cout<< "OpenSURF took: " << float(end - start) / CLOCKS_PER_SEC << " seconds" << std::endl; cvNamedWindow("1", CV_WINDOW_AUTOSIZE ); cvNamedWindow("2", CV_WINDOW_AUTOSIZE ); cvShowImage("1", img1); cvShowImage("2",img2); cvWaitKey(0); return 0; } //------------------------------------------------------- // 特征点聚类-Kmeas算法 int mainKmeans(void) { IplImage *img = cvLoadImage("imgs/img1.jpg"); IpVec ipts; Kmeans km; // Get Ipoints surfDetDes(img,ipts,true,3,4,2,0.0006f); for (int repeat = 0; repeat < 10; ++repeat) { IplImage *img = cvLoadImage("imgs/img1.jpg"); km.Run(&ipts, 5, true); drawPoints(img, km.clusters); for (unsigned int i = 0; i < ipts.size(); ++i) { cvLine(img, cvPoint(ipts[i].x,ipts[i].y), cvPoint(km.clusters[ipts[i].clusterIndex].x ,km.clusters[ipts[i].clusterIndex].y),cvScalar(255,255,255)); } showImage(img); } return 0; } //------------------------------------------------------- int main(void) { if (PROCEDURE == 1) return mainImage();//特征点检测 if (PROCEDURE == 2) return mainVideo();//视频特征点检测 if (PROCEDURE == 3) return mainMatch();//图像与视频匹配 if (PROCEDURE == 4) return mainMotionPoints();//动点检测 if (PROCEDURE == 5) return mainStaticMatch();//图像与图像匹配 if (PROCEDURE == 6) return mainKmeans();//特征点聚类-Kmeas算法 }