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

基于TensorFlow 2实现摄像头目标检测:检测到物体时仅打印一次名称

基于TensorFlow的摄像头目标检测:实现物体仅单次打印

我正在参考教程编写基于TensorFlow的摄像头目标检测代码,需求是当检测到物体时,仅打印一次该物体的名称。

现有代码

摄像头检测主循环

cap = cv2.VideoCapture(0)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

while cap.isOpened(): 
    ret, frame = cap.read()
    image_np = np.array(frame)
    
    input_tensor = tf.convert_to_tensor(np.expand_dims(image_np, 0), dtype=tf.float32)
    detections = detect_fn(input_tensor)
    
    num_detections = int(detections.pop('num_detections'))
    detections = {key: value[0, :num_detections].numpy()
                  for key, value in detections.items()}
    detections['num_detections'] = num_detections

    # detection_classes should be ints.
    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

    label_id_offset = 1
    image_np_with_detections = image_np.copy()

    viz_utils.visualize_boxes_and_labels_on_image_array(
                image_np_with_detections,
                detections['detection_boxes'],
                detections['detection_classes']+label_id_offset,
                detections['detection_scores'],
                category_index,
                use_normalized_coordinates=True,
                max_boxes_to_draw=5,
                min_score_thresh=.8,
                agnostic_mode=False)

    cv2.imshow('object detection',  cv2.resize(image_np_with_detections, (800, 600)))
    
    if cv2.waitKey(10) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break

已训练完成的标签定义

labels = [{'name':'phone', 'id':1}, {'name':'headphones', 'id':2}, {'name':'glasses', 'id':3}, {'name':'mug', 'id':4}]

with open(files['LABELMAP'], 'w') as f:
    for label in labels:
        f.write('item { \n')
        f.write('\tname:\'{}\'\n'.format(label['name']))
        f.write('\tid:{}\n'.format(label['id']))
        f.write('}\n')

解决方案:实现仅单次打印

要实现检测到物体时仅打印一次名称,只需维护一个记录已打印物体的集合,每次检测时对比筛选即可:

修改后的完整代码

cap = cv2.VideoCapture(0)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 初始化集合,记录已经打印过的物体名称
detected_objects = set()

while cap.isOpened(): 
    ret, frame = cap.read()
    image_np = np.array(frame)
    
    input_tensor = tf.convert_to_tensor(np.expand_dims(image_np, 0), dtype=tf.float32)
    detections = detect_fn(input_tensor)
    
    num_detections = int(detections.pop('num_detections'))
    detections = {key: value[0, :num_detections].numpy()
                  for key, value in detections.items()}
    detections['num_detections'] = num_detections

    # detection_classes should be ints.
    detections['detection_classes'] = detections['detection_classes'].astype(np.int64)

    label_id_offset = 1
    image_np_with_detections = image_np.copy()

    viz_utils.visualize_boxes_and_labels_on_image_array(
                image_np_with_detections,
                detections['detection_boxes'],
                detections['detection_classes']+label_id_offset,
                detections['detection_scores'],
                category_index,
                use_normalized_coordinates=True,
                max_boxes_to_draw=5,
                min_score_thresh=.8,
                agnostic_mode=False)

    # ------------------- 新增:仅单次打印物体名称 -------------------
    # 筛选出置信度符合阈值的检测结果
    valid_indices = detections['detection_scores'] >= 0.8
    current_classes = detections['detection_classes'][valid_indices] + label_id_offset
    
    # 获取当前检测到的物体名称
    current_objects = [category_index[cls]['name'] for cls in current_classes]
    
    # 遍历当前检测到的物体,仅打印未记录过的
    for obj in current_objects:
        if obj not in detected_objects:
            print(f"检测到新物体:{obj}")
            detected_objects.add(obj)
    # -------------------------------------------------------------

    cv2.imshow('object detection',  cv2.resize(image_np_with_detections, (800, 600)))
    
    if cv2.waitKey(10) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break

关键说明

  1. 集合detected_objects:用来存储已经打印过的物体名称,利用集合的唯一性避免重复记录。
  2. 筛选有效检测结果:和可视化时的min_score_thresh=.8保持一致,只处理置信度达标结果。
  3. 匹配物体名称:通过category_index将检测类别ID转换为对应名称,确保打印内容准确。

如果需要实现「物体离开画面后再次出现时重新打印」的功能,可以额外添加逻辑定期清理集合或检测物体是否消失,根据需求调整即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:55:22