gpt4 book ai didi

c++ - 如何在opencv中找到单个图像关键点之间的欧氏距离

转载 作者:太空狗 更新时间:2023-10-29 23:30:17 25 4
gpt4 key购买 nike

我想为图像中的每个关键点获取一个距离 vector d。距离 vector 应包含从该关键点到该图像中所有其他关键点的距离。注意:使用 SIFT 找到关键点。

我是 opencv 的新手。 C++ 中是否有库函数可以使我的任务变得简单?

最佳答案

如果你对位置距离不感兴趣,但对描述符距离感兴趣,你可以使用这个:

cv::Mat SelfDescriptorDistances(cv::Mat descr)
{
cv::Mat selfDistances = cv::Mat::zeros(descr.rows,descr.rows, CV_64FC1);
for(int keyptNr = 0; keyptNr < descr.rows; ++keyptNr)
{
for(int keyptNr2 = 0; keyptNr2 < descr.rows; ++keyptNr2)
{
double euclideanDistance = 0;
for(int descrDim = 0; descrDim < descr.cols; ++descrDim)
{
double tmp = descr.at<float>(keyptNr,descrDim) - descr.at<float>(keyptNr2, descrDim);
euclideanDistance += tmp*tmp;
}

euclideanDistance = sqrt(euclideanDistance);
selfDistances.at<double>(keyptNr, keyptNr2) = euclideanDistance;
}

}
return selfDistances;
}

这将为您提供一个 N x N 矩阵(N = 关键点的数量),其中 Mat_i,j = 关键点 i 和 j 之间的欧氏距离。

使用此输入:

enter image description here

我得到这些输出:

  1. 标记关键点且距离小于 0.05 的图像

enter image description here

  1. 对应于矩阵的图像。白色像素距离 < 0.05。

enter image description here

注意:你可以在矩阵的计算中优化很多东西,因为距离是对称的!

更新:

还有另一种方法:

从您的聊天中我知道您需要 13GB 内存来保存 41381 个关键点(您尝试过)的距离信息。如果您只想要 N 个最佳匹配项,请尝试以下代码:

// choose double here if you are worried about precision!
#define intermediatePrecision float
//#define intermediatePrecision double
//
void NBestMatches(cv::Mat descriptors1, cv::Mat descriptors2, unsigned int n, std::vector<std::vector<float> > & distances, std::vector<std::vector<int> > & indices)
{
// TODO: check whether descriptor dimensions and types are the same for both!

// clear vector
// get enough space to create n best matches
distances.clear();
distances.resize(descriptors1.rows);
indices.clear();
indices.resize(descriptors1.rows);

for(int i=0; i<descriptors1.rows; ++i)
{
// references to current elements:
std::vector<float> & cDistances = distances.at(i);
std::vector<int> & cIndices = indices.at(i);
// initialize:
cDistances.resize(n,FLT_MAX);
cIndices.resize(n,-1); // for -1 = "no match found"

// now find the 3 best matches for descriptor i:
for(int j=0; j<descriptors2.rows; ++j)
{
intermediatePrecision euclideanDistance = 0;
for( int dim = 0; dim < descriptors1.cols; ++dim)
{
intermediatePrecision tmp = descriptors1.at<float>(i,dim) - descriptors2.at<float>(j, dim);
euclideanDistance += tmp*tmp;
}
euclideanDistance = sqrt(euclideanDistance);

float tmpCurrentDist = euclideanDistance;
int tmpCurrentIndex = j;

// update current best n matches:
for(unsigned int k=0; k<n; ++k)
{
if(tmpCurrentDist < cDistances.at(k))
{
int tmpI2 = cIndices.at(k);
float tmpD2 = cDistances.at(k);

// update current k-th best match
cDistances.at(k) = tmpCurrentDist;
cIndices.at(k) = tmpCurrentIndex;

// previous k-th best should be better than k+1-th best //TODO: a simple memcpy would be faster I guess.
tmpCurrentDist = tmpD2;
tmpCurrentIndex =tmpI2;
}
}


}
}

}

它计算第一个描述符与第二个描述符的每个关键点的 N 个最佳匹配。因此,如果您想对相同的关键点执行此操作,您将设置为 descriptors1 = descriptors2 ion 您的调用,如下所示。 记住:函数不知道两个描述符集是相同的,所以第一个最佳匹配(或至少一个)将始终是距离为 0 的关键点本身!如果使用结果,请记住这一点!

下面是生成类似于上述图像的示例代码:

int main()
{
cv::Mat input = cv::imread("../inputData/MultiLena.png");

cv::Mat gray;
cv::cvtColor(input, gray, CV_BGR2GRAY);

cv::SiftFeatureDetector detector( 7500 );
cv::SiftDescriptorExtractor describer;

std::vector<cv::KeyPoint> keypoints;

detector.detect( gray, keypoints );

// draw keypoints
cv::drawKeypoints(input,keypoints,input);



cv::Mat descriptors;
describer.compute(gray, keypoints, descriptors);

int n = 4;
std::vector<std::vector<float> > dists;
std::vector<std::vector<int> > indices;

// compute the N best matches between the descriptors and themselves.
// REMIND: ONE best match will always be the keypoint itself in this setting!
NBestMatches(descriptors, descriptors, n, dists, indices);

for(unsigned int i=0; i<dists.size(); ++i)
{
for(unsigned int j=0; j<dists.at(i).size(); ++j)
{
if(dists.at(i).at(j) < 0.05)
cv::line(input, keypoints[i].pt, keypoints[indices.at(i).at(j)].pt, cv::Scalar(255,255,255) );
}
}

cv::imshow("input", input);
cv::waitKey(0);

return 0;
}

关于c++ - 如何在opencv中找到单个图像关键点之间的欧氏距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26543880/

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