OpenCV源码中有关于SURF算法的静态图像特征点匹配,就将其改进为动态视频图像实时获取特征点并将其与目标图像进行特征点匹配。
考虑到如果没有获取到连续帧图像,即有黑色图像被摄像头捕捉到,此时FLANN算法则失效,因为FLANN算法是无法处理黑色图像的,它必须能采集到特征点时才可用,否则,程序会闪退。故在此添加如下代码,用来处理上述现象,并统计丢失的帧率:
static int cnt_fail = 0;
if(imageDescriptors->total == 0)
{
cnt_fail++;
continue;
}
完整代码如下:
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/legacy/legacy.hpp"
#include "opencv2/legacy/compat.hpp"
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;
static void help()
{
printf(
"This program demonstrated the use of the SURF Detector and Descriptor using\n"
"either FLANN (fast approx nearst neighbor classification) or brute force matching\n"
"on planar objects.\n"
"Usage:\n"
"./find_obj <object_filename> <scene_filename>, default is box.png and box_in_scene.png\n\n");
return;
}
// define whether to use approximate nearest-neighbor search
#define USE_FLANN
#ifdef USE_FLANN
static void
flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors,
const CvSeq*, const CvSeq* imageDescriptors, vector<int>& ptpairs )
{
//函数flannFindPairs有5个形参1.参照物的keypoint 2.keypoint的描述符 3.图片的keypoint 4.图片keypoint的描述符 5.int型容器
//用于找到两幅图像之间匹配的点对,并把匹配的点对存储在 ptpairs 向量中,其中物体(object)图像的特征点
int length = (int)(objectDescriptors->elem_size/sizeof(float));
cv::Mat m_object(objectDescriptors->total, length, CV_32F);
cv::Mat m_image(imageDescriptors->total, length, CV_32F);
// copy descriptors
CvSeqReader obj_reader;
float* obj_ptr = m_object.ptr<float>(0);
cvStartReadSeq( objectDescriptors, &obj_reader );//reader来读取seq内部数据的
for(int i = 0; i < objectDescriptors->total; i++ )
{
const float* descriptor = (const float*)obj_reader.ptr;
CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
memcpy(obj_ptr, descriptor, length*sizeof(float));//memcpy内存拷贝函数
obj_ptr += length;
}
CvSeqReader img_reader;
float* img_ptr = m_image.ptr<float>(0);
cvStartReadSeq( imageDescriptors, &img_reader );//reader来读取seq内部数据的
for(int