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算法
}