基于opencv的车距智能检测系统

一、课题背景与意义

随着现代交通运输系统的日益发展和汽车数量的不断增加,如何提高行车安全性,避免交通事故,成为了交通管理的重中之重。尤其在高速公路、城市街道等高密度、复杂的交通环境下,车距的保持对于避免追尾事故至关重要。车距不足可能导致碰撞事故的发生,而车距过大又会导致交通流量降低。因此,车距检测技术成为了一项重要的研究课题,它能够为驾驶员提供安全行驶的依据。

目前,尽管很多高端汽车已经配备了自适应巡航控制(ACC)和碰撞预警系统等辅助驾驶技术,但这些技术一般都依赖于高成本的传感器,如雷达和激光雷达(LiDAR)。这些传感器的成本较高,且对于低成本或老旧车辆而言不可行。而图像处理技术,特别是利用普通摄像头结合计算机视觉技术进行车距检测,为低成本、高效率的车距检测提供了一种可行的解决方案。

本课题旨在设计一个基于OpenCV的车距检测系统,通过分析车辆的实时视频图像来估算车距,结合目标检测、目标跟踪和距离估计算法,为驾驶员提供实时车距反馈,并根据车距的变化进行预警提示。该系统具有广泛的应用前景,能够有效提高车辆行驶的安全性,尤其在低成本车辆中具有较高的普及价值。

二、课题目标与研究内容

1. 研究目标

本课题的主要目标是设计并实现一个基于OpenCV的车距检测系统,系统的核心功能包括:

通过视频流实时检测道路上行驶的车辆;
计算并估算与前方车辆的实际车距;
当车距过短时,系统能够发出预警信号,提示驾驶员注意安全车距。

具体来说,本课题将结合目标检测、目标跟踪和距离估计等计算机视觉算法,设计一个低成本、高实时性的车距检测系统,并对系统性能进行全面评估。

2. 研究内容

视频输入与预处理:使用视频流作为输入,通过图像处理技术进行预处理,去除噪声、调整图像大小、增强图像特征,以确保后续处理的效果。
车辆检测:采用YOLOv3(You Only Look Once)等先进的深度学习目标检测算法,对视频帧中的车辆进行检测,获取车辆的边界框信息。
目标跟踪:实现目标跟踪算法,跟踪检测到的车辆并保持目标信息的持续更新。
距离估计:基于单目视觉,通过计算车辆的像素宽度与实际宽度的比例,结合相机的焦距,估算与前方车辆的实际距离。
预警功能:根据实时计算的车距与预设的安全距离阈值对比,如果车距过短,则触发警告信号,提醒驾驶员及时调整车速或与前车保持更大的距离。
系统性能评估:通过实验数据验证系统的准确性、实时性,并对系统性能进行优化分析。

三、技术路线与实现方法

1. 技术路线

本课题主要采用计算机视觉技术与深度学习相结合的方式,利用OpenCV库进行图像处理和系统实现。具体技术路线如下:

graph TD
    A[视频输入] --> B[帧预处理]
    B --> C[车辆检测]
    C --> D[目标跟踪]
    D --> E[距离估计]
    E --> F[预警判断]
    F --> G[结果可视化]

视频输入与帧预处理
通过OpenCV的VideoCapture函数读取视频文件或实时视频流,提取每一帧图像。
对图像进行灰度化、归一化、去噪等基础图像处理,以提高后续算法的处理效果,减少噪声对检测结果的影响。
车辆检测
使用YOLOv3模型进行实时目标检测,YOLOv3能够在较高的帧率下提供较为准确的目标检测结果。通过此算法,能够准确识别视频帧中的车辆,并输出车辆在图像中的位置(即边界框)。
目标跟踪
采用自定义的质心跟踪算法来跟踪每一个检测到的车辆。该算法通过计算每一帧中车辆的位置与前一帧的差异,保证在车辆检测不到时仍能持续追踪目标。
距离估计
基于相似三角形原理,通过已知的标准车型宽度和车辆在图像中的像素宽度,结合相机的焦距来估算前车的距离。这种方法避免了使用激光雷达或雷达等昂贵传感器,降低了成本。
预警判断
当估算的车距小于设定的安全距离阈值时,系统会触发预警,并以声音或图像提示驾驶员,确保驾驶安全。
结果可视化
在图像中绘制检测到的车辆边界框、车距值以及预警状态,提供直观的结果展示。

2. 具体方法

YOLOv3目标检测
YOLOv3是当前广泛使用的深度学习目标检测算法,其优势在于高精度与高速度,适合实时视频处理。通过训练YOLOv3模型,能够在视频帧中准确检测到车辆的边界框。
质心跟踪算法
对于目标跟踪,采用了基于质心的跟踪算法,该算法通过计算每个车辆的质心位置(即车辆的中心坐标),并通过欧氏距离算法与上一帧的质心位置进行匹配,从而实现对目标的持续跟踪。
单目视觉车距估计
基于单目相机,通过已知的标准车型宽度和图像中车辆的像素宽度之间的比例关系,结合相机的焦距来估算车辆的距离。这种方法不仅具有较高的准确性,还避免了多目视觉或激光雷达的硬件成本。
车距预警与报警
通过设定一个安全车距阈值(例如:2秒的安全跟车距离),当估算的车距小于这个阈值时,系统会触发预警,提醒驾驶员保持安全车距。

四、主要技术与创新点

1. 目标检测与跟踪

YOLOv3目标检测:YOLOv3作为一种基于深度学习的目标检测算法,其通过全卷积网络将图像分割成多个网格单元,然后每个网格单元独立地预测包含目标的边界框及其类别。相比传统的滑动窗口检测方法,YOLOv3具有更高的处理速度和准确度。
多目标跟踪:采用基于质心的多目标跟踪算法,通过计算检测到的车辆在每帧图像中的质心位置,保持对每辆车的持续跟踪,避免了目标丢失和误识别的情况。

2. 距离估计

基于单目视觉的距离估计方法,通过计算车辆在图像中的像素宽度与实际车辆宽度的比例,结合相机的标定参数(焦距等),准确估算出车辆之间的距离。
该方法避免了高昂的硬件成本(如雷达和激光雷达),通过标准化的标定参数和简单的几何计算,能够以较低的成本提供可靠的车距估算。

3. 实时预警功能

通过设定车距的安全阈值,当系统检测到车辆之间的距离过短时,能够及时触发警告信号。该功能能够有效提高驾驶员的安全意识,减少因车距过短而导致的追尾事故。

4. 可视化展示

系统能够实时显示车辆检测与车距估算结果,并通过图像标注的方式将警告信息展示给驾驶员,提供清晰直观的结果展示。

五、系统设计与实现

1. 系统架构

本车距检测系统的整体架构采用模块化设计,每个模块负责特定的功能,主要模块包括:

视频输入与图像预处理模块:通过OpenCV读取视频流,对每一帧图像进行去噪、灰度化等预处理。
车辆检测模块:使用YOLOv3算法进行车辆的目标检测,输出车辆的边界框信息。

以下是一个基于OpenCV的车距检测系统的完整本科毕设核心代码参考案例实现,包含单目视觉测距、车辆检测与跟踪、安全预警等功能模块:

import cv2
import numpy as np
import math
from collections import deque

class VehicleDistanceDetector:
    def __init__(self):
        # 相机参数(需标定获得)
        self.focal_length = 1200  # 焦距(像素单位)
        self.car_width = 1.8      # 车辆平均宽度(米)
        
        # 车辆检测模型
        self.net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
        self.classes = []
        with open("coco.names", "r") as f:
            self.classes = [line.strip() for line in f.readlines()]
        self.layer_names = self.net.getLayerNames()
        self.output_layers = [self.layer_names[i - 1] for i in self.net.getUnconnectedOutLayers()]
        
        # 跟踪器
        self.tracked_vehicles = {}
        self.track_id = 0
        self.max_disappeared = 5  # 最大消失帧数
        
        # 距离阈值(米)
        self.safe_distance = 5.0
        self.warning_distance = 3.0
        self.danger_distance = 1.5
        
        # 可视化设置
        self.color_map = {
            "safe": (0, 255, 0),    # 绿色
            "warning": (0, 255, 255), # 黄色
            "danger": (0, 0, 255)    # 红色
        }
        
        # 帧处理队列
        self.frame_queue = deque(maxlen=5)
    
    def _calculate_distance(self, width_in_pixels):
        """根据车辆像素宽度计算实际距离"""
        if width_in_pixels == 0:
            return float('inf')
        return (self.car_width * self.focal_length) / width_in_pixels
    
    def _detect_vehicles(self, frame):
        """使用YOLOv3检测车辆"""
        height, width = frame.shape[:2]
        
        # 预处理
        blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
        self.net.setInput(blob)
        outs = self.net.forward(self.output_layers)
        
        # 解析检测结果
        boxes = []
        confidences = []
        class_ids = []
        
        for out in outs:
            for detection in out:
                scores = detection[5:]
                class_id = np.argmax(scores)
                confidence = scores[class_id]
                
                # 只保留汽车、卡车、公交车等类别
                if confidence > 0.5 and class_id in [2, 5, 7]:  
                    center_x = int(detection[0] * width)
                    center_y = int(detection[1] * height)
                    w = int(detection[2] * width)
                    h = int(detection[3] * height)
                    
                    # 矩形框坐标
                    x = int(center_x - w / 2)
                    y = int(center_y - h / 2)
                    
                    boxes.append([x, y, w, h])
                    confidences.append(float(confidence))
                    class_ids.append(class_id)
        
        # 非极大值抑制
        indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
        
        vehicles = []
        for i in indices:
            box = boxes[i]
            vehicles.append({
                "box": box,
                "confidence": confidences[i],
                "class_id": class_ids[i]
            })
            
        return vehicles
    
    def _update_tracker(self, detections):
        """更新车辆跟踪状态"""
        # 初始化返回结果
        tracked_objects = {}
        
        # 如果没有检测到车辆,更新所有跟踪器的disappeared计数
        if len(detections) == 0:
            for object_id in list(self.tracked_vehicles.keys()):
                self.tracked_vehicles[object_id]["disappeared"] += 1
                if self.tracked_vehicles[object_id]["disappeared"] > self.max_disappeared:
                    del self.tracked_vehicles[object_id]
            return tracked_objects
        
        # 当前帧的检测框中心点
        centroids = np.zeros((len(detections), 2), dtype="int")
        
        for (i, detection) in enumerate(detections):
            (x, y, w, h) = detection["box"]
            cx = x + w // 2
            cy = y + h // 2
            centroids[i] = (cx, cy)
        
        # 如果是第一次检测,初始化所有跟踪器
        if len(self.tracked_vehicles) == 0:
            for i in range(len(detections)):
                self.tracked_vehicles[self.track_id] = {
                    "centroid": centroids[i],
                    "bbox": detections[i]["box"],
                    "disappeared": 0,
                    "distance_history": deque(maxlen=10)
                }
                self.track_id += 1
        else:
            # 计算现有跟踪对象与新检测对象的欧氏距离
            object_ids = list(self.tracked_vehicles.keys())
            object_centroids = [self.tracked_vehicles[obj_id]["centroid"] for obj_id in object_ids]
            
            # 计算距离矩阵
            D = np.zeros((len(object_ids), len(detections)), dtype="float")
            for i in range(len(object_ids)):
                for j in range(len(detections)):
                    D[i, j] = math.sqrt(
                        (object_centroids[i][0] - centroids[j][0])**2 + 
                        (object_centroids[i][1] - centroids[j][1])**2
                    )
            
            # 匈牙利算法匹配
            rows = D.min(axis=1).argsort()
            cols = D.argmin(axis=1)[rows]
            
            used_rows = set()
            used_cols = set()
            
            for (row, col) in zip(rows, cols):
                if row in used_rows or col in used_cols:
                    continue
                    
                object_id = object_ids[row]
                self.tracked_vehicles[object_id]["centroid"] = centroids[col]
                self.tracked_vehicles[object_id]["bbox"] = detections[col]["box"]
                self.tracked_vehicles[object_id]["disappeared"] = 0
                
                tracked_objects[object_id] = self.tracked_vehicles[object_id]
                
                used_rows.add(row)
                used_cols.add(col)
            
            # 处理未匹配的检测(新出现的车辆)
            unused_cols = set(range(len(detections))) - used_cols
            for col in unused_cols:
                self.tracked_vehicles[self.track_id] = {
                    "centroid": centroids[col],
                    "bbox": detections[col]["box"],
                    "disappeared": 0,
                    "distance_history": deque(maxlen=10)
                }
                tracked_objects[self.track_id] = self.tracked_vehicles[self.track_id]
                self.track_id += 1
            
            # 处理未匹配的跟踪(消失的车辆)
            unused_rows = set(range(len(object_ids))) - used_rows
            for row in unused_rows:
                object_id = object_ids[row]
                self.tracked_vehicles[object_id]["disappeared"] += 1
                
                if self.tracked_vehicles[object_id]["disappeared"] > self.max_disappeared:
                    del self.tracked_vehicles[object_id]
        
        return tracked_objects
    
    def _estimate_distance(self, tracked_objects):
        """估计并更新车辆距离"""
        for object_id, obj in tracked_objects.items():
            (x, y, w, h) = obj["bbox"]
            distance = self._calculate_distance(w)
            obj["distance_history"].append(distance)
            
            # 使用历史距离的平均值
            avg_distance = sum(obj["distance_history"]) / len(obj["distance_history"])
            tracked_objects[object_id]["current_distance"] = avg_distance
            
            # 判断距离级别
            if avg_distance <= self.danger_distance:
                tracked_objects[object_id]["status"] = "danger"
            elif avg_distance <= self.warning_distance:
                tracked_objects[object_id]["status"] = "warning"
            else:
                tracked_objects[object_id]["status"] = "safe"
        
        return tracked_objects
    
    def process_frame(self, frame):
        """处理视频帧"""
        # 车辆检测
        vehicles = self._detect_vehicles(frame)
        
        # 更新跟踪器
        tracked_objects = self._update_tracker(vehicles)
        
        # 距离估计
        tracked_objects = self._estimate_distance(tracked_objects)
        
        # 可视化
        result_frame = self._visualize(frame, tracked_objects)
        
        return result_frame, tracked_objects
    
    def _visualize(self, frame, tracked_objects):
        """可视化检测结果"""
        for object_id, obj in tracked_objects.items():
            (x, y, w, h) = obj["bbox"]
            distance = obj["current_distance"]
            status = obj["status"]
            
            # 绘制边界框
            color = self.color_map[status]
            cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
            
            # 显示ID和距离
            label = f"ID:{object_id} {distance:.1f}m"
            cv2.putText(frame, label, (x, y - 10), 
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
            
            # 状态提示
            if status == "danger":
                warning_text = "DANGER! TOO CLOSE!"
                text_size = cv2.getTextSize(warning_text, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)[0]
                cv2.putText(frame, warning_text, 
                            ((frame.shape[1] - text_size[0]) // 2, 50),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
        
        # 显示最近距离
        if tracked_objects:
            min_distance = min([obj["current_distance"] for obj in tracked_objects.values()])
            cv2.putText(frame, f"Min Distance: {min_distance:.1f}m", 
                        (20, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
        
        return frame

def main():
    # 初始化检测器
    detector = VehicleDistanceDetector()
    
    # 视频源(0-摄像头,或视频文件路径)
    video_source = "test_video.mp4"
    cap = cv2.VideoCapture(video_source)
    
    # 视频输出设置
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('output.avi', fourcc, 20.0, 
                         (int(cap.get(3)), int(cap.get(4))))
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        
        # 处理帧
        processed_frame, distances = detector.process_frame(frame)
        
        # 显示结果
        cv2.imshow("Vehicle Distance Detection", processed_frame)
        out.write(processed_frame)
        
        # 退出键
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # 释放资源
    cap.release()
    out.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

代码说明文档

1. 系统架构

该车距检测系统采用模块化设计,主要包含以下功能模块:

车辆检测:基于YOLOv3深度学习模型
目标跟踪:基于质心跟踪算法
距离估计:单目视觉几何测距
安全预警:三级距离预警系统
可视化界面:实时显示检测结果

2. 关键技术实现

相机标定参数

focal_length:相机焦距(需通过标定获得)
car_width:车辆平均宽度(先验知识)

距离计算公式
distance=real_width×focal_lengthpixel_width ext{distance} = frac{ ext{real\_width} imes ext{focal\_length}}{ ext{pixel\_width}} distance=pixel_widthreal_width×focal_length​
多目标跟踪

使用匈牙利算法进行检测框匹配
消失帧数计数管理

三级预警机制

安全距离(>5m):绿色框
警告距离(3-5m):黄色框
危险距离(<1.5m):红色框+文字警示

3. 使用方法

准备YOLOv3模型文件:

下载yolov3.weights、yolov3.cfg和coco.names
放置在与脚本相同的目录下

运行程序:

python vehicle_distance.py

参数调整:

修改video_source变量切换视频源
调整safe_distance等阈值参数

4. 扩展建议

相机标定:使用OpenCV的棋盘格标定获取精确的焦距参数
模型优化:替换为YOLOv4或YOLOv7提升检测精度
多传感器融合:结合雷达数据进行距离验证
三维测距:使用双目视觉实现更精确的测距

分步骤进行解析:

1. 算法整体架构

graph TD
    A[视频输入] --> B[帧预处理]
    B --> C[车辆检测]
    C --> D[目标跟踪]
    D --> E[距离估计]
    E --> F[预警判断]
    F --> G[结果可视化]

2. 核心模块实现

2.1 相机标定与参数准备
def load_camera_params(config_file):
    """加载相机标定参数"""
    import json
    with open(config_file) as f:
        params = json.load(f)
    return params

# 标定参数示例
camera_params = {
    "focal_length": 1250,    # 像素单位
    "sensor_width": 4.8,     # 毫米
    "frame_width": 1920,     # 像素
    "car_width_ref": 1.8     # 标准车辆宽度(米)
}
2.2 车辆检测模块

YOLOv3检测实现

class VehicleDetector:
    def __init__(self):
        self.net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
        self.classes = ["car", "truck", "bus"]
        self.conf_threshold = 0.5
        self.nms_threshold = 0.4
        
    def detect(self, frame):
        height, width = frame.shape[:2]
        blob = cv2.dnn.blobFromImage(frame, 1/255, (416,416), swapRB=True)
        self.net.setInput(blob)
        outs = self.net.forward(self._get_output_layers())
        
        boxes, confs, class_ids = [], [], []
        
        for out in outs:
            for detection in out:
                scores = detection[5:]
                class_id = np.argmax(scores)
                confidence = scores[class_id]
                
                if confidence > self.conf_threshold and 
                   self.classes[class_id] in self.classes:
                    
                    center_x = int(detection[0] * width)
                    center_y = int(detection[1] * height)
                    w = int(detection[2] * width)
                    h = int(detection[3] * height)
                    
                    x = center_x - w // 2
                    y = center_y - h // 2
                    
                    boxes.append([x, y, w, h])
                    confs.append(float(confidence))
                    class_ids.append(class_id)
        
        indices = cv2.dnn.NMSBoxes(boxes, confs, self.conf_threshold, self.nms_threshold)
        return [boxes[i] for i in indices]
2.3 目标跟踪模块

改进的质心跟踪算法

class CentroidTracker:
    def __init__(self, max_disappeared=5):
        self.next_id = 0
        self.objects = {}
        self.disappeared = {}
        self.max_disappeared = max_disappeared
        
    def update(self, rects):
        new_objects = {}
        
        # 当前帧物体中心点计算
        centroids = np.zeros((len(rects), 2), dtype="int")
        for (i, (x, y, w, h)) in enumerate(rects):
            cx = x + w // 2
            cy = y + h // 2
            centroids[i] = (cx, cy)
        
        # 首帧初始化
        if len(self.objects) == 0:
            for i in range(len(centroids)):
                self.objects[self.next_id] = centroids[i]
                self.disappeared[self.next_id] = 0
                self.next_id += 1
        else:
            # 计算所有欧式距离
            object_ids = list(self.objects.keys())
            object_centroids = list(self.objects.values())
            
            D = np.zeros((len(object_centroids), len(centroids)), dtype=np.float32)
            for i in range(len(object_centroids)):
                for j in range(len(centroids)):
                    D[i, j] = np.linalg.norm(object_centroids[i] - centroids[j])
            
            # 匈牙利算法匹配
            rows = D.min(axis=1).argsort()
            cols = D.argmin(axis=1)[rows]
            
            used_rows, used_cols = set(), set()
            
            for (row, col) in zip(rows, cols):
                if row in used_rows or col in used_cols:
                    continue
                    
                object_id = object_ids[row]
                new_objects[object_id] = centroids[col]
                self.disappeared[object_id] = 0
                used_rows.add(row)
                used_cols.add(col)
            
            # 处理未匹配对象
            unused_rows = set(range(D.shape[0])) - used_rows
            unused_cols = set(range(D.shape[1])) - used_cols
            
            for row in unused_rows:
                object_id = object_ids[row]
                self.disappeared[object_id] += 1
                
                if self.disappeared[object_id] > self.max_disappeared:
                    del self.objects[object_id]
                    del self.disappeared[object_id]
            
            for col in unused_cols:
                self.objects[self.next_id] = centroids[col]
                self.disappeared[self.next_id] = 0
                self.next_id += 1
        
        return new_objects
2.4 距离估计算法

单目测距实现

class DistanceEstimator:
    def __init__(self, params):
        self.focal = params["focal_length"]
        self.ref_width = params["car_width_ref"]
        
    def calculate_distance(self, pixel_width):
        """基于相似三角形原理的距离计算"""
        if pixel_width <= 0:
            return float('inf')
        return (self.ref_width * self.focal) / pixel_width
    
    def refine_distance(self, distances, method='median'):
        """距离值滤波优化"""
        if method == 'median':
            return np.median(distances)
        elif method == 'mean':
            return np.mean(distances)
        else:
            return distances[-1]
2.5 预警系统实现
class SafetyMonitor:
    LEVELS = {
        "safe": (5.0, float('inf'), (0, 255, 0)),
        "warning": (3.0, 5.0, (0, 255, 255)),
        "danger": (0, 3.0, (0, 0, 255))
    }
    
    def check_level(self, distance):
        for level, (min_d, max_d, color) in self.LEVELS.items():
            if min_d <= distance < max_d:
                return level, color
        return "unknown", (255, 255, 255)
    
    def audio_alert(self, level):
        if level == "danger":
            # 播放报警音效
            import winsound
            winsound.Beep(2000, 500)

3. 主系统集成

class VehicleDistanceSystem:
    def __init__(self):
        self.camera_params = load_camera_params("camera.json")
        self.detector = VehicleDetector()
        self.tracker = CentroidTracker()
        self.estimator = DistanceEstimator(self.camera_params)
        self.monitor = SafetyMonitor()
        
        # 历史数据缓存
        self.distance_history = {}
        
    def process_frame(self, frame):
        # 车辆检测
        boxes = self.detector.detect(frame)
        
        # 目标跟踪
        tracked_objs = self.tracker.update(boxes)
        
        # 距离计算与预警
        results = []
        for obj_id, centroid in tracked_objs.items():
            x, y, w, h = boxes[obj_id]
            
            # 距离估计
            distance = self.estimator.calculate_distance(w)
            
            # 缓存历史数据
            if obj_id not in self.distance_history:
                self.distance_history[obj_id] = deque(maxlen=10)
            self.distance_history[obj_id].append(distance)
            
            # 距离滤波
            filtered_dist = self.estimator.refine_distance(
                list(self.distance_history[obj_id])
            )
            
            # 安全评估
            level, color = self.monitor.check_level(filtered_dist)
            
            results.append({
                "id": obj_id,
                "bbox": (x, y, w, h),
                "distance": filtered_dist,
                "level": level,
                "color": color
            })
        
        return frame, results
    
    def visualize(self, frame, results):
        for obj in results:
            x, y, w, h = obj["bbox"]
            
            # 绘制边界框
            cv2.rectangle(frame, (x,y), (x+w,y+h), obj["color"], 2)
            
            # 显示信息
            text = f"ID:{obj['id']} {obj['distance']:.1f}m"
            cv2.putText(frame, text, (x, y-10), 
                       cv2.FONT_HERSHEY_SIMPLEX, 0.6, obj["color"], 2)
            
            # 危险状态特殊提示
            if obj["level"] == "danger":
                cv2.putText(frame, "DANGER!", (x, y+h+20),
                          cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255), 2)
                
        # 显示最近车距
        if results:
            min_dist = min([obj["distance"] for obj in results])
            cv2.putText(frame, f"Min Distance: {min_dist:.1f}m", 
                       (20,40), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)
            
        return frame

4. 完整运行示例

def main():
    system = VehicleDistanceSystem()
    cap = cv2.VideoCapture("highway.mp4")
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
            
        # 处理帧
        processed_frame, results = system.process_frame(frame)
        output_frame = system.visualize(processed_frame, results)
        
        # 显示结果
        cv2.imshow("Vehicle Distance Monitor", output_frame)
        if cv2.waitKey(30) == 27:  # ESC退出
            break
    
    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

5. 关键优化技术

距离计算优化

# 动态焦距调整(根据车辆位置)
def dynamic_focal_length(self, y_pos, frame_height):
    """考虑透视效应的动态焦距"""
    baseline_focal = self.focal
    pos_ratio = y_pos / frame_height
    return baseline_focal * (1 + 0.5 * pos_ratio)

多目标跟踪改进

# 添加速度预测
def predict_position(self, obj_id):
    history = self.positions[obj_id]
    if len(history) >= 2:
        vx = history[-1][0] - history[-2][0]
        vy = history[-1][1] - history[-2][1]
        return (history[-1][0]+vx, history[-1][1]+vy)
    return history[-1]

夜间模式增强

def enhance_night_vision(image):
    lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    l, a, b = cv2.split(lab)
    clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))
    l_enhanced = clahe.apply(l)
    lab_enhanced = cv2.merge((l_enhanced,a,b))
    return cv2.cvtColor(lab_enhanced, cv2.COLOR_LAB2BGR)

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容