David Lowe 的sift一直被大家拿来使用,自己编不出来,编出来估计也不如人家编的好,就拿来用了
首先利用sift对目标物提取特征点,作为之后的判断依据
demo的目的是再一段视频中检测到目标物体。
我们利用了opencv去读取一段视频
利用sift去提取每一帧的特征点,之后进行匹配
起初想去除错检测点,但发现确实不太好处理,算法时间,错误点数量,如何达到最优都比较麻烦。
最后觉得既然是要检测出目标那么判断匹配点的数量
如果数量足够多那么就发出报警。也就是规定一个阀值而已。
程序源码如下:
void main()
{
int i = 0;
int num =0;
CvCapture *capture;
IplImage *frame;
IplImage *tempframe;
IplImage *object;
Keypoint k1 = NULL, k2 = NULL;
//tempframe = cvCreateImage(
capture = cvCaptureFromFile("D:\\My Documents\\Visual Studio 2008\\Projects\\siftobject\\PETS-09.avi");
object = cvLoadImage("object.png",1);
IplImage *objecttemp;
objecttemp = cvCreateImage(cvGetSize(object),8,1);
cvCvtColor(object,objecttemp,CV_BGR2GRAY);
char filename1[1024];
sprintf(filename1,"D:\\My Documents\\Visual Studio 2008\\Projects\\siftobject\\siftobject\\object.pgm",i);
cvSaveImage(filename1,objecttemp);
system("siftWin32.exe <object.pgm >object.key");
cvNamedWindow("Webcam",0);
while(i<10)
{
frame = cvQueryFrame(capture);
tempframe = cvCreateImage(cvGetSize(frame),8,1);
cvCvtColor(frame,tempframe,CV_BGR2GRAY);
//cvShowImage("Webcam",frame);
//cvWriteFrame(writer,frame);
char filename[1024];
sprintf(filename,"D:\\My Documents\\Visual Studio 2008\\Projects\\siftobject\\siftobject\\test.pgm",i);
cvSaveImage(filename,tempframe);
//cvShowImage("Webcam",tempframe);
printf("%d\n",i);
//cvWaitKey(0);
//if(cvWaitKey(20)>0) break;
i++;
system("siftWin32.exe <test.pgm >test.key");
char* test = "test.key";
char* object = "object.key";
k1 = ReadKeyFile(test);
k2 = ReadKeyFile(object);
num = FindMatches(k1,k2,tempframe);
cout<<num<<endl;
num = 0;
//cvShowImage("Webcam",tempframe);
//system("siftWin32.exe <test.pgm >test.key");
}
cvReleaseCapture(&capture);
cvDestroyWindow("Webcam");
}
由于程序源码很长,这里仅仅贴出了主函数部分。
其他代码大家可以参看 David Lowe 的个人网站。
另外给出另一个牛人的homepage
Andrea Vedaldi:http://www.vlfeat.org/~vedaldi/ 他的代码效率更高,效果更好。
希望做同样工作的同学跟我联系,共同讨论。