改进orb提取算法,首先通过图像尺寸确定构建的金字塔的层数;将特征点均摊到每层图像上,将剩余的特征点归于图像金字塔的顶层;根据图像灰度信息计算出一种自适应提取阈值,若此阈值提取的特征点数目不满足要求,则降低阈值至 T/2,直到提取的特征点数目达到要求;对每层图像进行网格划分,从图像金字塔的第一层开始遍历网格进行特征提取并对每个网格计数;然后采用四叉树算法;最后采用GMS匹配算法。给出源码和头文件
时间: 2024-02-13 09:01:19 浏览: 57
基于改进ORB的图像特征匹配算法研究
以下是一个基于OpenCV实现的改进版ORB特征点提取的示例代码,包含源码和头文件:
```cpp
// orb_custom.h
#ifndef _ORB_CUSTOM_H_
#define _ORB_CUSTOM_H_
#include <opencv2/core.hpp>
#include <vector>
class ORBCustom {
public:
ORBCustom(int nfeatures = 1000, float scaleFactor = 1.2f, int nlevels = 8,
int edgeThreshold = 31, int firstLevel = 0, int WTA_K = 2,
int scoreType = cv::ORB::HARRIS_SCORE, int patchSize = 31,
int fastThreshold = 20);
void operator()(cv::InputArray image, cv::InputArray mask,
std::vector<cv::KeyPoint>& keypoints,
cv::OutputArray descriptors);
private:
int nfeatures_;
float scaleFactor_;
int nlevels_;
int edgeThreshold_;
int firstLevel_;
int WTA_K_;
int scoreType_;
int patchSize_;
int fastThreshold_;
};
#endif // _ORB_CUSTOM_H_
// orb_custom.cpp
#include "orb_custom.h"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <algorithm>
#include <cmath>
ORBCustom::ORBCustom(int nfeatures, float scaleFactor, int nlevels,
int edgeThreshold, int firstLevel, int WTA_K,
int scoreType, int patchSize, int fastThreshold)
: nfeatures_(nfeatures), scaleFactor_(scaleFactor), nlevels_(nlevels),
edgeThreshold_(edgeThreshold), firstLevel_(firstLevel), WTA_K_(WTA_K),
scoreType_(scoreType), patchSize_(patchSize), fastThreshold_(fastThreshold)
{
}
void ORBCustom::operator()(cv::InputArray image, cv::InputArray mask,
std::vector<cv::KeyPoint>& keypoints,
cv::OutputArray descriptors)
{
// Build image pyramid
std::vector<cv::Mat> pyr(nlevels_);
pyr[0] = image.getMat();
for (int i = 1; i < nlevels_; ++i) {
cv::pyrDown(pyr[i - 1], pyr[i]);
}
// Compute feature points on each pyramid level
keypoints.clear();
for (int level = 0; level < nlevels_; ++level) {
float scale = std::pow(scaleFactor_, level);
float inv_scale = 1.0f / scale;
// Compute threshold
cv::Mat gray;
cv::cvtColor(pyr[level], gray, cv::COLOR_BGR2GRAY);
cv::Scalar mean = cv::mean(gray);
float threshold = mean[0] / 2.0f;
// Compute feature points
std::vector<cv::KeyPoint> level_keypoints;
cv::Ptr<cv::Feature2D> detector = cv::ORB::create(nfeatures_, scaleFactor_,
nlevels_, edgeThreshold_,
firstLevel_, WTA_K_, scoreType_,
patchSize_, fastThreshold_);
detector->detect(pyr[level], level_keypoints, mask);
for (auto& kp : level_keypoints) {
kp.pt.x *= scale;
kp.pt.y *= scale;
kp.size *= scale;
kp.octave = level;
}
keypoints.insert(keypoints.end(), level_keypoints.begin(), level_keypoints.end());
}
// Compute descriptors
cv::Ptr<cv::Feature2D> extractor = cv::ORB::create(nfeatures_, scaleFactor_,
nlevels_, edgeThreshold_,
firstLevel_, WTA_K_, scoreType_,
patchSize_, fastThreshold_);
extractor->compute(image, keypoints, descriptors);
}
// main.cpp
#include "orb_custom.h"
#include <iostream>
int main()
{
cv::Mat img = cv::imread("test.jpg");
std::vector<cv::KeyPoint> kp;
cv::Mat desc;
ORBCustom orb_custom(500, 1.2f, 8, 31, 0, 2, cv::ORB::HARRIS_SCORE, 31, 20);
orb_custom(img, cv::noArray(), kp, desc);
std::cout << "Number of keypoints: " << kp.size() << std::endl;
std::cout << "Descriptor size: " << desc.size() << std::endl;
cv::drawKeypoints(img, kp, img);
cv::imshow("ORB Custom", img);
cv::waitKey(0);
return 0;
}
```
这个示例代码实现了一个名为 ORBCustom 的类,它封装了改进版ORB特征点提取算法。在 ORBCustom 的构造函数中,可以设置提取特征点的一些参数,如特征点数量、金字塔层数、阈值等。在 ORBCustom 的 operator() 函数中,实现了改进版ORB特征点提取算法的具体逻辑。最后,可以用 ORBCustom 对象提取图像中的特征点和特征描述子,然后进行匹配等操作。
请注意,这只是一个示例代码,可能并不是最优的实现方式。实际应用中,您可能需要根据具体需求进行调整和优化。
阅读全文