+
96
-

回答

实现摄像头统计双向车流量和入口进出人流量,可以使用Python结合OpenCV和深度学习模型(如YOLO、SSD等)来检测和跟踪车辆和行人。

为了确保一个人或车在摄像头中进出只算一个,你需要引入对象跟踪机制。常见的对象跟踪算法有KCF、CSRT、MOSSE等。通过对象跟踪,你可以跟踪每个检测到的对象,并在它们离开视野后再计数。以下是一个基本的示例代码,使用OpenCV的CSRT跟踪器来跟踪检测到的对象,并确保每个对象只计数一次:

所需库安装

首先,你需要安装一些必要的Python库:

pip install opencv-pythonpip install numpypip install imutilspip install pafypip install youtube-dl

下载YOLOv3模型

下载YOLOv3的配置文件和权重文件:

yolov3.cfg https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg

yolov3.weights   https://pjreddie.com/media/files/yolov3.weights

coco.names  https://github.com/pjreddie/darknet/blob/master/data/coco.names

确保这些文件放在同一个目录下。

代码示例

以下是一个基本的示例代码,使用YOLOv3进行车辆和行人检测,并统计双向车流量和入口进出人流量:

import cv2
import numpy as np
import imutils

# 加载YOLOv3模型
net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# 加载COCO类标签
with open('coco.names', 'r') as f:
    classes = [line.strip() for line in f.readlines()]

# 初始化视频流
cap = cv2.VideoCapture(0)  # 使用摄像头
# cap = cv2.VideoCapture('video.mp4')  # 使用视频文件

# 初始化计数器
vehicle_count = 0
person_count = 0

trackers = cv2.MultiTracker_create()

while True:
    ret, frame = cap.read()
    if not ret:
        break

    frame = imutils.resize(frame, width=600)
    height, width, channels = frame.shape

    # 检测对象
    blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
    net.setInput(blob)
    outs = net.forward(output_layers)

    # 信息显示
    class_ids = []
    confidences = []
    boxes = []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > 0.5:
                # 对象检测
                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)

    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

    for i in range(len(boxes)):
        if i in indexes:
            x, y, w, h = boxes[i]
            label = str(classes[class_ids[i]])
            confidence = confidences[i]
            color = (0, 255, 0) if label == 'car' or label == 'truck' else (0, 0, 255)
            cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
            cv2.putText(frame, f"{label} {confidence:.2f}", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)

            # 添加跟踪器
            tracker = cv2.TrackerCSRT_create()
            trackers.add(tracker, frame, (x, y, w, h))

    # 更新跟踪器
    success, boxes = trackers.update(frame)
    for i, newbox in enumerate(boxes):
        p1 = (int(newbox[0]), int(newbox[1]))
        p2 = (int(newbox[0] + newbox[2]), int(newbox[1] + newbox[3]))
        cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)

        # 计数逻辑
        if success:
            label = str(classes[class_ids[i]])
            if label in ['car', 'truck']:
                vehicle_count += 1
            elif label == 'person':
                person_count += 1

    # 显示计数
    cv2.putText(frame, f"Vehicles: {vehicle_count}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    cv2.putText(frame, f"Persons: {person_count}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

    # 显示结果帧
    cv2.imshow("Frame", frame)

    # 按下 'q' 键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头并关闭所有窗口
cap.release()
cv2.destroyAllWindows()
代码解释

初始化跟踪器:使用 cv2.MultiTracker_create() 初始化多目标跟踪器。

添加跟踪器:在检测到新对象时,创建一个新的CSRT跟踪器,并将其添加到多目标跟踪器中。

更新跟踪器:在每一帧中,更新所有跟踪器,并绘制跟踪框。

计数逻辑:在成功跟踪到对象时,更新计数器。

注意事项

这个示例代码是一个基本的对象跟踪器,实际应用中可能需要更多的优化和处理,例如处理跟踪失败、对象重新进入视野等。

CSRT跟踪器在计算资源上要求较高,确保你的计算机有足够的处理能力。

如果需要更精确的跟踪和计数,可以考虑使用其他深度学习模型和跟踪算法(如DeepSORT等)。

网友回复

我知道答案,我要回答