以 sub-pixel 的精度稳健地找到图像块的局部最大值
Robustly finding the local maximum of an image patch with sub-pixel accuracy
我正在用 C 语言开发 SLAM 算法,我已经实现了 FAST 角点查找方法,该方法为我提供了图像中的一些强关键点。下一步是以 sub-pixel 的精度获得关键点的中心,因此我在每个关键点周围提取一个 3x3 的补丁,并对二维二次方程进行最小二乘拟合:
其中 f(x,y) 是每个像素的角点显着性度量,类似于 original paper 上提出的 FAST 分数,但经过修改后也提供非角点像素的显着性度量。
和最小二乘:
其中 为估计参数。
我现在可以通过将梯度设为零来计算拟合二次方程的峰值位置,从而实现我最初的目标。
问题出现在一些极端情况下,其中局部峰值更接近 window 的边缘,导致拟合具有低残差但二次方式的峰值在 [=63= 之外].
一个例子:
拟合二次方程的角点显着性和轮廓:
作为 3D 网格的显着性(蓝色)和拟合(红色):
这个例子的数值是(row-major排序):
[336, 522, 483, 423, 539, 153, 221, 412, 234]
由此产生的 (2.6, -17.1) 子像素中心是错误的。
如何约束拟合,使中心位于 window 范围内?
我对寻找亚像素峰值的替代方法持开放态度。
显而易见的答案是拒绝离散最大值不在中心的 3x3(或 5x5,无论您使用什么)框。换句话说,仅使用二次近似来细化必须位于框内的最大值的位置。
更一般地说,在这种情况下,首先要问的问题不是 "How do I constrain my model-fitting procedure to shoehorn a solution for this edge case?",而是
"Does my model apply to this edge case?" 和 "Is this edge case even worth spending time on, or can I just ignore it?"
我尝试使用自己的代码将 2D 二次函数拟合到 3x3 值,使用稳定的最小二乘求解算法,并且还找到了域外的最大值。 3x3 数据块与二次函数不匹配,因此拟合没有用。
将 2D 二次方程拟合到 3x3 邻域需要一定程度的数据平滑度,这在您的 FAST 输出中似乎没有。
还有许多其他方法可以找到最大值的子像素位置。我喜欢的一个是 "separable" 二次函数的拟合,因为它更稳定且计算量更少。简而言之,您将二次函数拟合到一个维度中局部最大值周围的三个值,然后在另一个维度中拟合另一个。这不是用 9 个值求解 6 个参数,而是用 3 个值求解 3 个参数,两次。只要中心像素大于或等于 4-连通邻域中的所有像素,解决方案就保证稳定。
z1 = [f(-1,0), f(0,0), f(1,0)]^T
[1,-1,0]
X = [0,0,0]
[1,1,0]
solve: X b1 = z1
和
z2 = [f(0,-1), f(0,0), f(0,1)]^T
[1,-1,0]
X = [0,0,0]
[1,1,0]
solve: X b2 = z2
现在您从 b1
获得质心的 x 坐标,从 b2
获得 y 坐标。
我正在用 C 语言开发 SLAM 算法,我已经实现了 FAST 角点查找方法,该方法为我提供了图像中的一些强关键点。下一步是以 sub-pixel 的精度获得关键点的中心,因此我在每个关键点周围提取一个 3x3 的补丁,并对二维二次方程进行最小二乘拟合:
其中 f(x,y) 是每个像素的角点显着性度量,类似于 original paper 上提出的 FAST 分数,但经过修改后也提供非角点像素的显着性度量。
和最小二乘:
其中 为估计参数。
我现在可以通过将梯度设为零来计算拟合二次方程的峰值位置,从而实现我最初的目标。
问题出现在一些极端情况下,其中局部峰值更接近 window 的边缘,导致拟合具有低残差但二次方式的峰值在 [=63= 之外].
一个例子:
拟合二次方程的角点显着性和轮廓:
作为 3D 网格的显着性(蓝色)和拟合(红色):
这个例子的数值是(row-major排序):
[336, 522, 483, 423, 539, 153, 221, 412, 234]
由此产生的 (2.6, -17.1) 子像素中心是错误的。
如何约束拟合,使中心位于 window 范围内?
我对寻找亚像素峰值的替代方法持开放态度。
显而易见的答案是拒绝离散最大值不在中心的 3x3(或 5x5,无论您使用什么)框。换句话说,仅使用二次近似来细化必须位于框内的最大值的位置。
更一般地说,在这种情况下,首先要问的问题不是 "How do I constrain my model-fitting procedure to shoehorn a solution for this edge case?",而是 "Does my model apply to this edge case?" 和 "Is this edge case even worth spending time on, or can I just ignore it?"
我尝试使用自己的代码将 2D 二次函数拟合到 3x3 值,使用稳定的最小二乘求解算法,并且还找到了域外的最大值。 3x3 数据块与二次函数不匹配,因此拟合没有用。
将 2D 二次方程拟合到 3x3 邻域需要一定程度的数据平滑度,这在您的 FAST 输出中似乎没有。
还有许多其他方法可以找到最大值的子像素位置。我喜欢的一个是 "separable" 二次函数的拟合,因为它更稳定且计算量更少。简而言之,您将二次函数拟合到一个维度中局部最大值周围的三个值,然后在另一个维度中拟合另一个。这不是用 9 个值求解 6 个参数,而是用 3 个值求解 3 个参数,两次。只要中心像素大于或等于 4-连通邻域中的所有像素,解决方案就保证稳定。
z1 = [f(-1,0), f(0,0), f(1,0)]^T
[1,-1,0]
X = [0,0,0]
[1,1,0]
solve: X b1 = z1
和
z2 = [f(0,-1), f(0,0), f(0,1)]^T
[1,-1,0]
X = [0,0,0]
[1,1,0]
solve: X b2 = z2
现在您从 b1
获得质心的 x 坐标,从 b2
获得 y 坐标。