)
Steger 线提取算法是工业视觉中最经典的亚像素级线中心检测算法之一在很多视觉库包括HALCON中用于检测激光结构光中心线细线wire / crack / stripe条纹中心光学干涉条纹其特点亚像素精度0.01 ~ 0.1 pixel抗噪声强适合细线 / 光条一、为什么要用 Steger 算法假设有一条激光线##############################我们真正想要的是----------并且要求亚像素精度Steger算法就是解决如何从灰度图中找到一条亮线(或暗线)真正的中心。二、Steger 算法核心思想核心思想利用二阶导数Hessian矩阵寻找线结构中心。线中心 灰度函数在法线方向上的极值点。直观理解一条亮线的灰度分布中心位置* * * * * * *梯度 0二阶导数 0所以一阶导数 0二阶导数最大三、数学模型计算 Hessian 矩阵求特征值和特征向量确定线方向线法线方向n eigenvector(λ1)这就是光条垂直方向亚像素定位关键我们沿着法线方向寻找真正中心。几何理解非常重要假设光条横截面* * * * * * *中心点梯度 0但采样点可能在pixel centerSteger通过梯度 曲率推算真实中心。四、Steger 算法完整流程完整步骤1 图像高斯平滑2 计算一阶导数3 计算二阶导数4 构造 Hessian5 求特征值和特征向量6 判断线结构7 沿法线方向计算 t8 得到亚像素中心流程图Image↓Gaussian↓Gradient↓Hessian↓Eigenvalue↓Line condition↓Subpixel offset↓Center line五、OpenCV 和HalconOpenCVOpenCV没有官方函数但可以实现步骤OpenCV 没有内置 Steger 算法但可以通过以下步骤实现对图像做高斯滤波Gaussian求梯度SobelSobel非极大值抑制找到边缘像素沿梯度方向做三点抛物线拟合求亚像素中心核心代码Mat Lxx, Lxy, Lyy; Sobel(img, Lxx, CV_64F, 2, 0); Sobel(img, Lyy, CV_64F, 0, 2); Sobel(img, Lxy, CV_64F, 1, 1);然后计算eigenvalues再算t offsetHalcon在HALCON中直接封装为算子lines_gaussread_image (Image, laser) lines_gauss (Image, Lines, 1.5, 10, 20, light, true, bar-shaped, true) dev_display (Lines)参数含义sigma高斯尺度low低阈值high高阈值sigma 参数非常关键dev_close_window () read_image (Angio, angio-part) get_image_size (Angio, Width, Height) dev_open_window (0, 0, 3 * Width / 2, 3 * Height / 2, black, WindowID) dev_display (Angio) dev_set_color (blue) MaxLineWidth : 8 Contrast : 12 calculate_lines_gauss_parameters (MaxLineWidth, [Contrast,0], Sigma, Low, High) lines_gauss (Angio, Lines, Sigma, Low, High, dark, true, parabolic, true) count_obj (Lines, Number) dev_update_pc (off) dev_update_var (off) for I : 1 to Number by 1 select_obj (Lines, Line, I) get_contour_xld (Line, Row, Col) get_contour_attrib_xld (Line, angle, Angle) get_contour_attrib_xld (Line, width_left, WidthL) get_contour_attrib_xld (Line, width_right, WidthR) * To display the lines, the point at which the gray value drops to * 25% of the contrast between the line and the background will be * displayed. This point is given by sqrt(3/4) for the parabolic * line model. RowR : Row cos(Angle) * WidthR * sqrt(0.75) ColR : Col sin(Angle) * WidthR * sqrt(0.75) RowL : Row - cos(Angle) * WidthL * sqrt(0.75) ColL : Col - sin(Angle) * WidthL * sqrt(0.75) dev_set_color (red) dev_display (Line) dev_set_color (green) disp_polygon (WindowID, RowL, ColL) disp_polygon (WindowID, RowR, ColR) endfor六、总结优点亚像素精度高抗噪声适合细线缺点计算量大需要选择σ一张图理解 Steger亮线灰度 * * * * * * * pixel grid | | | | | | | * | | | | | | | | 真实中心 | | | | | | | o| | | | | | | | o 亚像素中心Q1 为什么用 Hessian因为线结构是二阶结构边缘一阶导数线二阶导数Q2 为什么 λ1 λ2线法线方向曲率大线方向曲率小Q3 Steger 和 Canny 区别算法检测Canny边缘Steger线中心