3、检测框中心计算:如何从检测框的左上角坐标和宽高计算中心点,坐标系定义与像素坐标转换
在机器人目标跟随任务中,检测模型输出的原始信息通常是目标检测框的四个参数:左上角横坐标 \(x\)、左上角纵坐标 \(y\)、框宽度 \(w\)、框高度 \(h\)。然而,机器人底盘或云台进行跟随控制时,真正需要的是目标在图像平面中的中心位置,以及该中心点相对于图像中心(或相机光轴)的偏移量。这个偏移量经过坐标转换后,才能转化为机器人转向或云台转动的控制指令。因此,检测框中心计算是整个目标跟随链路中承上启下的关键环节——它连接了“感知输出”与“运动控制”。
3.1 核心原理:图像坐标系与检测框参数的含义
在计算机视觉领域,尤其是使用 OpenCV、YOLO 系列或 TensorRT 部署时,图像坐标系遵循左上角原点、x 轴向右、y 轴向下的约定。这与数学中常见的笛卡尔坐标系(原点在左下角、y 轴向上)不同,初学者极易混淆。检测模型输出的 (x, y, w, h) 中,x 和 y 表示检测框左上角顶点在图像中的像素位置,w 和 h 分别表示框的像素宽度和高度。这里的像素坐标是离散的,最小单位为 1 个像素,但计算出的中心点坐标可以是浮点数(例如 cx=215.7),这在后续控制中是被允许且更精确的。
中心点计算公式非常简单:cx = x + w / 2,cy = y + h / 2。从几何角度看,这是矩形对角线交点的坐标。但为什么需要单独强调这个计算?因为在机器人跟随中,我们真正关心的是目标中心与图像中心(即相机光轴在图像上的投影点)之间的偏差。如果直接用左上角坐标做控制,当目标大小变化时,即使目标中心没有移动,左上角坐标也会变化,导致控制不稳定。因此,必须先计算出稳定的中心点,再与图像中心做差。
3.2 判断方法与操作流程:从检测输出到控制输入
在实际工程中,从检测框到控制指令需要经过一系列坐标变换。以下是一个标准流程,适用于大多数基于视觉的机器人跟随系统:
- 获取检测输出:从模型推理结果中解析出目标类别、置信度以及检测框参数 (x, y, w, h)。注意,不同框架的输出格式可能不同,例如 YOLOv5 的 txt 格式为
class x_center y_center width height(归一化坐标),而 OpenCV 的cv2.dnn输出为left top right bottom。需要先统一转换为左上角+宽高格式。 - 计算中心点像素坐标:使用公式
cx = x + w / 2,cy = y + h / 2。如果输入是归一化坐标,则需要乘以图像宽高:cx = x_center * W_img,cy = y_center * H_img。 - 计算图像中心坐标:图像中心为
(W_img / 2, H_img / 2)。例如 640×480 的图像,中心为 (320, 240)。 - 计算偏移量:
dx = cx - W_img / 2,dy = cy - H_img / 2。dx 为正表示目标在图像右侧,机器人需要右转;dy 为正表示目标在图像下方,云台需要下俯。 - 归一化(可选):为了消除不同分辨率的影响,可以将偏移量除以图像宽度或高度,得到 [-0.5, 0.5] 范围内的归一化误差,便于 PID 参数整定。
| 步骤 | 输入 | 操作 | 输出 |
|---|---|---|---|
| 1 | 模型输出 (x, y, w, h) | 格式校验与转换 | 左上角+宽高 (像素) |
| 2 | (x, y, w, h) | cx = x + w/2; cy = y + h/2 | 中心点 (cx, cy) |
| 3 | 图像尺寸 (W, H) | img_cx = W/2; img_cy = H/2 | 图像中心 |
| 4 | (cx, cy), (img_cx, img_cy) | dx = cx - img_cx; dy = cy - img_cy | 像素偏移量 |
| 5 | dx, dy, W, H | norm_dx = dx / W; norm_dy = dy / H | 归一化偏移量 |
3.3 案例拆解:基于 YOLOv5 的机器人跟随实现
下面通过一个具体案例展示从检测框到 PID 控制输入的完整计算过程。假设我们使用 YOLOv5s 模型,输入图像尺寸为 640×480,检测到目标“person”的归一化输出为:class=0, x_center=0.55, y_center=0.45, width=0.2, height=0.4。
第一步:转换为像素坐标。左上角 x = (0.55 - 0.2/2) × 640 = 0.45 × 640 = 288;左上角 y = (0.45 - 0.4/2) × 480 = 0.25 × 480 = 120;框宽 w = 0.2 × 640 = 128;框高 h = 0.4 × 480 = 192。因此检测框为 (288, 120, 128, 192)。
第二步:计算中心点。cx = 288 + 128/2 = 288 + 64 = 352;cy = 120 + 192/2 = 120 + 96 = 216。目标中心在 (352, 216)。
第三步:计算偏移量。图像中心为 (320, 240)。dx = 352 - 320 = 32 像素;dy = 216 - 240 = -24 像素。dx 为正,说明目标偏右,机器人需要向右转;dy 为负,说明目标偏上,云台需要上仰。
第四步:归一化与 PID 输入。norm_dx = 32 / 640 = 0.05;norm_dy = -24 / 480 = -0.05。将这两个值输入 PID 控制器,比例系数 Kp=100,则转向角速度 = 0.05 × 100 = 5 rad/s(示例值)。
cx = x + w / 2.0 而不是 cx = x + w // 2。另外,当检测框非常小(例如 w=3 像素)时,中心点计算仍然有效,但可能受到检测框抖动的影响,此时可以加入低通滤波或卡尔曼滤波平滑中心点轨迹。
3.4 常见误区与总结复盘
误区一:混淆坐标系方向。 图像坐标系 y 轴向下,因此 dy 为正表示目标在图像下方。如果按照笛卡尔坐标系理解,会导致云台俯仰方向反转。解决方法是始终以 OpenCV 的坐标约定为准,并在代码注释中明确标注。
误区二:忽略图像缩放。 如果检测前对图像进行了 resize,那么检测框坐标是基于缩放后图像的。必须将坐标映射回原始图像尺寸,或者统一在缩放后的尺寸下计算偏移量。否则,控制量会与实际视觉范围不匹配。
误区三:中心点计算后不做限幅。 当目标部分离开画面时,检测框可能超出图像边界,导致 cx 或 cy 超出 [0, W] 或 [0, H] 范围。此时计算出的偏移量可能非常大,导致 PID 输出饱和。建议对 dx、dy 做限幅处理,例如限制在 [-W/2, W/2] 范围内。
误区四:将像素偏移直接当作物理角度。 像素偏移量是二维平面上的距离,而机器人转向需要的是角度。严格来说,需要利用相机内参(焦距 f)将像素偏移转换为角度偏移:angle_yaw = atan(dx / f)。但在简单跟随任务中,如果相机视角较窄且目标距离较远,可以近似认为像素偏移与角度成正比,直接使用像素偏移作为 PID 输入。
cx_filtered = alpha * cx + (1 - alpha) * cx_filtered_prev,其中 alpha 取 0.3~0.5。这能有效减少目标中心的高频抖动,提升跟随的平滑性。
总结复盘: 检测框中心计算虽然公式简单,但在机器人控制中扮演着“感知-控制”接口的角色。核心要点包括:明确图像坐标系定义(原点左上、y 轴向下);使用浮点数计算中心点;计算与图像中心的偏移量作为控制误差;根据实际需求决定是否归一化;注意检测框超出边界、图像缩放、坐标系混淆等工程陷阱。掌握这些细节,才能让目标跟随系统在真实场景中稳定运行。