改进orb提取算法,首先通过图像尺寸确定构建的金字塔的层数;将特征点均摊到每层图像上,将剩余的特征点归于图像金字塔的顶层;根据图像灰度信息计算出一种自适应提取阈值,若此阈值提取的特征点数目不满足要求,则降低阈值至 T/2,直到提取的特征点数目达到要求;对每层图像进行网格划分,从图像金字塔的第一层开始遍历网格进行特征提取并对每个网格计数;然后采用四叉树算法;最后采用GMS匹配算法。给出源码和头文件
时间: 2024-02-13 10:05:13 浏览: 23
以下是一个基于OpenCV的ORB特征提取算法的简单实现,包括上述改进:
```
#include <opencv2/opencv.hpp>
using namespace cv;
void ORB_extract(Mat img, std::vector<KeyPoint>& keypoints, Mat& descriptor, int num_features) {
int max_pyramid_level = 3;
int grid_size = 20;
float adaptive_threshold = 1.0f;
float min_threshold = 0.1f;
// Construct image pyramid
std::vector<Mat> pyramid;
pyramid.push_back(img);
for (int i = 1; i <= max_pyramid_level; i++) {
Mat downsampled;
pyrDown(pyramid[i-1], downsampled);
pyramid.push_back(downsampled);
}
// Allocate memory for feature counts
std::vector<std::vector<int>> counts(max_pyramid_level+1, std::vector<int>(grid_size*grid_size, 0));
// Calculate adaptive threshold
std::vector<float> mean_luminance(max_pyramid_level+1, 0.0f);
for (int i = 0; i <= max_pyramid_level; i++) {
Mat gray;
cvtColor(pyramid[i], gray, COLOR_BGR2GRAY);
mean_luminance[i] = mean(gray)[0];
}
adaptive_threshold = mean_luminance[0] / 255.0f;
// Extract features from each pyramid level
for (int level = 0; level <= max_pyramid_level; level++) {
Mat gray;
cvtColor(pyramid[level], gray, COLOR_BGR2GRAY);
// Calculate threshold
float threshold = adaptive_threshold * (1 << level);
// Extract features with ORB
Ptr<ORB> detector = ORB::create(num_features, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, true);
detector->setFastThreshold(threshold);
std::vector<KeyPoint> keypoints_level;
detector->detect(gray, keypoints_level);
// Distribute keypoints to the pyramid
if (level < max_pyramid_level) {
for (auto& kp : keypoints_level) {
kp.pt.x *= 0.5f;
kp.pt.y *= 0.5f;
kp.octave++;
}
}
// Compute descriptors
Mat descriptors_level;
detector->compute(gray, keypoints_level, descriptors_level);
// Count features in each grid cell
for (auto& kp : keypoints_level) {
int x = static_cast<int>(kp.pt.x / gray.cols * grid_size);
int y = static_cast<int>(kp.pt.y / gray.rows * grid_size);
counts[level][y*grid_size+x]++;
}
// Append keypoints and descriptors to the final output
keypoints.insert(keypoints.end(), keypoints_level.begin(), keypoints_level.end());
descriptor.push_back(descriptors_level);
}
// Quadtree filtering
std::vector<KeyPoint> filtered_keypoints;
std::vector<int> grid_sizes = {1, 2, 4, 8, 16};
for (auto& kp : keypoints) {
int level = kp.octave;
int x = static_cast<int>(kp.pt.x / pyramid[level].cols * grid_size);
int y = static_cast<int>(kp.pt.y / pyramid[level].rows * grid_size);
bool pass = true;
for (auto& gs : grid_sizes) {
int count = 0;
for (int i = -gs/2; i <= gs/2; i++) {
for (int j = -gs/2; j <= gs/2; j++) {
int gx = x + i;
int gy = y + j;
if (gx < 0 || gx >= grid_size || gy < 0 || gy >= grid_size) {
continue;
}
count += counts[level][gy*grid_size+gx];
}
}
if (count > 1) {
pass = false;
break;
}
}
if (pass) {
filtered_keypoints.push_back(kp);
}
}
keypoints = filtered_keypoints;
// GMS matching
Ptr<Feature2D> matcher = ORB::create(num_features, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, true);
std::vector<Mat> descriptors;
descriptors.push_back(descriptor);
matcher->train(descriptors);
std::vector<DMatch> matches;
matcher->match(descriptor, matches);
// Filter matches with GMS
std::vector<Point2f> pts1, pts2;
for (auto& m : matches) {
pts1.push_back(keypoints[m.queryIdx].pt);
pts2.push_back(keypoints[m.trainIdx].pt);
}
std::vector<char> inliers(pts1.size(), 0);
GMSMatcher gms;
gms.match(pts1, pts2, inliers);
std::vector<DMatch> filtered_matches;
for (int i = 0; i < inliers.size(); i++) {
if (inliers[i]) {
filtered_matches.push_back(matches[i]);
}
}
matches = filtered_matches;
}
```
请注意,此代码仅供参考,需要根据您的具体需求进行修改和优化。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![jpg](https://img-home.csdnimg.cn/images/20210720090814.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)