Steger算法(Line_Gauss)-光条中心线提取(基于Hessian矩阵)

本文详细介绍了Steger算法如何利用Hessian矩阵和泰勒多项式提取光条中心线,涉及Hessian矩阵的概念、泰勒展开在图像优化中的应用,以及如何通过一阶导数零点确定中心点和亚像素坐标。通过实例展示了高斯函数在拟合实际光条模型中的关键作用,以及文献[1][2]的参考价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Steger算法(Line_Gauss)-光条中心线提取(基于Hessian矩阵)

算法背景介绍

在线结构光视觉传感器中,由线激光器发射出的线结构光,在本质上为一个连续且具有一定厚度的空间光平面,而在目标表面上所形成的具有一定宽度的光条特征,即为该光平面与目标表面相交而成的交线。在该空间光平面的厚度方向上,光强近似服从高斯分布,因而在摄像机采集到的光条图像中,在沿着光条宽度的方向或光条的法线方向上,其灰度也会呈现出类似的高斯分布特点,即光条中心的灰度值大而光条边缘的灰度值小,如图1所示,因而光条中心线的提取任务就是要找到图像中的光条灰度的高斯分布中心。

在这里插入图片描述

如果熟悉Halcon软件的朋友应该对Line_Gauss算法非常了解,该算法的核心其实就是德国 Steger 博士最先提出的基于 Hessian 矩阵的亚像素级光条中心线的提取方法。
Steger算法的基本思路是首先通过 Hessian 矩阵获得光条的法线方向,然后在其法线方向上对像素灰度应用泰勒多项式展开而得到灰度分布函数,进而计算出光条中心的亚像素位置。由于光条特征的灰度在其法线方向上近似为高斯分布,因而越靠近光条中心点的像素,其灰度值越大。因此,对该法线方向上的灰度分布函数的二阶泰勒多项式求取极值,即可得到光条在该法线方向上的中心点坐标。

Hessian 矩阵与泰勒多项式

那么Hessian 矩阵是什么呢?在工程优化问题中,目标函数通常会以非线性多元函数的形式出现,这种函数形式非常复杂,不便于后续的进一步处理。因此,为了使问题简化,经常会将目标函数在某点的邻域内展开成泰勒多项式的形式,以此来近似或逼近原目标函数。在这个过程中,以矩阵形式表示的泰勒多项式就会涉及到 Hessian 矩阵,而且利用Hessian 矩阵可以判定多元函数的极值问题。
先来说一下多元函数的 Hessian 矩阵,对于一个实值多元函数 f(x1, x2, …, xn) 来说,如果函数 f 的多阶偏导数均存在,则定义函数 f 的 Hessian 矩阵H(f) 为:
函数f的Hessian矩阵
对于二维离散图像I(u, v) 来说,其 Hessian 矩阵可以表示为
在这里插入图片描述
其中,u、v 分别表示像素的列坐标和行坐标;
I(u, v)即为像素 (u, v) 的灰度,因而可以将I(u, v) 视为该图像的灰度分布函数;Iuu、Iuv和Ivv分别表示二维高斯函数G(u, v)的二阶偏导数与图像I(u, v) 进行卷积运算的结果。

至于为什么要采用高斯函数进行卷积,可以看下一节。

那么回过头来看看泰勒展开,此处可以参考知乎关于多元函数的泰勒展开式的一些介绍和证明: https://zhuanlan.zhihu.com/p/33316479
一元函数在点 x k x_k xk处的泰勒展开式为:
在这里插入图片描述
二元函数在点 ( x k , y k ) (x_k,y_k) (xk,yk)处的泰勒展开式为:
在这里插入图片描述
多元函数(n)在点 ( x k ) (x_k) (xk)处的泰勒展开式为:
在这里插入图片描述
把泰勒展开式写成矩阵的形式,如下图所示,其中的 H ( x k ) H(x_k) H(xk)就是我们上面提到的Hessian矩阵,至此,泰勒展开与Hessian矩阵的联系就描述完成,注意其中的X,它是向量形式。
在这里插入图片描述
下面介绍二维图像中的泰勒展开与Hessian矩阵。对于图像中光条上的任意像素 ( u 0 , v 0 ) (u_0,v_0) (u0,v0),设其法线方向的单位方向向量为 e → = [ e u , e v ] \overrightarrow{e}=[e_u,e_v] e =[eu,ev],在该像素处将光条法线方向上的灰度分布函数 I ( u , v ) I(u,v) I(u,v) 沿方向 e → \overrightarrow{e} e 展开成泰勒多项式的形式,并忽略二阶以上的展开式。因此,光条法线方向上的像素 ( u 0 + t ⋅ e u , v 0 + t ⋅ e v ) (u_0+t·e_u, v_0+t·e_v) (u0+

以下是一个基本的Python实现Steger算法提取线中心的例子: ```python import cv2 import numpy as np def steger_algorithm(img): # 进行高斯平滑以减少噪声 img = cv2.GaussianBlur(img, (5, 5), 0) # 求出图像的梯度 dx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5) dy = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5) mag = np.sqrt(dx ** 2 + dy ** 2) # 二值化图像 thresh = cv2.threshold(mag, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1] # 进行形态学操作 kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) # 计算距离变换 dist = cv2.distanceTransform(thresh, cv2.DIST_L2, 5) dist = cv2.normalize(dist, None, 0, 1.0, cv2.NORM_MINMAX) # 计算Hessian矩阵的特征值 hxx = cv2.Sobel(dx, cv2.CV_64F, 1, 0, ksize=5) hyy = cv2.Sobel(dy, cv2.CV_64F, 0, 1, ksize=5) hxy = cv2.Sobel(dx, cv2.CV_64F, 0, 1, ksize=5) hessian = np.zeros(img.shape[:2] + (2, 2)) hessian[..., 0, 0] = hxx hessian[..., 0, 1] = hxy hessian[..., 1, 0] = hxy hessian[..., 1, 1] = hyy lambda1, lambda2 = cv2.eigen(hessian) # 计算线中心 center = np.zeros_like(img) center[dist > 0.5] = 255 center[lambda2 < 0] = 0 center[lambda1 > 0.01] = 0 return center ``` 以上代码假设输入的图像是灰度图像。它首先进行高斯平滑以减少噪声,然后计算图像的梯度,并将其平方和开方以获得梯度幅值。接下来,它对梯度幅值进行二值化,并通过形态学操作来消除噪声。然后,它计算距离变换,并归一化到0到1之间。接下来,它计算Hessian矩阵的特征值,并使用它们来确定激线的中心。最后,它返回一个二值图像,其中1表示激线的中心。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值