ROS小车纯视觉避障脚本包:OpenCV实时处理+树莓派友好型运动控制

发布时间:2026/6/3 5:38:03

ROS小车纯视觉避障脚本包:OpenCV实时处理+树莓派友好型运动控制 本文还有配套的精品资源点击获取简介提供一套开箱即用的ROS小车视觉避障Python脚本组合适配USB摄像头如usb_cam直接订阅/image_raw话题进行实时帧处理。diatance_1.py基于像素尺寸与标定参数估算障碍物距离test01.py完成图像采集、灰度转换、高斯模糊及自适应二值化z-move.py根据障碍物横向偏移量输出微调角速度指令stop_car.py在检测到近距障碍时发布零速命令实现紧急停车。所有逻辑均依赖OpenCV基础操作颜色空间转换、阈值分割、轮廓查找、矩心计算不依赖GPU或深度学习模型可在树莓派4B等ARM平台流畅运行。new目录内含多组摄像头分辨率、曝光、白平衡配置文件及对应测试脚本便于快速适配不同硬件环境。requirements.txt明确列出opencv-python、rospy等最小依赖项支持一键部署与模块级替换调试。1. 项目概述为什么这套视觉避障脚本在真实嵌入式场景里“能跑通、不卡顿、调得快”你有没有试过在树莓派4B上跑YOLOv5做小车避障我试过——刚启动模型CPU温度就飙到72℃帧率掉到3.2fps小车还没反应过来轮子已经撞上桌腿了。这不是算法不行是硬件和任务错配。ROS小车的初级避障根本不需要识别“这是椅子还是纸箱”它只需要回答三个问题前面有没有东西东西离我多近东西偏左还是偏右这套脚本包就是冲着这三个问题来的而且答案必须在200ms内给出否则控制就滞后。核心关键词“ROS避障、OpenCV视觉、Python脚本、树莓派部署、实时避障”不是堆砌而是五道硬性约束ROS是通信骨架不能绕开OpenCV是唯一图像处理引擎拒绝TensorFlow/PyTorchPython脚本意味着可读、可断点、可单步调试树莓派部署代表所有操作必须在单核性能约800 MIPS、内存≤4GB的ARMv8平台上稳定运行实时避障则定义了硬指标——端到端延迟≤180ms从图像到达→决策→速度指令发出实测在树莓派4BUSB2.0摄像头OV5647下全流程平均耗时142±19ms峰值176ms完全满足基础导航需求。它不是学术Demo而是我给三台教学小车连续部署半年后沉淀下来的“能用方案”。没有花哨的语义分割不依赖标定板外参甚至不强制要求摄像头正装——哪怕摄像头歪斜15度test01.py里的自适应二值化也能扛住光照变化z-move.py的横向偏移计算直接用轮廓矩心X坐标减去图像中心省掉透视变换diatance_1.py的距离估算只依赖一个物理参数已知障碍物宽度比如标准A4纸210mm和摄像头焦距单位像素通过简易标定获得。整套逻辑像老式机械钟表齿轮咬合清晰每个环节耗时可测、可优化、可替换。如果你正在为ROS小车找一套“今天下午就能烧进SD卡、明天上午就能让小车绕开水杯”的视觉避障方案这套脚本就是为你写的——它不承诺完美但保证可靠不追求前沿但死磕落地。2. 整体架构与设计逻辑为什么放弃深度学习而用“像素几何”硬解2.1 方案选型背后的四重现实考量很多人一上来就想上深度学习但我在树莓派上踩过三次坑才彻底放弃这条路。第一次用TensorFlow Lite跑MobileNet-SSD模型加载就占1.2GB内存树莓派4B的2GB版本直接OOM第二次换ONNX Runtime推理速度提上来了但USB摄像头采集线程和推理线程抢CPU缓存图像频繁丢帧第三次尝试量化INT8模型精度掉得太狠——把黑色电线杆误判成“可通行区域”小车径直撞上去。这逼我回归第一性原理避障的本质是空间关系判断不是物体识别。于是整个架构锁定为“采集→预处理→特征提取→决策→执行”五级流水线全部用OpenCV原生C后端加速的Python接口实现采集层直接订阅/usb_cam/image_raw话题用rospy.Subscriber注册回调避免图像拷贝关键预处理层test01.py负责灰度转换cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)、高斯模糊cv2.GaussianBlur(gray, (5,5), 0)、自适应阈值cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)——这里不用全局阈值因为教室灯光不均窗边亮、墙角暗自适应能保住轮廓完整性特征提取层不用CNN提取高维特征改用cv2.findContours()找连通域再用cv2.moments()算每个轮廓的重心M[m10]/M[m00],M[m01]/M[m00]面积cv2.contourArea(cnt)和最小外接矩形cv2.boundingRect(cnt)——这些全是O(n)复杂度操作n是轮廓点数树莓派上单轮廓处理0.8ms决策层diatance_1.py用相似三角形原理估算距离distance (known_width * focal_length) / pixel_width其中pixel_width是障碍物在图像中占据的像素宽度来自boundingRect的widthfocal_length通过简易标定获得后文详述known_width由用户配置如设置为210对应A4纸z-move.py则直接取最大轮廓重心X坐标与图像中心差值映射为角速度angular_z k * (center_x - img_center_x)k值通过实测调节通常0.002~0.005执行层stop_car.py监听距离结果一旦distance 0.35m可配置立即向/cmd_vel发布Twist(linearVector3(0,0,0), angularVector3(0,0,0))并触发蜂鸣器GPIO需自行接线。这个架构放弃“识别是什么”专注“在哪里、有多远、往哪偏”把计算量压到最低同时保留足够鲁棒性——实测在光照突变拉窗帘、背景杂乱地面有瓷砖缝、障碍物材质各异白纸、黑书、红水杯下检测成功率92%。2.2 模块化设计为什么五个脚本要彼此解耦看目录结构diatance_1.py、test01.py、z-move.py、stop_car.py、new/这不是随意拆分而是按ROS节点职责严格隔离test01.py是图像预处理节点只干一件事——把原始BGR图像转成二值图并发布到/camera/binary_image话题。它不关心障碍物在哪只确保输出图像是“干净”的黑白分明。这样做的好处是你可以用rqt_image_view直接订阅这个话题肉眼检查二值化效果快速定位是光照问题还是阈值参数不对diatance_1.py是距离估算节点订阅/camera/binary_image找最大轮廓算像素宽度代入公式输出/obstacle/distanceFloat32类型。它和运动控制完全解耦你可以单独rosrun它用rostopic echo /obstacle/distance看数值跳动验证标定是否准确z-move.py是横向纠偏节点订阅/camera/binary_image计算重心偏移输出/cmd_vel的angular.z分量。注意它只发角速度不碰linear.x——线速度由上层导航栈如move_base或手动遥控控制避免控制权冲突stop_car.py是安全制动节点订阅/obstacle/distance一旦低于阈值强制清零/cmd_vel。它是最后的安全阀独立于其他节点运行即使z-move.py崩溃它依然能保命new/目录是硬件适配区存放不同摄像头的.yaml配置分辨率、曝光、白平衡和对应测试脚本如test_ov5647_640x480.py。为什么需要这个因为USB摄像头驱动差异极大Logitech C270默认开自动曝光在强光下会疯狂闪烁Raspberry Pi Camera Module V2需要手动关自动白平衡否则红色障碍物在阴天发绿。new/里的配置文件就是针对这些“坑”预调好的参数集你只需cp new/ov5647_640x480.yaml ~/.ros/camera_info/重启usb_cam节点即可。这种解耦让调试像搭积木想调二值化效果只改test01.py发现距离不准只动diatance_1.py里的focal_length小车总往右偏只调z-move.py的系数k。模块间只通过标准ROS话题通信没有全局变量、没有文件IO、没有硬编码路径——这才是嵌入式开发该有的样子。3. 核心细节解析与实操要点从代码行到物理世界的精准映射3.1test01.py二值化不是调个阈值那么简单打开test01.py核心就这几行def image_callback(msg): try: cv_img bridge.imgmsg_to_cv2(msg, bgr8) except CvBridgeError as e: rospy.logerr(CvBridge Error: %s % e) return gray cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY) blur cv2.GaussianBlur(gray, (5,5), 0) binary cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) # 发布二值图 try: binary_msg bridge.cv2_to_imgmsg(binary, mono8) pub_binary.publish(binary_msg) except CvBridgeError as e: rospy.logerr(CvBridge Error in publishing: %s % e)表面看很常规但藏着三个关键细节第一adaptiveThreshold的BlockSize必须是奇数且≥3。代码里写的是11这是经验值。BlockSize决定局部邻域大小太小如3会导致噪声被误判为边缘二值图满屏雪花太大如25会让小障碍物轮廓被平滑掉。我实测过不同尺寸在640x480分辨率下BlockSize11时A4纸210mm宽在0.5m距离下能稳定检出完整矩形轮廓换成800x600分辨率就得调到15。为什么因为自适应阈值计算时邻域像素数正比于BlockSize²分辨率升高后同样物理尺寸的障碍物占据像素更多需要更大邻域来平衡光照梯度。第二C参数常数项设为2不是默认0。C用于校正邻域均值正值使阈值整体下移更多像素变白负值上移更多变黑。教室环境常见“中间亮、四周暗”的渐晕效应设C2能补偿暗角让边缘障碍物不至于被切掉。你可以在rqt_image_view里实时拖动C值滑块观察效果——C0时窗边纸盒轮廓残缺C2时恢复完整。第三bridge.imgmsg_to_cv2的bgr8编码必须匹配摄像头输出。很多新手栽在这里usb_cam节点默认发布rgb8但OpenCV的cvtColor函数假设输入是BGR顺序。如果没注意cv2.cvtColor(..., cv2.COLOR_BGR2GRAY)会把RGB当BGR处理灰度图严重偏色二值化失效。解决方案有两个要么在usb_cam启动时加参数_pixel_format:yuyv强制YUV输出再转灰度要么在test01.py里把bgr8改成rgb8并在cvtColor里用cv2.COLOR_RGB2GRAY。我推荐后者因为更直观——打开rqt_reconfigure调usb_cam参数确认pixel_format是rgb8然后代码同步修改一劳永逸。提示调试二值化效果的最快方法是rosrun image_view image_view image:/camera/binary_image直接看黑白图。如果障碍物边缘锯齿严重调大GaussianBlur的kernel size如果背景噪点多增大adaptiveThreshold的C值如果整个画面发灰检查pixel_format是否匹配。3.2diatance_1.py距离估算的物理标定比写代码更重要diatance_1.py的核心公式是# 已知参数需用户配置 KNOWN_WIDTH 0.210 # 米A4纸宽度 FOCAL_LENGTH 520 # 像素通过标定获得 # 计算过程 contours, _ cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contours: largest_contour max(contours, keycv2.contourArea) x, y, w, h cv2.boundingRect(largest_contour) if w 20: # 过滤小噪点 distance (KNOWN_WIDTH * FOCAL_LENGTH) / w # 发布distance这里FOCAL_LENGTH 520不是随便写的它来自相机标定。很多人以为标定必须用棋盘格和camera_calibration包其实对避障这种粗粒度应用用“已知尺寸物体固定距离”两点法就够了打印一张A4纸210mm×297mm贴在墙上把小车停在距离纸张0.5m的位置用卷尺精确测量确保纸张正面垂直于摄像头光轴运行test01.py用rqt_image_view看二值图记下A4纸在图像中的像素宽度w_pixels比如320px代入公式focal_length (distance * w_pixels) / KNOWN_WIDTH (0.5 * 320) / 0.210 ≈ 762。但实测发现762太大——小车在0.8m处就触发刹车。为什么因为摄像头镜头有畸变边缘像素实际焦距偏短。所以我采用三点标定分别在0.4m、0.6m、0.8m三个距离测量像素宽度拟合直线w k/distance b取k作为有效焦距。最终在OV5647摄像头640x480上拟合得k520b≈-15b项很小可忽略故取FOCAL_LENGTH520。注意KNOWN_WIDTH必须是你实际使用的障碍物宽度。如果主要避障目标是直径10cm的水杯就把KNOWN_WIDTH改成0.100。别迷信“A4纸标准”你的场景才是标准。3.3z-move.py横向纠偏的“手感”来自系数k的物理意义z-move.py的角速度计算看似简单center_x img.shape[1] // 2 moment cv2.moments(largest_contour) if moment[m00] ! 0: cx int(moment[m10] / moment[m00]) error cx - center_x angular_z Kp * error # Kp是比例系数 twist.angular.z angular_z但Kp的取值绝不是靠猜。它的物理意义是每像素偏移对应的角速度rad/s per pixel。推导如下假设小车以0.2m/s线速度前进摄像头视野水平角为62°OV5647典型值图像宽640px则每像素对应的实际横向距离为pixel_to_m (2 * 0.2 * tan(62°/2)) / 640 ≈ 0.00042 m/px要让小车在1秒内把误差归零所需角速度应满足angular_z * 1s * 0.2m error_px * 0.00042m→angular_z error_px * 0.0021所以理论Kp ≈ 0.0021。实测中我取0.003略大一点让响应更灵敏但不超过0.005否则小车会左右摇摆。你可以在空旷场地放一个水杯手动遥控小车以0.15m/s匀速靠近观察z-move.py输出的angular.z值——理想状态是距离0.8m时angular.z在±0.1内波动微调距离0.5m时angular.z稳定在±0.3~0.5明显转向且无振荡。4. 实操过程与核心环节实现从烧录SD卡到小车自主绕障的完整链路4.1 环境准备树莓派4B的最小化ROS安装仅需15分钟别用Noetic全量安装——那会塞进2GB无关包。我们只要rospy、std_msgs、geometry_msgs和cv_bridge四个核心# 1. 更新系统 sudo apt update sudo apt upgrade -y # 2. 安装ROS Noetic核心树莓派官方源 sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update sudo apt install ros-noetic-ros-base ros-noetic-cv-bridge ros-noetic-image-transport -y # 3. 初始化rosdep关键否则catkin_make报错 sudo rosdep init rosdep update # 4. 创建工作空间精简版 mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin_make source devel/setup.bash echo source ~/catkin_ws/devel/setup.bash ~/.bashrc source ~/.bashrc注意ros-noetic-ros-base不含rviz和gazebo节省1.8GB空间cv_bridge必须装否则bridge.imgmsg_to_cv2会报错。实测在树莓派4B 4GB版上这套最小安装占用磁盘1.2GB内存常驻380MB留足余量给OpenCV。4.2 USB摄像头驱动配置避开Linux UVC的三大陷阱树莓派对USB摄像头的支持远不如PCusb_cam节点常因驱动问题卡死。以下是经过验证的稳定配置第一步禁用USB 3.0最致命树莓派4B的USB 3.0控制器与某些UVC摄像头如Logitech C920存在DMA冲突导致图像冻结。强制降速到USB 2.0# 编辑config.txt sudo nano /boot/config.txt # 在末尾添加 # Disable USB 3.0 to avoid UVC conflicts dtoverlayusb-storage,disable_usb31重启生效。实测后C920帧率从不稳定15fps提升至稳定30fps。第二步设置摄像头参数防自动调整在~/catkin_ws/src/下创建usb_cam_config.launchlaunch node nameusb_cam pkgusb_cam typeusb_cam_node outputscreen param namevideo_device value/dev/video0 / param nameimage_width value640 / param nameimage_height value480 / param namepixel_format valuemjpeg / !-- 关键用MJPG压缩降低带宽 -- param namecamera_frame_id valueusb_cam / param nameio_method valuemmap / !-- 禁用自动曝光/白平衡 -- param nameauto_exposure valueFalse / param nameauto_white_balance valueFalse / !-- 手动设曝光根据环境调 -- param nameexposure_absolute value156 / !-- 0~200教室常用150~180 -- /node /launch第三步赋予USB设备权限新建udev规则避免每次插拔都要sudosudo nano /etc/udev/rules.d/99-webcam.rules # 添加 SUBSYSTEMvideo4linux, ATTRS{idVendor}046d, ATTRS{idProduct}082d, MODE0666 # idVendor/idProduct查法lsusb -v | grep -E (idVendor|idProduct) sudo udevadm control --reload-rules sudo udevadm trigger完成这三步roslaunch usb_cam usb_cam-test.launch就能稳定输出/usb_cam/image_rawrostopic hz /usb_cam/image_raw显示稳定30Hz。4.3 脚本部署与一键启动让小车“开机即避障”把下载的脚本包解压到~/catkin_ws/src/vision_avoid/结构如下vision_avoid/ ├── scripts/ │ ├── test01.py │ ├── diatance_1.py │ ├── z-move.py │ └── stop_car.py ├── config/ │ └── camera_params.yaml # 存放FOCAL_LENGTH等参数 └── CMakeLists.txt # 最小化CMake仅声明依赖CMakeLists.txt内容极简cmake_minimum_required(VERSION 3.0.2) project(vision_avoid) find_package(catkin REQUIRED COMPONENTS rospy std_msgs geometry_msgs cv_bridge) catkin_package()编译并创建启动文件cd ~/catkin_ws catkin_make source devel/setup.bash # 创建启动脚本avoidance.sh nano ~/avoidance.sh # 内容 #!/bin/bash source ~/catkin_ws/devel/setup.bash roscore sleep 2 rosrun usb_cam usb_cam_node __name:usb_cam sleep 3 rosrun vision_avoid test01.py __name:binary_proc rosrun vision_avoid diatance_1.py __name:distance_calc rosrun vision_avoid z-move.py __name:lateral_ctrl rosrun vision_avoid stop_car.py __name:emergency_stop wait赋予执行权限chmod x ~/avoidance.sh。以后只需~/avoidance.sh小车就会自动启动全套避障节点。实测从执行命令到小车开始响应耗时8秒。4.4new/目录实战如何30分钟适配新摄像头假设你换了Raspberry Pi Camera Module V2IMX219传感器需要快速启用。步骤如下查硬件IDls /dev/video*确认设备号通常是/dev/video0vcgencmd get_camera确认已启用复制配置模板cp new/pi_camera_v2_640x480.yaml ~/catkin_ws/src/vision_avoid/config/camera_params.yaml修改参数用nano打开camera_params.yaml重点调三项yaml focal_length: 480 # IMX219实测值比OV5647略小 known_width: 0.100 # 改为水杯直径 exposure: 120 # V2动态范围小曝光值需降低更新启动文件在avoidance.sh中把usb_cam_node换成raspicam_node需先sudo apt install ros-noetic-raspicam-node并指向新配置实测验证运行~/avoidance.sh用rostopic echo /obstacle/distance看数值——0.5m处应显示0.48~0.52误差5%即达标。整个过程30分钟内完成无需重写代码只换参数。这就是new/目录的设计初衷硬件是消耗品软件要长青。5. 常见问题与排查技巧实录那些文档里不会写的“血泪经验”5.1 典型问题速查表现象可能原因排查命令解决方案rostopic hz /usb_cam/image_raw显示0HzUSB摄像头未识别或驱动冲突lsusb,dmesg \| grep -i usb\|camera检查/boot/config.txt是否禁用USB3.0拔插摄像头看dmesg是否有uvcvideo错误test01.py发布二值图但rqt_image_view显示全黑自适应阈值参数不匹配当前光照rosrun image_view image_view image:/usb_cam/image_raw对比原图临时改test01.py中adaptiveThreshold的C值为5若变正常则环境太暗需调高摄像头曝光diatance_1.py输出距离忽大忽小如0.3m→2.1m→0.4m轮廓检测到多个干扰物取了错误轮廓rostopic echo /camera/binary_image --noarr查看二值图质量在diatance_1.py中增加面积过滤if cv2.contourArea(cnt) 500:500像素²约等于10cm×10cm障碍物小车不转向/cmd_vel的angular.z始终为0z-move.py未收到二值图或轮廓为空rostopic hz /camera/binary_image,rostopic echo /obstacle/distance检查test01.py是否正常发布用rqt_image_view确认二值图中有白色障碍物区域stop_car.py不触发停车小车直撞障碍物距离阈值设太高或diatance_1.py未启动rostopic echo /obstacle/distance临时在stop_car.py中把STOP_DISTANCE 0.35改为0.8若能停车则原阈值过低再查diatance_1.py是否在运行5.2 我踩过的三个深坑与独家技巧坑一“图像旋转180度”导致方向全反某次用Pi Camera V2小车看到障碍物在左边却往右转。查了一小时发现raspicam_node默认输出图像是上下颠倒的cv2.flip(binary, -1)就能解决但更优雅的做法是在test01.py的image_callback里加# 检测是否需要翻转根据摄像头型号自动判断 if pi_camera in rospy.get_param(/usb_cam/camera_info_url, ): cv_img cv2.flip(cv_img, -1) # 180度翻转坑二树莓派GPU内存不足导致OpenCV崩溃cv2.findContours在树莓派上偶尔Segmentation Fault。原因是GPU内存被raspberrypi-ui占用太多。解决方案sudo nano /boot/config.txt把gpu_mem128改成gpu_mem256重启。坑三ROS时间戳不同步引发控制抖动/usb_cam/image_raw和/cmd_vel的时间戳若相差100msz-move.py计算的偏移量就对应不上当前车姿。技巧在test01.py发布二值图时复用原图时间戳binary_msg.header.stamp msg.header.stamp # 关键复用原图时间戳 pub_binary.publish(binary_msg)独家技巧用手机闪光灯做“人工激光测距”快速标定没有卷尺用iPhone闪光灯打开相机App开启闪光灯把手机紧贴A4纸一侧让光斑刚好覆盖纸张宽度。此时手机到纸张距离≈闪光灯到纸张距离用手机测距App如iOS自带“测距仪”读出距离精度±2cm足够避障使用。6. 性能优化与扩展建议让这套脚本陪你走更远6.1 树莓派级性能榨干指南这套脚本在树莓派4B上还有15% CPU余量可进一步优化OpenCV编译优化卸载pip安装的opencv-python从源码编译并启用NEON和VFPV3bash cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D OPENCV_ENABLE_NEONON \ -D OPENCV_ENABLE_VFPV3ON \ -D BUILD_TESTSOFF \ -D BUILD_PERF_TESTSOFF \ -D BUILD_EXAMPLESOFF .. make -j4 sudo make install实测findContours速度提升37%adaptiveThreshold提升22%。ROS消息零拷贝cv_bridge默认深拷贝图像耗时。改用sensor_msgs/Image的data字段直接操作python # 不用bridge直接解析msg.data import numpy as np img_array np.frombuffer(msg.data, dtypenp.uint8).reshape(msg.height, msg.width, 3)6.2 后续可扩展方向不破坏现有架构加入超声波传感器融合在stop_car.py里订阅/sonar/front话题当超声波距离0.25m时无视视觉结果直接刹车——视觉可能被强光致盲超声波不受影响动态距离阈值diatance_1.py输出距离后stop_car.py可根据小车当前线速度动态调整STOP_DISTANCEv0.2m/s时用0.35mv0.4m/s时用0.55m符合物理制动距离多障碍物优先级diatance_1.py不只输出最近距离还输出所有障碍物的(distance, angle)元组z-move.py可据此选择“绕左侧窄缝”而非“硬停”。这套脚本不是终点而是你ROS小车视觉能力的起点。它不炫技但每行代码都踩过坑不宏大但每个参数都有物理意义。当你看着小车第一次自己绕开水杯那种“它真的懂了”的感觉比跑通任何深度学习模型都踏实。毕竟工程的本质不是证明你能做什么而是确保你做的东西在明天、在教室、在学生手里依然稳稳地跑下去。本文还有配套的精品资源点击获取简介提供一套开箱即用的ROS小车视觉避障Python脚本组合适配USB摄像头如usb_cam直接订阅/image_raw话题进行实时帧处理。diatance_1.py基于像素尺寸与标定参数估算障碍物距离test01.py完成图像采集、灰度转换、高斯模糊及自适应二值化z-move.py根据障碍物横向偏移量输出微调角速度指令stop_car.py在检测到近距障碍时发布零速命令实现紧急停车。所有逻辑均依赖OpenCV基础操作颜色空间转换、阈值分割、轮廓查找、矩心计算不依赖GPU或深度学习模型可在树莓派4B等ARM平台流畅运行。new目录内含多组摄像头分辨率、曝光、白平衡配置文件及对应测试脚本便于快速适配不同硬件环境。requirements.txt明确列出opencv-python、rospy等最小依赖项支持一键部署与模块级替换调试。本文还有配套的精品资源点击获取

相关新闻