图像拼接|OpenCV3.4 stitching源码分析(一)

图像拼接|OpenCV3.4 stitching源码分析(一)

前言

图像拼接|——OpenCV3.4 stitching模块分析(一)特征点检测
参考opencv_赵春江的专栏_zhaocj-CSDN博客

特征点检测

OpenCV3.4中实现了surf、orb、sift等特征检测算法,默认的是surf。
特征检测算法的实现主要包含在 “opencv2/stitching/detail/matchers.hpp” 中。

源码

首先定义了一个ImageFeatures结构体用于存放特征信息,包括图片序号、尺寸、特征点信息及描述子矩阵:

struct CV_EXPORTS ImageFeatures
{
    int img_idx;
    Size img_size;
    std::vector<KeyPoint> keypoints;
    UMat descriptors;
};

定义FeaturesFinder基类,其中的成员函数find()是用来寻找特征信息:

class CV_EXPORTS FeaturesFinder
{
public:
    virtual ~FeaturesFinder() {}
    //重载
    void operator ()(InputArray image, ImageFeatures &features);
    //寻找给定图像特征
    void operator ()(InputArray image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
    //并行寻找给定图像特征
    void operator ()(InputArrayOfArrays images, std::vector<ImageFeatures> &features,
                     const std::vector<std::vector<cv::Rect> > &rois);
    //重载
    void operator ()(InputArrayOfArrays images, std::vector<ImageFeatures> &features);
    //释放内存
    virtual void collectGarbage() {}

protected:
    //纯虚函数,根据用户所选取的特征类别,调用不同子类的find函数
    virtual void find(InputArray image, ImageFeatures &features) = 0;
    //判断是否可以并行
    bool isThreadSafe() const;
};

FeaturesFinder基类派生出SurfFeaturesFinder、SiftFeaturesFinder、OrbFeaturesFinder等派生类。
SurfFeaturesFinder派生类定义:

class CV_EXPORTS SurfFeaturesFinder : public FeaturesFinder
{
public:
    SurfFeaturesFinder(double hess_thresh = 300., int num_octaves = 3, int num_layers = 4,
                       int num_octaves_descr = /*4*/3, int num_layers_descr = /*2*/4);

private:
    void find(InputArray image, ImageFeatures &features) CV_OVERRIDE;

    Ptr<FeatureDetector> detector_;
    Ptr<DescriptorExtractor> extractor_;
    Ptr<Feature2D> surf;
};

SiftFeaturesFinder派生类定义:

class CV_EXPORTS SiftFeaturesFinder : public FeaturesFinder
{
public:
    SiftFeaturesFinder();

private:
    void find(InputArray image, ImageFeatures &features) CV_OVERRIDE;
    Ptr<Feature2D> sift;
};

OrbFeaturesFinder派生类定义:

class CV_EXPORTS OrbFeaturesFinder : public FeaturesFinder
{
public:
    OrbFeaturesFinder(Size _grid_size = Size(3,1), int nfeatures=1500, float scaleFactor=1.3f, int nlevels=5);

private:
    void find(InputArray image, ImageFeatures &features) CV_OVERRIDE;

    Ptr<ORB> orb;
    Size grid_size;
};

关于各个特征检测算法的具体实现,就不具体展开了,一般只要知道怎样调用高级API即可。

应用

#include <iostream>
#include "opencv2/highgui.hpp"
#include "opencv2/stitching/detail/matchers.hpp"

using namespace std;
using namespace cv;
using namespace cv::detail;

int main()
{
	Mat img = imread("4.jpg");

	Ptr<FeaturesFinder> finder1, finder2, finder3;
	finder1 = makePtr<SurfFeaturesFinder>();
	finder2 = makePtr<OrbFeaturesFinder>();
	finder3 = makePtr<SiftFeaturesFinder>();

	ImageFeatures features1, features2, features3;
	(*finder1)(img, features1);
	(*finder2)(img, features2);
	(*finder3)(img, features3);

	Mat output_img1, output_img2, output_img3;
	//调用drawKeypoints函数绘制特征
	drawKeypoints(img, features1.keypoints, output_img1, Scalar(255, 0, 0));
	drawKeypoints(img, features2.keypoints, output_img2, Scalar(255, 0, 0));
	drawKeypoints(img, features3.keypoints, output_img3, Scalar(255, 0, 0));

	cout << "Number of surf keypoints: " << features1.keypoints.size() << endl;
	cout << "Number of orb keypoints: " << features2.keypoints.size() << endl;
	cout << "Number of sift keypoints: " << features3.keypoints.size() << endl;

	namedWindow("surf");
	imshow("surf", output_img1);
	namedWindow("orb");
	imshow("orb", output_img2);
	namedWindow("sift");
	imshow("sift", output_img3);

	waitKey(0);

	return 0;
}

运行结果:
原图

surf
orb
sift

Number of surf keypoints: 1403
Number of orb keypoints: 1346
Number of sift keypoints: 1287
主观视觉上还是SIFT更稳健一些,不过stitching默认使用的是surf。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值