本视觉测量系统采用单目视觉技术实现目标物距离和几何尺寸的双重测量。系统首先通过深度学习模型(PaddleDetection)快速定位目标物(带黑框的A4纸),利用目标物在图像中的像素高度与物理距离的二次函数关系,解算目标到基准线的距离D。该函数模型通过实验标定获得,测量范围100-200cm,精度达±2cm。
对于内部几何尺寸测量,系统创新性地采用中心区域聚焦策略:在检测到的目标区域内,自动裁剪中心80%区域排除边框干扰,通过自适应阈值处理和形态学滤波增强几何特征。随后提取四边形轮廓,基于图像中心优选算法锁定目标几何图形,最后利用A4纸标准尺寸(210×297mm)与像素尺寸的比例关系,精确换算内部几何图形的实际边长x,测量误差≤0.6cm。
系统严格满足竞赛实时性要求,从图像采集到结果显示完整流程耗时<1s。关键创新点包括:1)动态阈值窗口技术,根据目标尺寸自动调整处理参数;2)几何特征三级过滤机制(顶点数/宽高比/中心距离);3)松耦合模块化设计,为后续扩展三角形/圆形测量预留接口。整套方案在200-1000lux照度下稳定工作,已通过基本要求三项测试验证。
模型选择:采用PaddleDetection深度学习框架。
检测对象:A4纸目标物(带2cm黑色边框)。
关键参数:model.SetThreshold(0.7, 0.3);
输出:检测到的A4纸位置。
距离测量基于目标物高度像素值与实际距离的二次函数关系,具体的实现代码如下:
double reverseToDistance(double y) { // 构造方程:a*x^2 + b*x + (c - y) = 0 double A = a; double B = b; double C = c - y; double discriminant = B * B - 4 * A * C; // 判别式小于0,无实数解 if (discriminant < 0) { return -1.0; // 表示无效解 } double sqrt_d = std::sqrt(discriminant); double x1 = (-B + sqrt_d) / (2 * A); double x2 = (-B - sqrt_d) / (2 * A); // 选择在合理范围 [1.0, 2.0] 内的解 bool x1_valid = (x1 >= 1.0 && x1 <= 2.0); bool x2_valid = (x2 >= 1.0 && x2 <= 2.0); if (x1_valid && x2_valid) { // 如果两个解都有效,选择更接近趋势的(通常 x2 更小,x1 更大,看哪个更合理) // 实际上由于 a > 0, b < 0,通常 x2 是更合理的(较小的根) // 但根据抛物线形状,我们取更靠近数据趋势的 // 可以打印调试,但通常取接近 1.0~2.0 之间的 return x2; // 通常 x2 是物理意义正确的(递减趋势) } else if (x1_valid) { return x1; } else if (x2_valid) { return x2; } else { return -1.0; // 无有效解 }}
物理原理:目标物表观尺寸与距离成反比。
标定方式:通过实验数据拟合参数
几何特征提取是视觉测量系统的核心环节,采用多级处理流程确保测量精度。系统首先在目标检测获取的A4纸区域内,动态裁剪中心80%区域以排除2cm黑色边框干扰,随后进行自适应二值化处理:基于目标尺寸自动计算阈值窗口(取目标短边的1/4且保证为奇数),采用高斯加权模式增强内部几何图形与背景的对比度。该自适应策略能有效应对100-200cm距离范围内目标表观尺寸的变化。
轮廓处理阶段采用三级过滤机制:先通过形态学闭运算消除噪点,再提取所有潜在轮廓;然后执行严格几何验证:1) 多边形逼近顶点数必须为4(四边形) 2) 宽高比限制在0.5-2.0范围 3) 轮廓面积大于40像素。最终通过中心优选算法:计算各轮廓点到图像中心的欧氏距离,选取距离平方和最小的轮廓作为目标几何图形,该策略可有效减少透视畸变影响,确保在物面平行于成像平面时获得最优测量结果。
部分核心代码如下:
// 提取 ROIcv::Mat roi_frame = input_mat(safe_box);if (roi_frame.empty()) continue;// 转灰度并二值化提取黑色区域cv::Mat roi_gray, roi_binary;cv::cvtColor(roi_frame, roi_gray, cv::COLOR_BGR2GRAY);// 关键修改1:使用自适应阈值处理中心区域int block_size = std::min(safe_box.width, safe_box.height) / 4;if (block_size % 2 == 0) block_size++; // 确保为奇数cv::adaptiveThreshold(roi_gray, roi_binary, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY_INV, block_size, 5);// 关键修改2:创建中心区域ROI(忽略边缘黑边)int margin = std::min(safe_box.width, safe_box.height) / 5; // 忽略20%的边缘区域cv::Rect center_roi(margin, margin, roi_binary.cols - 2 * margin, roi_binary.rows - 2 * margin);if (center_roi.width <= 0 || center_roi.height <= 0) continue;cv::Mat roi_center = roi_binary(center_roi);// 形态学操作去噪cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));cv::morphologyEx(roi_center, roi_center, cv::MORPH_CLOSE, kernel);// 查找轮廓(仅在中心区域)std::vectorvectorPoint>> contours;cv::findContours(roi_center, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
目标物的尺寸计算原理是基于相似理论的比例来进行换算的,核心代码如下:
// A4纸实际尺寸(毫米)const double A4_WIDTH_MM = 210.0;const double A4_HEIGHT_MM = 297.0;cv::Rect a4_rect = results[0].box; double a4_width_px = a4_rect.width;double a4_height_px = a4_rect.height;// 计算实际尺寸比例double scale_x = A4_WIDTH_MM / a4_width_px;double scale_y = A4_HEIGHT_MM / a4_height_px;// 计算内部矩形的实际尺寸(单位:毫米)double inner_width_mm = inner_width_px * scale_x;double inner_height_mm = inner_height_px * scale_x;double inner_length_mm = ((inner_width_mm + inner_height_mm) / 2) + 5; inner_length_cm = inner_length_mm / 10.0; // 转换为厘米
处理速度:平均推理时间:<100ms,端到端延迟:<1s
测量精度:
| 参数 | 要求精度 | 实测精度 |
|---|---|---|
| 距离D | <= 5cm | <= 2cm |
| 边长x | <= 1cm | <= 0.6cm |
全部0条评论
快来发表一下你的评论吧 !