【测量】知识点
测量的核心是在高精度的定位基础上,通过数学方法计算几何尺寸。
1. 亚像素定位算法 (Sub-pixel Localization)
这是高精度测量的基石,目标是将特征点(如边缘、角点)的定位精度突破物理像素的限制,达到0.1甚至0.01像素的级别。
基于矩的方法 (Moment-based)
-
原理: 利用灰度图像的灰度分布矩来计算灰度重心。对于边缘,通过计算边缘附近区域的灰度重心来亚像素定位边缘位置。
-
公式(一维边缘灰度重心): sub_pixel_x = Σ(x * I(x)) / Σ(I(x)),其中x是像素坐标,I(x)是灰度值。
-
特点: 计算速度快,适用于光斑、刀边等特征的定位。
-
优点: 计算非常快,适用于实时系统。
-
缺点: 假设光条灰度分布是对称的,如果分布不对称(如受噪声干扰),精度会下降。
-
改进: 可以先对profile进行高斯平滑,再计算重心,以提高抗噪性。
-
示例:“在测量芯片焊球高度的项目中,需要亚像素精度定位焊球顶点。我使用了灰度重心法对激光线扫图像中的激光光条中心进行提取。首先通过高斯滤波降噪,然后通过简单的阈值分割粗定位光条区域,最后在每一列像素上计算该区域的灰度重心,作为光条中心的亚像素坐标。这种方法将我们的定位重复精度从1个像素稳定提升到了0.2个像素以内。”
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>/*** @brief 使用灰度重心法提取激光线的亚像素中心坐标(针对单行或单列)* @param profile 输入的灰度剖面数据(可以是单行或单列的像素灰度值)* @return 亚像素精度的中心位置*/
double calculateSubpixelCenter(const cv::Mat& profile) {double sumIntensity = 0.0;double weightedSum = 0.0;// 确保profile是单行或单列的向量for (int i = 0; i < profile.cols; i++) { double intensity = profile.at<uchar>(0, i); // 获取灰度值sumIntensity += intensity;we