gpt4 book ai didi

c++ - 使用 OpenCV 改进特征点的匹配

转载 作者:IT老高 更新时间:2023-10-28 12:50:07 27 4
gpt4 key购买 nike

我想匹配立体图像中的特征点。我已经用不同的算法找到并提取了特征点,现在我需要一个好的匹配。在这种情况下,我使用 FAST 算法进行检测和提取,使用 BruteForceMatcher 匹配特征点。

匹配码:

vector< vector<DMatch> > matches;
//using either FLANN or BruteForce
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(algorithmName);
matcher->knnMatch( descriptors_1, descriptors_2, matches, 1 );

//just some temporarily code to have the right data structure
vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
good_matches2.push_back(matches[i][0]);
}

因为有很多错误匹配,我计算了最小和最大距离并删除了所有太糟糕的匹配:

//calculation of max and min distances between keypoints
double max_dist = 0; double min_dist = 100;
for( int i = 0; i < descriptors_1.rows; i++ )
{
double dist = good_matches2[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}

//find the "good" matches
vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
{
if( good_matches2[i].distance <= 5*min_dist )
{
good_matches.push_back( good_matches2[i]);
}
}

问题是,我要么得到很多错误匹配,要么只有少数正确匹配(见下图)。

many matches with bad results
(来源:codemax.de)

only a few good matches
(来源:codemax.de)

我认为这不是编程问题,而是匹配的问题。据我了解 BruteForceMatcher 只考虑特征点的视觉距离(存储在 FeatureExtractor 中),而不是局部距离(x&y 位置),它位于我的案子也很重要。有没有人遇到过这个问题或改进匹配结果的好主意?

编辑

我更改了代码,它为我提供了 50 个最佳匹配项。在此之后,我通过第一场比赛来检查它是否在指定区域。如果不是,我会进行下一场比赛,直到在给定区域内找到比赛为止。

vector< vector<DMatch> > matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create(algorithmName);
matcher->knnMatch( descriptors_1, descriptors_2, matches, 50 );

//look if the match is inside a defined area of the image
double tresholdDist = 0.25 * sqrt(double(leftImageGrey.size().height*leftImageGrey.size().height + leftImageGrey.size().width*leftImageGrey.size().width));

vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());
for (size_t i = 0; i < matches.size(); ++i)
{
for (int j = 0; j < matches[i].size(); j++)
{
//calculate local distance for each possible match
Point2f from = keypoints_1[matches[i][j].queryIdx].pt;
Point2f to = keypoints_2[matches[i][j].trainIdx].pt;
double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y));
//save as best match if local distance is in specified area
if (dist < tresholdDist)
{
good_matches2.push_back(matches[i][j]);
j = matches[i].size();
}
}

我认为我没有得到更多匹配项,但这样我可以删除更多错误匹配项:

less but better features
(来源:codemax.de)

最佳答案

确定高质量特征匹配的另一种方法是 David Lowe 在他关于 SIFT 的论文中提出的比率测试。 (第 20 页有解释)。此测试通过计算最佳匹配和次佳匹配之间的比率来拒绝不良匹配。如果该比率低于某个阈值,则匹配被视为低质量而被丢弃。

std::vector<std::vector<cv::DMatch>> matches;
cv::BFMatcher matcher;
matcher.knnMatch(descriptors_1, descriptors_2, matches, 2); // Find two nearest matches
vector<cv::DMatch> good_matches;
for (int i = 0; i < matches.size(); ++i)
{
const float ratio = 0.8; // As in Lowe's paper; can be tuned
if (matches[i][0].distance < ratio * matches[i][1].distance)
{
good_matches.push_back(matches[i][0]);
}
}

关于c++ - 使用 OpenCV 改进特征点的匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17967950/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com