【OpenCV】SURF算法之视频图像实时特征点匹配

本文介绍了如何使用OpenCV实现动态视频图像的SURF特征点匹配,并针对摄像头捕捉到黑色图像导致FLANN算法失效的问题,提供了解决方案,以防止程序闪退并统计丢失帧率。
摘要由CSDN通过智能技术生成

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
  • 1
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值