提前道歉,我主要使用 Python,所以我会避免引用 C++ 让自己尴尬。
DenseFeatureDetector 使用 KeyPoints 填充向量以传递给计算特征描述符。这些关键点有一个点向量和它们的比例集。在文档中,scale 是关键点的像素半径。
关键点在传递给 DenseFeatureVector 的图像矩阵的宽度和高度上均匀分布。
现在讨论论点:
initFeatureScale
以像素为单位设置初始 KeyPoint 特征半径(据我所知,这没有影响)
featureScaleLevels
我们希望在其上制作关键点的尺度数
featureScaleMuliplier
initFeatureScale 在 featureScaleLevels 上的缩放调整,这种缩放调整也可以应用于边界(initImgBound)和步长(initxystep)。因此,当我们设置 featureScaleLevels>1 时,这个乘数将应用于连续的尺度,以调整特征尺度、步长和图像周围的边界。
initXyStep
以像素为单位移动列和行步长。我希望不言自明。
initImgBound
要忽略图像周围的行/列边界区域(像素),因此 initImgBound 为 10 的 100x100 图像将在图像的中心 80x80 部分创建关键点。
varyXyStepWithScale
布尔值,如果我们有多个 featureScaleLevels,我们是否要使用 featureScaleMultiplier 调整步长。
varyImgBoundWithScale
布尔值,如 varyXyStepWithScale,但应用于边框。
这里是 OpenCV 2.4.3 源代码中检测器.cpp 中的 DenseFeatureDetector 源代码,它可能比我的话解释得更好:
DenseFeatureDetector::DenseFeatureDetector( float _initFeatureScale, int _featureScaleLevels,
float _featureScaleMul, int _initXyStep,
int _initImgBound, bool _varyXyStepWithScale,
bool _varyImgBoundWithScale ) :
initFeatureScale(_initFeatureScale), featureScaleLevels(_featureScaleLevels),
featureScaleMul(_featureScaleMul), initXyStep(_initXyStep), initImgBound(_initImgBound),
varyXyStepWithScale(_varyXyStepWithScale), varyImgBoundWithScale(_varyImgBoundWithScale)
{}
void DenseFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const
{
float curScale = static_cast<float>(initFeatureScale);
int curStep = initXyStep;
int curBound = initImgBound;
for( int curLevel = 0; curLevel < featureScaleLevels; curLevel++ )
{
for( int x = curBound; x < image.cols - curBound; x += curStep )
{
for( int y = curBound; y < image.rows - curBound; y += curStep )
{
keypoints.push_back( KeyPoint(static_cast<float>(x), static_cast<float>(y), curScale) );
}
}
curScale = static_cast<float>(curScale * featureScaleMul);
if( varyXyStepWithScale ) curStep = static_cast<int>( curStep * featureScaleMul + 0.5f );
if( varyImgBoundWithScale ) curBound = static_cast<int>( curBound * featureScaleMul + 0.5f );
}
KeyPointsFilter::runByPixelsMask( keypoints, mask );
}
您可能期望计算调用会根据 DenseFeatureDetector 生成的关键点,使用相关关键点检测算法(例如角度)计算其他关键点特征。不幸的是,Python 下的 SIFT 并非如此——我没有研究过其他特征检测器,也没有研究过 C++ 中的行为。
另请注意,DenseFeatureDetector 不在 OpenCV 3.2 中(不确定它在哪个版本中被删除)。