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

YOLOv8+ROS目标检测:识别类别带时间写入TXT失败求助

YOLOv8+ROS目标检测:识别类别与时间写入TXT文件失败问题处理

我正在用YOLOv8结合ROS开展目标检测任务,基础功能正常,但实现将检测框内识别到的类别名称搭配检测时间写入TXT文件时功能失效。我尝试了自己的代码实现但无法推进,目前正在查阅Ultralytics官方文档。以下是我的代码及TXT文件的错误输出:

原代码

#!/usr/bin/env python3

from ultralytics import YOLO    
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import os
import datetime

model = YOLO('yolov8n.pt')

# 创建存储识别标签的文件
label_file = open("labels.txt", "w")

def start_node():
    rospy.init_node('detect_pump')
    rospy.loginfo('detect_pump node started')
    rospy.Subscriber("/image", Image, process_image)
    rospy.spin()

def process_image(msg):
    bridge = CvBridge()
    orig = bridge.imgmsg_to_cv2(msg, "bgr8")
    image = orig
    results = model(orig, verbose=True, imgsz=640)
    resultado= model.predict(source="0")
    cv2.imshow('IMAGEM RECEBIDA', orig)
    cv2.waitKey(1)
    res_plotted = results[0].plot()
    cv2.imshow("result", res_plotted)
    cv2.waitKey(1)

    # 获取当前时间
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 将识别到的标签拼接成字符串
    labels_str = "\n".join(results.names)

    # 将标签和时间写入文件
    label_file.write(f"Data/Hora: {current_time}\n")
    label_file.write(f"Labels: \n{labels_str}\n\n")

if __name__ == '__main__':
    try:
        start_node()
    except rospy.ROSInterruptException:
        pass

# 使用完毕后关闭文件
label_file.close()

当前错误输出

Data/Hora: 2023-10-14 17:08:30
Resultados: [ultralytics.yolo.engine.results.Results object with attributes:

boxes: ultralytics.yolo.engine.results.Boxes object
keypoints: None
keys: ['boxes']
masks: None
names: {0: 'person', 1: 'bicycle', 2: 'car', 3: 'motorcycle', 4: 'airplane', 5: 'bus', 6: 'train', 7: 'truck', 8: 'boat', 9: 'traffic light', 10: 'fire hydrant', 11: 'stop sign', 12: 'parking meter', 13: 'bench', 14: 'bird', 15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe', 24: 'backpack', 25: 'umbrella', 26: 'handbag', 27: 'tie', 28: 'suitcase', 29: 'frisbee', 30: 'skis', 31: 'snowboard', 32: 'sports ball', 33: 'kite', 34: 'baseball bat', 35: 'baseball glove', 36: 'skateboard', 37: 'surfboard', 38: 'tennis racket', 39: 'bottle', 40: 'wine glass', 41: 'cup', 42: 'fork', 43: 'knife', 44: 'spoon', 45: 'bowl', 46: 'banana', 47: 'apple', 48: 'sandwich', 49: 'orange', 50: 'broccoli', 51: 'carrot', 52: 'hot dog', 53: 'pizza', 54: 'donut', 55: 'cake', 56: 'chair', 57: 'couch', 58: 'potted plant', 59: 'bed', 60: 'dining table', 61: 'toilet', 62: 'tv', 63: 'laptop', 64: 'mouse', 65: 'remote', 66: 'keyboard', 67: 'cell phone', 68: 'microwave', 69: 'oven', 70: 'toaster', 71: 'sink', 72: 'refrigerator', 73: 'book', 74: 'clock', 75: 'vase', 76: 'scissors', 77: 'teddy bear', 78: 'hair drier', 79: 'toothbrush'}
orig_img: array([[[253, 238, 255],
        [253, 238, 255],
        [253, 238, 255],
        ...,
        [191, 213, 146],
        [191, 222, 129],
        [191, 222, 129]],

       [[253, 238, 255],
        [253, 238, 255],
        [253, 238, 255],
        ...,
        [191, 213, 146],
        [191, 222, 129],
        [191, 222, 129]],

       [[253, 241, 255],
        [253, 241, 255],
        [253, 241, 255],
        ...,
        [192, 209, 156],
        [192, 216, 142],
        [192, 216, 142]],

       ...,

       [[131, 118, 154],
        [131, 118, 154],
        [130, 117, 153],
        ...,
        [ 22,  26,  32],
        [ 20,  25,  28],
        [ 19,  24,  27]],

       [[131, 118, 156],
        [130, 117, 155],
        [129, 116, 154],
        ...,
        [ 24,  28,  34],
        [ 22,  27,  30],
        [ 21,  26,  29]],

       [[131, 118, 156],
        [130, 117, 155],
        [128, 115, 153],
        ...,
        [ 25,  29,  35],
        [ 23,  28,  31],
        [ 22,  27,  30]]], dtype=uint8)
orig_shape: (640, 480)
path: 'image0.jpg'
probs: None
save_dir: None
speed: {'preprocess': 3.4890174865722656, 'inference': 41.97049140930176, 'postprocess': 2.0608901977539062}]

问题分析

  1. 类别获取错误:results.names是模型包含的全量类别字典,不是当前帧实际识别到的类别,导致输出所有80个COCO类别而非检测框内的目标。
  2. 冗余推理操作:代码中同时执行了model(orig)(处理ROS图像)和model.predict(source="0")(调用本地摄像头),后者完全多余,会浪费计算资源且干扰结果。
  3. 文件操作不规范:全局以写入模式("w")打开文件,每次运行会清空历史记录;且未及时刷新缓冲区,ROS节点运行时可能导致内容无法实时写入磁盘。

修正后的代码

#!/usr/bin/env python3

from ultralytics import YOLO    
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
import datetime

model = YOLO('yolov8n.pt')

def start_node():
    rospy.init_node('detect_pump')
    rospy.loginfo('detect_pump node started')
    rospy.Subscriber("/image", Image, process_image)
    rospy.spin()

def process_image(msg):
    bridge = CvBridge()
    orig = bridge.imgmsg_to_cv2(msg, "bgr8")
    # 仅对ROS传入的图像执行推理
    results = model(orig, verbose=True, imgsz=640)
    
    cv2.imshow('IMAGEM RECEBIDA', orig)
    cv2.waitKey(1)
    res_plotted = results[0].plot()
    cv2.imshow("result", res_plotted)
    cv2.waitKey(1)

    # 获取当前时间
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 提取当前帧识别到的类别名称
    detected_classes = []
    # 获取所有检测框的类别ID
    class_ids = results[0].boxes.cls.cpu().numpy()
    names = results[0].names
    for cls_id in class_ids:
        detected_classes.append(names[int(cls_id)])
    # 去重并拼接成字符串(避免同一类别多次出现)
    unique_classes = list(set(detected_classes))
    labels_str = "\n".join(unique_classes)

    # 以追加模式打开文件,确保历史记录不丢失,写入后立即刷新
    with open("labels.txt", "a", encoding="utf-8") as label_file:
        label_file.write(f"Data/Hora: {current_time}\n")
        label_file.write(f"Labels: \n{labels_str}\n\n")
        label_file.flush()

if __name__ == '__main__':
    try:
        start_node()
    except rospy.ROSInterruptException:
        pass

修正说明

  • 移除了多余的model.predict(source="0")调用,仅处理ROS订阅到的图像
  • 通过results[0].boxes.cls获取当前帧检测框的类别ID,再映射为类别名称,确保只输出实际识别到的目标
  • 使用with语句管理文件,自动处理打开/关闭,以追加模式("a")写入避免覆盖历史数据,每次写入后调用flush()确保内容实时写入磁盘
  • 对识别到的类别做了去重处理,避免同一帧内同一类别多次出现重复记录

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:30:55