You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算机视觉车牌检测存储项目:单车牌重复抓拍问题求助

车牌检测重复抓拍问题解决

我正在进行计算机视觉方向的项目,需实现车辆车牌检测、抓拍并将图片存储至指定文件夹。编写的代码逻辑为:当车牌目标完全进入矩形框时,脚本会抓拍并存储该图片。但目前遇到问题:单个车牌目标会被重复抓拍并存储多张图片。


解决方案思路

要解决重复抓拍问题,核心是跟踪车牌目标的进入状态——只有当车牌从"不在框内"变为"进入框内"的瞬间才触发抓拍,而非只要在框内就持续触发。这里采用状态标记+唯一标识的方案,确保同一车牌仅被抓拍一次。


修改后的完整代码

import cv2
import os
from ultralytics import YOLO

# 源视频文件路径
video_path = 'sample.mp4'

# 存储抓拍图片的目录
output_directory = 'captured_images'
os.makedirs(output_directory, exist_ok=True)

# 使用训练好的模型创建YOLO对象
yolo = YOLO('./models/license_plate_detector.pt') # 替换为你的训练权重实际路径

# 创建VideoCapture对象
cap = cv2.VideoCapture(video_path)

# 检查视频是否成功打开
if not cap.isOpened():
    print("Error: Could not open video.")
    exit()

# 获取视频属性
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
aspect_ratio = frame_width / frame_height

# 设置窗口大小以匹配视频宽高比
window_height = 768
window_width = int(window_height * aspect_ratio)
cv2.namedWindow("Video with Rectangle", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Video with Rectangle", window_width, window_height)

# 矩形框的坐标与尺寸
x, y, width, height = 2200, 1600, 700, 100

# 存储已抓拍过的车牌标识,避免重复抓拍
captured_plates = set()
image_counter = 1

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

    # 使用训练好的YOLO模型检测目标
    results = yolo(frame)

    # 获取检测框
    detected_boxes = results[0].boxes.xyxy  # 检测框格式:xmin, ymin, xmax, ymax

    # 记录当前帧中在框内的车牌标识
    current_in_box = set()

    for box in detected_boxes:
        x_min, y_min, x_max, y_max = box[:4]
        center_x = (x_min + x_max) / 2
        center_y = (y_min + y_max) / 2

        # 生成车牌唯一标识(用中心坐标取整哈希,避免浮点精度问题)
        plate_id = (int(center_x // 10), int(center_y // 10))

        # 检查是否在触发框内
        if x < center_x < x + width and y < center_y < y + height:
            current_in_box.add(plate_id)
            # 仅对未抓拍过的车牌执行存储
            if plate_id not in captured_plates:
                # 截取检测到的目标区域
                object_frame = frame[int(y_min):int(y_max), int(x_min):int(x_max)]
                # 保存目标图片
                image_filename = os.path.join(output_directory, f"captured_object_{image_counter}.jpg")
                cv2.imwrite(image_filename, object_frame)
                print(f"已抓拍并存储: {image_filename}")
                image_counter += 1
                # 标记该车牌为已抓拍
                captured_plates.add(plate_id)
        else:
            # 车牌离开框内时移除标记,支持后续再次进入时抓拍(可选)
            if plate_id in captured_plates:
                captured_plates.remove(plate_id)

    # 在帧上绘制矩形框
    cv2.rectangle(frame, (x, y), (x + width, y + height), (0, 255, 0), 2)

    # 显示帧
    cv2.imshow("Video with Rectangle", frame)

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

# 释放视频捕获对象
cap.release()

# 关闭所有窗口
cv2.destroyAllWindows()

关键改动说明

  1. 新增captured_plates集合:存储已抓拍车牌的唯一标识,防止重复触发。
  2. 生成plate_id:用车牌中心坐标取整哈希作为唯一标识,解决浮点精度导致的重复识别问题。
  3. 状态判断逻辑:仅当车牌首次进入框内且未被抓拍时执行存储;车牌离开框内时可移除标记,支持再次进入时抓拍(可根据需求关闭此逻辑)。
  4. 可选优化:若需更精准的目标跟踪,可改用YOLO的跟踪模式(yolo.track()),直接使用模型返回的id作为plate_id,确保移动中的车牌被准确识别为同一目标。

内容的提问来源于stack exchange,提问作者Rajkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 06:34:52