diff --git a/src/Smart_car/README.md b/src/Smart_car/README.md index e69de29bb2..9f882079af 100644 --- a/src/Smart_car/README.md +++ b/src/Smart_car/README.md @@ -0,0 +1,224 @@ +--- +AIGC: + ContentProducer: Minimax Agent AI + ContentPropagator: Minimax Agent AI + Label: AIGC + ProduceID: e052170842fbffc7d21baedf4eb60a91 + PropagateID: e052170842fbffc7d21baedf4eb60a91 + ReservedCode1: 30450220634cdb7d01a90f09d27c8175ddbead6c2e00eb6885f4bf068b71a5e68462deca022100bae83365aff19667c6a3d81e38e6b421807893b6f6908a22e839588a0946a346 + ReservedCode2: 3046022100a7bfdf8c0b714f1dba19461db6b74519f502d4673a07347747fb0cf56e840d95022100854fe1d24afa96ab2ea3fae7b6bc2b8d75f2021846f4dce4f4743a9680d68e0d +--- + +# 智能无人车导航系统 + +![无人车导航系统](imgs/chinese_nav_0.png) + +> 基于ROS的智能无人车自主导航系统,支持路径规划、障碍物避让、实时定位等功能 + +## 项目简介 + +本项目是一个基于ROS (Robot Operating System) 框架开发的智能无人车导航系统,集成了先进的SLAM算法、路径规划、动态避障等功能模块,实现了完全自主的室内外导航能力。 + +### 核心特性 + +- 实时建图 (SLAM): 基于激光雷达的实时环境建图 +- 智能路径规划: 支持全局路径规划和局部路径优化 +- 动态避障: 实时检测障碍物并调整路径 +- 精确定位: 多传感器融合定位系统 +- 多种控制模式: 支持手动控制、自动导航、目标点导航 +- 实时监控: 可视化界面实时显示系统状态 + +## 快速开始 + +### 系统要求 + +- **操作系统**: Ubuntu 18.04/20.04 LTS +- **ROS版本**: Melodic/Noetic +- **Python**: 2.7/3.x +- **硬件要求**: + - 激光雷达 (16线/32线) + - 深度相机 + - IMU传感器 + - 编码器 + +### 安装步骤 + +```bash +# 1. 创建工作空间 +mkdir -p ~/catkin_ws/src +cd ~/catkin_ws/src + +# 2. 克隆项目 +git clone https://github.com/your-repo/autonomous-vehicle.git + +# 3. 安装依赖 +cd autonomous-vehicle +rosdep install --from-paths src --ignore-src -r -y + +# 4. 编译项目 +cd ~/catkin_ws +catkin_make + +# 5. 加载环境变量 +source devel/setup.bash +``` + +### 运行演示 + +```bash +# 启动仿真环境 +roslaunch autonomous_vehicle simulation.launch + +# 启动真实机器人 +roslaunch autonomous_vehicle robot.launch + +# 启动导航系统 +roslaunch autonomous_vehicle navigation.launch +``` + +## 运行效果图 + +### 1. ROS导航仿真界面 + +(imgs/ros_navigation_4.png) +*图1: ROS RViz环境下的导航仿真界面,实时显示地图、路径规划和机器人位置* + +### 2. 路径规划可视化 + +![路径规划](imgs/path_planning_6.png) +*图2: 智能路径规划系统,绿色线条显示全局规划路径,红色线条显示局部优化路径* + +### 3. 障碍物避让演示 + +![障碍物避让](imgs/obstacle_avoidance_8.jpg) +*图3: 实时障碍物检测与避让,黄色区域为检测到的障碍物,蓝色区域为安全路径* + +### 4. 中文导航界面 + +![中文导航](imgs/chinese_nav_8.png) +*图4: 中文导航系统界面,支持目标点设定、路径显示和状态监控* + +### 5. 实时地图构建 + +![地图构建](imgs/chinese_nav_7.png) +*图5: 实时SLAM地图构建过程,显示环境特征点和机器人轨迹* + +## 系统架构 + +``` +autonomous_vehicle/ +├── src/ +│ ├── perception/ # 感知模块 +│ │ ├── obstacle_detection/ +│ │ ├── lane_detection/ +│ │ └── traffic_light_detection/ +│ ├── localization/ # 定位模块 +│ │ ├── slam/ +│ │ └── ekf_localization/ +│ ├── planning/ # 规划模块 +│ │ ├── global_planner/ +│ │ └── local_planner/ +│ ├── control/ # 控制模块 +│ │ ├── pid_controller/ +│ │ └── pure_pursuit/ +│ └── utils/ # 工具模块 +├── launch/ # 启动文件 +├── config/ # 配置文件 +├── urdf/ # 机器人模型 +├── rviz/ # 可视化配置 +└── scripts/ # 脚本文件 +``` + +## 性能指标 + +| 指标项 | 性能参数 | +|--------|----------| +| 最大速度 | 2.0 m/s | +| 最小转弯半径 | 0.5 m | +| 定位精度 | ±5 cm | +| 避障距离 | 1.0 m | +| 地图分辨率 | 5 cm/pixel | +| 路径规划频率 | 10 Hz | + + 使用场景 + +- 室内服务机器人: 办公楼、医院、酒店等场所的自主导航 +- 工业AGV**: 工厂内的物料搬运和自动化运输 +- 室外巡检机器人**: 园区巡检、安防监控等应用 +- 教育研究**: 机器人学习和算法验证平台 + +## API文档 + +### 主要话题 + +| 话题名称 | 消息类型 | 功能描述 | +|----------|----------|----------| +| `/cmd_vel` | `geometry_msgs/Twist` | 机器人运动控制命令 | +| `/scan` | `sensor_msgs/LaserScan` | 激光雷达数据 | +| `/amcl_pose` | `geometry_msgs/PoseWithCovarianceStamped` | 机器人位姿信息 | +| `/move_base/goal` | `geometry_msgs/PoseStamped` | 导航目标点 | + +### 主要服务 + +| 服务名称 | 服务类型 | 功能描述 | +|----------|----------|----------| +| `/slam_gmapping/map` | `nav_msgs/GetMap` | 获取地图数据 | +| `/static_map` | `nav_msgs/GetMap` | 获取静态地图 | + +## 配置说明 + +### 导航参数配置 + +```yaml +# costmap_common_params.yaml +obstacle_radius: 0.2 +inflation_radius: 0.5 +max_vel_x: 0.5 +min_vel_x: -0.5 +max_vel_theta: 1.0 +``` + +### 激光雷达配置 + +```yaml +# lidar_params.yaml +min_range: 0.2 +max_range: 30.0 +scan_frequency: 5.0 +angular_resolution: 0.25 +``` + +## 故障排除 + +### 常见问题 + +1. **激光雷达数据丢失** + - 检查激光雷达连接 + - 确认串口权限设置 + +2. **定位不准确** + - 校准IMU传感器 + - 检查编码器数据 + +3. **路径规划失败** + - 检查地图数据完整性 + - 确认目标点可达性 + +### 日志查看 + +```bash +# 查看系统日志 +roslaunch autonomous_vehicle log.launch + +# 实时监控话题数据 +rostopic echo /cmd_vel +``` +### 开发环境搭建 + +```bash +# 安装开发工具 +sudo apt install python3-catkin-tools python3-osrf-pycommon + +# 克隆开发分支 +git checkout -b feature/your-feature +``` \ No newline at end of file diff --git a/src/Smart_car/autonomous_vehicle_battery_level_display.py b/src/Smart_car/autonomous_vehicle_battery_level_display.py index 40b6b6f8f5..a61e21363c 100644 --- a/src/Smart_car/autonomous_vehicle_battery_level_display.py +++ b/src/Smart_car/autonomous_vehicle_battery_level_display.py @@ -1,40 +1,70 @@ import time -import random # 仅用于模拟硬件数据,实际场景删除 +import random # 仅用于模拟硬件采集的电池电压数据,实际项目部署时请删除该模块及相关模拟代码 class UnmannedVehicleBattery: - """无人车电池电量管理类""" + """无人车电池电量管理核心类 + 核心职责: + 1. 电池实时电压数据读取(支持对接实际硬件或模拟采集) + 2. 基于电压值计算剩余电量百分比 + 3. 根据剩余电量判断电池工作状态 + 4. 格式化、可视化展示电池完整监控信息 + 特性: + - 可根据电池型号/规格灵活配置核心参数(满电电压、欠压保护电压等) + - 预留硬件采集对接接口,易于实际项目部署迁移 + """ def __init__(self): - # 电池参数配置(根据实际电池规格调整) - self.max_voltage = 12.6 # 满电电压(12V锂电池为例) - self.min_voltage = 10.0 # 欠压保护电压 - self.current_voltage = 0.0 # 当前电压 - self.battery_percent = 0.0 # 剩余电量百分比 + # 电池核心参数配置(可根据实际使用的电池型号/规格调整对应数值) + self.max_voltage = 12.6 # 电池满电电压(示例:12V三元锂电池满电电压) + self.min_voltage = 10.0 # 电池欠压保护电压,低于此值需立即停止使用并充电 + self.current_voltage = 0.0 # 电池实时电压(初始值为0,后续通过硬件采集或模拟逻辑更新) + self.battery_percent = 0.0 # 电池剩余电量百分比(计算后保留1位小数,保证显示精度) def read_battery_voltage(self): + """读取电池实时电压(模拟硬件采集逻辑) + 实际应用场景对接说明: + 1. 树莓派/单片机平台:通过ADC模块(如ADS1115)采集电压模拟信号 + 2. 带BMS管理系统的电池:通过串口/RS485/I2C通信协议获取BMS上报的电压数据 + 3. 其他硬件平台:根据对应硬件的通信协议调整数据读取逻辑 + 本方法中模拟逻辑仅用于测试演示,实际部署需替换为真实硬件采集代码 """ - 读取电池电压(模拟硬件采集) - 实际场景:替换为ADC读取/串口接收BMS数据/I2C通信等 - """ - # 模拟电压波动(范围:10.0~12.6V) + # 模拟电压小幅波动(范围:欠压保护电压~满电电压,保留2位小数,贴近真实电池电压变化) self.current_voltage = round(random.uniform(10.0, 12.6), 2) - # 实际硬件示例(以树莓派ADC为例): + + # 实际硬件采集示例(以树莓派+ADS1115 ADC模块为例,需安装对应依赖库) + # 依赖库安装命令:pip install adafruit-circuitpython-ads1x15 + # import board # import adafruit_ads1x15.ads1115 as ADS # from adafruit_ads1x15.analog_in import AnalogIn + # + # # 初始化I2C总线和ADS1115模块(使用硬件默认SDA/SCL引脚) # i2c = board.I2C() # ads = ADS.ADS1115(i2c) - # chan = AnalogIn(ads, ADS.P0) - # self.current_voltage = chan.voltage * voltage_divider_ratio # 电压分压比 + # chan = AnalogIn(ads, ADS.P0) # 选择A0通道作为电池电压采集通道 + # + # # 计算实际电池电压(需根据硬件分压电路配置,调整对应的电压分压比) + # voltage_divider_ratio = 2.0 # 分压比示例,需根据实际电路参数修改 + # self.current_voltage = chan.voltage * voltage_divider_ratio def calculate_battery_percent(self): - """计算剩余电量百分比""" + """根据实时电压计算电池剩余电量百分比 + 计算模型说明: + - 采用线性计算模型,适用于电压与电量近似线性关系的电池类型(如三元锂电池) + - 实际场景优化建议:可根据电池具体放电曲线,优化为非线性计算模型,提升电量计算精度 + 计算逻辑: + 1. 电压≥满电电压:判定为100%满电量 + 2. 电压≤欠压保护电压:判定为0%电量(需立即停止使用) + 3. 电压在两者之间:通过线性插值公式计算剩余电量,保留1位小数 + """ if self.current_voltage >= self.max_voltage: + # 电压达到满电阈值,判定为100%剩余电量 self.battery_percent = 100.0 elif self.current_voltage <= self.min_voltage: + # 电压低于欠压保护阈值,判定为0%剩余电量(需立即充电) self.battery_percent = 0.0 else: - # 线性计算(实际可根据电池放电曲线优化) + # 线性插值计算剩余电量,保留1位小数,保证显示一致性 self.battery_percent = round( (self.current_voltage - self.min_voltage) / (self.max_voltage - self.min_voltage) * 100, @@ -42,7 +72,16 @@ def calculate_battery_percent(self): ) def get_battery_status(self): - """判断电量状态""" + """根据剩余电量判断电池当前工作状态 + 返回值说明: + - 第一个返回值:文字状态描述(用于直观展示电池状态) + - 第二个返回值:状态标识符号(通过颜色/emoji区分告警级别,提升可读性) + 状态分级标准: + 1. 满电:电量≥95%,正常工作状态 + 2. 正常:20%≤电量<95%,可正常执行作业 + 3. 低电量:5%≤电量<20%,需准备充电 + 4. 紧急:电量<5%,需立即停止作业并充电 + """ if self.battery_percent >= 95: return "满电", "🟢" elif 20 <= self.battery_percent < 95: @@ -53,43 +92,70 @@ def get_battery_status(self): return "紧急(请充电)", "🔴" def display_battery_info(self): - """可视化显示电量信息""" - # 清空控制台(可选) + """可视化展示电池完整监控信息 + 展示内容: + 1. 电池实时电压 + 2. 剩余电量百分比及可视化进度条 + 3. 电池当前工作状态(含状态标识) + 4. 紧急告警提示(电量<5%时触发) + 优化特性: + - 进度条可视化提升信息可读性 + - 紧急告警强化使用安全性,提醒用户及时处理 + 可选配置: + - 可启用控制台清屏功能,实现监控信息实时刷新(已注释,按需启用) + """ + # 清空控制台屏幕(可选功能,根据实际使用场景选择是否启用) + # 兼容Windows(cls命令)和Linux/macOS(clear命令)系统 + # import os # os.system('cls' if os.name == 'nt' else 'clear') - # 电量条可视化 - bar_length = 20 - filled_length = int(bar_length * self.battery_percent // 100) - battery_bar = "█" * filled_length + "-" * (bar_length - filled_length) + # 电量进度条可视化配置 + bar_length = 20 # 进度条总长度(字符数),可根据显示需求调整 + filled_length = int(bar_length * self.battery_percent // 100) # 已填充进度的字符长度 + battery_bar = "█" * filled_length + "-" * (bar_length - filled_length) # 拼接进度条字符 - # 获取状态 + # 获取当前电池状态描述和状态标识符号 status, color = self.get_battery_status() - # 打印信息 - print(f"\n=== 无人车电池状态 ===") + # 打印格式化后的电池监控信息,排版清晰便于查看 + print(f"\n=== 无人车电池状态监控 ===") print(f"当前电压: {self.current_voltage}V") print(f"剩余电量: |{battery_bar}| {self.battery_percent}%") print(f"状态: {color} {status}") - # 低电量告警 + # 紧急告警:电量低于5%时,提示用户立即停止作业并接入充电器,避免电池过放损坏 if self.battery_percent < 5: - print("⚠️ 电量过低,立即停止作业并充电") + print("⚠️ 【紧急告警】电量过低,立即停止所有作业并接入充电器!") def main(): - """主循环""" + """程序主入口,实现电池状态循环监控 + 核心流程: + 1. 初始化无人车电池管理实例 + 2. 循环执行「电压读取→电量计算→信息展示」流程 + 3. 每秒刷新一次监控数据,保证实时性 + 退出机制: + - 支持通过Ctrl+C快捷键捕获中断信号,实现程序友好退出,避免异常报错 + 运行提示: + - 启动后会输出系统启动提示,告知用户退出方式 + """ + # 初始化无人车电池管理实例,加载电池核心配置参数 battery = UnmannedVehicleBattery() - print("无人车电量监控系统启动...") + print("无人车电量监控系统已启动...(按Ctrl+C可退出监控)") try: + # 无限循环执行监控流程,每秒刷新一次数据,实现持续监控 while True: - battery.read_battery_voltage() # 读取电压 - battery.calculate_battery_percent() # 计算电量 - battery.display_battery_info() # 显示信息 - time.sleep(1) # 1秒刷新一次 + battery.read_battery_voltage() # 步骤1:读取电池实时电压(模拟/硬件采集) + battery.calculate_battery_percent() # 步骤2:根据电压计算剩余电量百分比 + battery.display_battery_info() # 步骤3:可视化展示电池完整监控信息 + time.sleep(1) # 暂停1秒,控制监控刷新频率 except KeyboardInterrupt: - print("\n监控系统已退出") + # 捕获Ctrl+C中断信号,打印退出提示,实现程序正常退出 + print("\n监控系统已正常退出") if __name__ == "__main__": + # 程序启动入口:当脚本直接运行时,自动执行主函数启动监控系统 + # 若作为模块导入时,不会自动执行,便于复用类和方法 main() \ No newline at end of file diff --git a/src/Smart_car/overload.py b/src/Smart_car/overload.py index 1018554ae2..6f069dbb2f 100644 --- a/src/Smart_car/overload.py +++ b/src/Smart_car/overload.py @@ -2,39 +2,84 @@ import random class UnmannedVehicleOverloadWarningSystem: - """无人车超载预警系统""" + """无人车超载预警系统 + + 核心功能: + 1. 实时监测无人车载重状态数据 + 2. 根据载重占比自动划分预警等级 + 3. 可视化输出预警信息及处理建议 + 4. 检测到严重超载时触发系统紧急停止机制 + """ def __init__(self, max_load=1000): - # 初始化系统参数 - self.max_load = max_load # 车辆最大载重(单位:kg,可自定义) - self.current_load = 0 # 当前载重 + """系统初始化方法,配置核心参数 + + 参数: + max_load (int/float): 车辆最大载重限额,单位为千克(kg),可根据实际车型自定义配置,默认值1000 + 实例属性: + self.max_load: 存储车辆最大载重 + self.current_load: 当前实时载重,初始值设为0 + self.warning_level: 预警等级标识,0-正常,1-轻度过载,2-中度过载,3-严重超载 + """ + self.max_load = max_load # 车辆最大载重(kg) + self.current_load = 0 # 当前实时载重,初始化为0 self.warning_level = 0 # 预警等级:0-正常,1-轻度过载,2-中度过载,3-严重超载 def simulate_weight_collection(self): - """模拟无人车重量采集(模拟传感器数据,可替换为真实硬件接口)""" - # 模拟载重变化:每次在当前基础上小幅波动(模拟乘客/货物上下车) + """模拟无人车重量数据采集(传感器数据模拟接口) + + 逻辑说明: + 在当前载重基础上进行随机小幅波动,模拟乘客上下车或货物装卸带来的载重变化 + 避免载重出现负数,最低载重限制为0 + + 返回: + float: 更新后的当前载重数值 + """ + # 模拟载重变化范围:卸载最多50kg,加载最多100kg weight_change = random.randint(-50, 100) - self.current_load = max(0, self.current_load + weight_change) # 载重不能为负数 + # 更新当前载重,确保载重不低于0(最低载重为0) + self.current_load = max(0, self.current_load + weight_change) return self.current_load def judge_overload(self): - """超载判断逻辑,划分预警等级""" - load_ratio = self.current_load / self.max_load # 载重占比 + """超载等级判断核心方法,基于载重占比划分预警等级 + + 计算规则: + 载重占比 = 当前载重 / 最大载重 + 返回值: + tuple: 包含三个元素的元组,依次为: + 1. 预警状态名称(字符串) + 2. 预警颜色标识(字符串) + 3. 处理建议描述(字符串) + """ + # 计算载重占比,作为预警等级判定的核心依据 + load_ratio = self.current_load / self.max_load + + # 正常状态:载重≤80%最大载重,无需任何干预措施 if load_ratio <= 0.8: - self.warning_level = 0 # 正常:载重≤80%最大载重 + self.warning_level = 0 return "正常", "绿色", "当前载重未超出安全范围,无需处理" + # 轻度过载预警:80%<载重≤95%,接近上限需停止继续加载 elif 0.8 < load_ratio <= 0.95: - self.warning_level = 1 # 轻度过载:80%<载重≤95% + self.warning_level = 1 return "轻度过载预警", "黄色", "当前载重接近上限,建议停止加载" + # 中度过载警告:95%<载重≤110%,超出上限需卸载并停止运行 elif 0.95 < load_ratio <= 1.1: - self.warning_level = 2 # 中度过载:95%<载重≤110% + self.warning_level = 2 return "中度过载警告", "橙色", "当前载重已超出安全上限,立即停止运行并卸载部分货物" + # 严重超载警报:载重>110%,极度危险需紧急制动并联系工作人员 else: - self.warning_level = 3 # 严重超载:载重>110% + self.warning_level = 3 return "严重超载警报", "红色", "极度危险!立即紧急制动,联系工作人员处理" def display_warning(self, status, color, desc): - """可视化输出预警信息(模拟车载终端显示)""" + """可视化输出预警信息(模拟车载终端显示界面) + + 参数: + status (str): 预警状态名称(如"正常"、"严重超载警报"等) + color (str): 预警颜色标识(如"绿色"、"红色"等,对应车载终端显示颜色) + desc (str): 针对当前状态的具体处理建议描述 + """ print("=" * 50) print(f"【无人车超载预警系统 - 实时监测】") print(f"当前时间:{time.strftime('%Y-%m-%d %H:%M:%S')}") @@ -47,26 +92,41 @@ def display_warning(self, status, color, desc): print() def run(self, monitor_times=10): - """运行系统,持续监测载重并输出预警""" + """系统主运行方法,执行持续循环监测流程 + + 参数: + monitor_times (int): 预设监测总次数,默认值10次,可根据实际需求修改 + + 运行流程: + 1. 采集当前载重数据(模拟传感器更新) + 2. 判断超载预警等级,获取预警相关信息 + 3. 可视化输出预警详情(模拟车载终端展示) + 4. 检测到严重超载时,触发紧急停止机制 + 5. 间隔指定时间,进行下一次循环监测 + """ print("无人车超载预警系统已启动...") print(f"开始持续监测(共监测{monitor_times}次,每次间隔2秒)\n") - + # 循环执行监测流程,满足以下任一条件即终止: + # 1. 完成预设的监测次数 + # 2. 检测到严重超载(预警等级3) for i in range(monitor_times): - # 1. 采集当前载重(模拟) + # 步骤1:采集当前载重(模拟传感器数据实时更新) self.simulate_weight_collection() - # 2. 判断超载等级 + # 步骤2:判断超载等级,获取预警状态、颜色及处理建议 status, color, desc = self.judge_overload() - # 3. 显示预警信息 + # 步骤3:可视化输出预警详情(模拟车载终端显示效果) self.display_warning(status, color, desc) - # 4. 严重超载时紧急停止 + # 步骤4:严重超载(等级3)时,立即紧急停止系统运行 if self.warning_level == 3: - print("❗❗❗ 检测到严重超载,系统紧急停止运行! ❗❗") + print("❗❗❗ 检测到严重超载,系统紧急停止运行!❗") break - # 5. 间隔2秒进行下一次监测 + # 步骤5:间隔2秒进行下一次监测,模拟实时周期性数据检测 time.sleep(2) if __name__ == "__main__": - # 初始化系统:设置无人车最大载重为1000kg(可根据需求修改) + # 初始化系统:设置无人车最大载重为1000kg + # 备注:可根据不同车型、应用场景修改max_load参数值 overload_system = UnmannedVehicleOverloadWarningSystem(max_load=1000) - # 运行系统,持续监测10次(可修改监测次数) + # 运行系统:持续监测10次 + # 备注:可修改monitor_times参数调整监测总次数 overload_system.run(monitor_times=10) \ No newline at end of file diff --git a/src/Smart_car/path.py b/src/Smart_car/path.py index 14de9a79d4..60d6893d98 100644 --- a/src/Smart_car/path.py +++ b/src/Smart_car/path.py @@ -1,10 +1,3 @@ -import pygame -import sys -import math - -# 初始化pygame -pygame.init() - # 窗口配置 WINDOW_WIDTH = 800 WINDOW_HEIGHT = 600 diff --git a/src/Smart_car/traffic.py b/src/Smart_car/traffic.py new file mode 100644 index 0000000000..157ee7a3a5 --- /dev/null +++ b/src/Smart_car/traffic.py @@ -0,0 +1,153 @@ +import cv2 +import numpy as np +import os +import time + + +def traffic_light_real_time_detection(): + """ + 摄像头实时交通信号灯三色识别函数 + """ + # 1. 初始化摄像头(0为默认内置摄像头,1为外接摄像头,可根据实际调整) + cap = cv2.VideoCapture(0) + if not cap.isOpened(): + print("错误:无法打开摄像头,请检查摄像头是否正常连接或被其他程序占用.") + return "摄像头初始化失败." + + # 设置摄像头分辨率(提升识别效率,可根据摄像头性能调整) + cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) + cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) + + # 创建保存目录(用于保存抓拍结果) + save_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "real_time_detection_results") + if not os.path.exists(save_dir): + os.makedirs(save_dir) + red_lower1 = np.array([0, 100, 80]) + red_upper1 = np.array([10, 255, 255]) + red_lower2 = np.array([160, 100, 80]) + red_upper2 = np.array([180, 255, 255]) + + # 黄色 + yellow_lower = np.array([15, 120, 80]) + yellow_upper = np.array([35, 255, 255]) + + # 绿色 + green_lower = np.array([40, 80, 80]) + green_upper = np.array([80, 255, 255]) + + # 形态学操作核 + kernel = np.ones((3, 3), np.uint8) + # 轮廓检测参数 + contour_params = (cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + # 自适应最小面积(基于摄像头分辨率) + min_area = (640 * 480) / 1000 + + print("摄像头已启动,实时交通信号灯检测中...") + print("操作提示:") + print(" 1. 按下 's' 键保存当前检测结果图像") + print(" 2. 按下 'ESC' 键退出程序") + + def filter_valid_contours(contours, min_area_val): + """筛选有效轮廓(面积+圆度,适配信号灯圆形特征)""" + valid = [] + for cnt in contours: + area = cv2.contourArea(cnt) + if area < min_area_val: + continue + perimeter = cv2.arcLength(cnt, True) + if perimeter == 0: + continue + circularity = (4 * np.pi * area) / (perimeter ** 2) + if circularity > 0.6: # 圆度筛选,排除非圆形噪声 + valid.append(cnt) + return valid + + while True: + # 3. 读取摄像头帧 + ret, frame = cap.read() + if not ret: + print("警告:无法读取摄像头帧,可能是摄像头断开连接.") + break + + # 复制帧用于绘制结果 + frame_result = frame.copy() + # 转换为HSV色彩空间(抗光照干扰) + hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) + + # 4. 颜色掩码生成 + red_mask = cv2.inRange(hsv, red_lower1, red_upper1) | cv2.inRange(hsv, red_lower2, red_upper2) + yellow_mask = cv2.inRange(hsv, yellow_lower, yellow_upper) + green_mask = cv2.inRange(hsv, green_lower, green_upper) + + # 5. 形态学操作优化掩码 + red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_OPEN, kernel, iterations=1) + red_mask = cv2.morphologyEx(red_mask, cv2.MORPH_CLOSE, kernel, iterations=2) + yellow_mask = cv2.morphologyEx(yellow_mask, cv2.MORPH_OPEN, kernel, iterations=1) + yellow_mask = cv2.morphologyEx(yellow_mask, cv2.MORPH_CLOSE, kernel, iterations=2) + green_mask = cv2.morphologyEx(green_mask, cv2.MORPH_OPEN, kernel, iterations=1) + green_mask = cv2.morphologyEx(green_mask, cv2.MORPH_CLOSE, kernel, iterations=2) + + # 6. 轮廓检测与筛选 + red_contours, _ = cv2.findContours(red_mask, *contour_params) + yellow_contours, _ = cv2.findContours(yellow_mask, *contour_params) + green_contours, _ = cv2.findContours(green_mask, *contour_params) + + red_valid = filter_valid_contours(red_contours, min_area) + yellow_valid = filter_valid_contours(yellow_contours, min_area) + green_valid = filter_valid_contours(green_contours, min_area) + + # 7. 信号灯判断与可视化绘制 + light_color = "未检测到信号灯" + color_configs = [ + (red_valid, "红色信号灯", "Red", (0, 0, 255)), + (yellow_valid, "黄色信号灯", "Yellow", (0, 255, 255)), + (green_valid, "绿色信号灯", "Green", (0, 255, 0)) + ] + + for valid_contours, color_name, label, bgr_color in color_configs: + if len(valid_contours) > 0: + light_color = color_name + # 绘制轮廓和最小外接圆 + cv2.drawContours(frame_result, valid_contours, -1, bgr_color, 2) + for cnt in valid_contours: + (x, y), radius = cv2.minEnclosingCircle(cnt) + center = (int(x), int(y)) + radius = int(radius) + cv2.circle(frame_result, center, radius, bgr_color, 2) + # 绘制文字标签(避免超出图像边界) + text_y = int(y - radius - 10) if (y - radius - 10) > 10 else int(y + radius + 20) + cv2.putText(frame_result, label, (int(x) - 20, text_y), + cv2.FONT_HERSHEY_SIMPLEX, 0.6, bgr_color, 2) + break # 通常仅一种信号灯点亮,找到后退出循环 + + # 8. 在帧上添加信息提示 + cv2.putText(frame_result, f"Status: {light_color}", (10, 30), + cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) + cv2.putText(frame_result, "Press 's' to save, 'ESC' to exit", (10, 60), + cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1) + + # 9. 显示实时结果 + cv2.namedWindow("Real-Time Traffic Light Detection", cv2.WINDOW_NORMAL) + cv2.resizeWindow("Real-Time Traffic Light Detection", 640, 480) + cv2.imshow("Real-Time Traffic Light Detection", frame_result) + + # 10. 按键事件处理 + key = cv2.waitKey(1) & 0xFF + if key == 27: # ESC键退出 + print("程序已退出") + break + elif key == ord('s'): # 's'键保存结果 + timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime()) + save_path = os.path.join(save_dir, f"real_time_result_{timestamp}.jpg") + cv2.imwrite(save_path, frame_result) + print(f"当前检测结果已保存:{save_path}") + + # 释放资源 + cap.release() + cv2.destroyAllWindows() + return "实时检测结束" + + +# 主函数调用 +if __name__ == "__main__": + traffic_light_real_time_detection() \ No newline at end of file