基于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
关键说明
- 集合
detected_objects:用来存储已经打印过的物体名称,利用集合的唯一性避免重复记录。 - 筛选有效检测结果:和可视化时的
min_score_thresh=.8保持一致,只处理置信度达标结果。 - 匹配物体名称:通过
category_index将检测类别ID转换为对应名称,确保打印内容准确。
如果需要实现「物体离开画面后再次出现时重新打印」的功能,可以额外添加逻辑定期清理集合或检测物体是否消失,根据需求调整即可。
内容的提问来源于stack exchange,提问作者Michal
相关产品推荐
相关产品推荐

