F R E A K 特 征 点 匹 配 算 法 介 绍 ( 2 0 2 0 )
- 格式:pdf
- 大小:218.33 KB
- 文档页数:8
近似匹配公式(二)近似匹配公式1. Levenshtein距离(编辑距离)公式•描述:Levenshtein距离用于衡量两个字符串之间的差异程度,即通过添加、删除和替换字符将一个字符串转换为另一个字符串的最小操作次数。
•公式:d[i,j] = min(d[i-1,j]+1, d[i,j-1]+1, d[i-1,j-1]+(s[i]!=t[j]))•例子:比如字符串s为“kitten”,字符串t为“sitting”,计算Levenshtein距离时,最小编辑次数为3次,即将”i”替换为”i”,“e”替换为”i”,“n”替换为”g”。
2. 欧几里得距离公式•描述:欧几里得距离用于衡量两个向量之间的差异程度,即两个向量的欧式距离。
•公式:d = sqrt((x2-x1)^2 + (y2-y1)^2)•例子:比如有两个二维向量A(1, 2)和B(4, 6),计算欧几里得距离时,即d = sqrt((4-1)^2 + (6-2)^2) = sqrt(9+16) = 5。
3. Jaccard相似性系数公式•描述:Jaccard相似性系数用于衡量两个集合之间的相似程度,即两个集合的交集与并集的比值。
•公式:J(A,B) = |A ∩ B| / |A ∪ B|•例子:比如有两个集合A={1, 2, 3}和B={2, 3, 4},计算Jaccard相似性系数时,即J(A,B) = |{2, 3}| / |{1, 2, 3,4}| = 2 / 4 = 。
4. 余弦相似度公式•描述:余弦相似度用于衡量两个向量之间的夹角余弦值,范围在-1到1之间,数值越接近1表示越相似。
•公式:similarity = cos(θ) = (A·B) / (||A|| ||B||)•例子:比如有两个向量A(1, 2)和B(3, 4),计算余弦相似度时,即similarity = (13 + 24) / (sqrt(1^2 + 2^2) * sqrt(3^2 + 4^2)) = (3+8) / (sqrt(5) * sqrt(25)) ≈ 。
三个描述符的比较:SURF,FREAK和BRISK=================分割线=================我认为从事对象识别,图像注册和使用关键点提取的其他领域的开发人员和研究人员可以发现这个帖子很有用。
最近(从2.4.2),一个新的特征描述符算法被添加到OpenCV库中。
据称FREAK描述符优于ORB和SURF描述符,但速度非常快(与ORB相当)。
也有人在我的博客上的评论提到BRISK描述符,这是比SURF更新,更高效。
那么,最后我找到一个时间来比较他们,并发表我的研究成果。
这篇文章与我过去的OpenCV比较报告非常相似。
虽然这些报告是多年前发表的,但它们还是有些实际的。
对于这个测试,我决定从头开始重写整个测试框架。
源代码即将可用。
但现在,让我解释我做了什么来找到最好的三种算法。
将图像转换为描述符的主要目标是什么?从像素域移动到更紧凑的表示形式相同的数据。
此外,我们希望我们的表示是旋转和比例不变的(例如,当源图像旋转或缩放时,表示保持不变或略微变化)。
SURF,FREAK和BRISK描述符宣称它们是旋转和尺度不变的。
========================分割线==============================就像在OpenCV比较报告中一样,测试应用程序与测试模式图像一起工作。
我们有四个基本的转换:旋转,缩放,模糊和亮度调整。
这里是如何旋转转换类看起来像:class ImageRotationTransformation : public ImageTransformationImageRotationTransformation(float startAngleInDeg, float endAngleInDeg, float step, cv::Point2f rotationCenterInUnitSpace): ImageTransformation("Rotation"), m_startAngleInDeg(startAngleInDeg), m_endAngleInDeg(endAngleInDeg), m_step(step),m_rotationCenterInUnitSpace(rotationCenterInUnitSpace) -- Fill the argumentsfor (float arg = startAngleInDeg; arg = endAngleInDeg; arg += step)m_args.push_back(arg);virtual std::vector getX() constreturn m_args;virtual void transform(float t, const cv::Mat source, cv::Mat result) constcv::Point2f center(source.cols * m_rotationCenterInUnitSpace.x, source.cols * m_rotationCenterInUnitSpace.y);cv::Mat rotationMat = cv::getRotationMatrix2D(center, t, 1);cv::warpAffine(source, result, rotationMat, source.size());private:float m_startAngleInDeg;float m_endAngleInDeg;float m_step;cv::Point2f m_rotationCenterInUnitSpace;std::vector m_args;其他类型的转换看起来相似。
但它显示了这个想法。
========================分割线==============================FeatureAlgorithm正如你可能知道的,当处理描述符时我们需要三个组件:特征检测器 - 从cv :: FeatureDetector派生的类,实现特定的检测算法。
例如,cv :: SurfFeatureDetector实现SURF文件中描述的检测算法。
描述符提取器 - 从cv :: DescriptorExtractor派生的类。
它从传递的关键点计算描述符。
cv :: SurfDescriptorExtractor将计算机的SURF描述符。
描述符匹配器 - cv :: FlannBasedMatcher类的cv :: BFMatcher的一个实例用于匹配两组描述符。
我们将这三个对象存储在FeatureAlgorithm类中:?class FeatureAlgorithmFeatureAlgorithm(std::string name, cv::FeatureDetector* d, cv::DescriptorExtractor* e, cv::DescriptorMatcher* m);std::string name;bool knMatchSupported;bool extractFeatures(const cv::Mat image, Keypoints kp, Descriptors desc) const;void matchFeatures(const Descriptors train, const Descriptors query, Matches matches) const;void matchFeatures(const Descriptors train, const Descriptors query, int k, std::vector matches) const;private:cv::FeatureDetector* detector;cv::DescriptorExtractor* extractor;cv::DescriptorMatcher* matcher;========================分割线==============================测试程序主要测试功能采用FeatureAlgorithm,Transformation和测试图像。
作为输出,我们返回每个运行的匹配统计信息列表。
这是一个简短的序列:将输入图像转换为灰度检测关键点并从输入灰度图像中提取描述符使用传递的转换算法生成所有变换的图像对于每个变换的图像:检测关键点并提取描述符匹配列车描述符和查询使用单应性估计将分段匹配到内点和外点计算统计数据(消耗时间,匹配百分比,正确匹配的百分比等)主循环使用OpenMP并行,在我的四核酷睿i5上,在测试的同时加载100%的所有内核。
特征算法:?algorithms.push_back(FeatureAlgorithm("SURF-BRISK-BF", new cv::SurfFeatureDetector(),new cv::BriskDescriptorExtractor(),new cv::BFMatcher(cv::NORM_HAMMING, true)));algorithms.push_back(FeatureAlgorithm("SURF-FREAK-BF", new cv::SurfFeatureDetector(),new cv::FREAK(),new cv::BFMatcher(cv::NORM_HAMMING, true)));algorithms.push_back(FeatureAlgorithm("SURF-SURF-BF", new cv::SurfFeatureDetector(),new cv::SurfDescriptorExtractor(),new cv::BFMatcher(cv::NORM_L2, true)));图像转换:transformations.push_back(new GaussianBlurTransform(9));transformations.push_back(newBrightnessImageTransform(-127, +127, 10));transformations.push_back(new ImageRotationTransformation(0, 360, 10, cv::Point2f(0.5f,0.5f)));transformations.push_back(new ImageScalingTransformation(0.25f, 2.0f, 0.1f));========================分割线==============================计算以下指标:匹配百分比?- 分割匹配的商数计算关键点的最小值,以两个百分数计算。
正确匹配的百分比?- 分配正确匹配的商数以百分比计总匹配数。
匹配比例?-匹配百分比*正确匹配百分比。
在所有图表中,我将使用Y轴的“匹配比率”(百分比)值。
========================分割线==============================运行所有测试后,我们收集每个转换和算法的统计信息。
特定转换算法的报表如下所示:Argument SURF-BRISK-BF SURF-FREAK-BF SURF-SURF-BF1 100 88.5965 82.67522 100 86.9608 79.16893 100 85.6069 70.67314 100 85.0897 64.90575 100 83.1528 59.47766 100 85.1648 58.97637 100 88.6447 59.30668 100 94.9109 64.80199 100 95.9707 69.1154为了制作图表,我使用Google Spreadsheets导入CSV表格并生成图表。
您可以在这里找到这个电子表格:?OpenCV2.4.9功能比较报告。
========================分割线=======================================================分割线==============================说明:原博文打开慢,请耐心等待,可能话需要翻墙。
===========================END========================== ==δmax=9.75δ,δmin=13.67δ,其中δ为特征点的尺度。