| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- import os
- from ultralytics import YOLO
- def auto_label(image_dir, output_dir, model_path='model/best.pt', conf=0.5, save_segmentation=True):
- """
- 使用 YOLO 模型自动标注图片并生成 TXT 标签文件。
- """
- # 检查模型文件是否存在
- if not os.path.exists(model_path):
- print(f"错误: 模型文件不存在 -> {model_path}")
- # 尝试使用根目录下的 yolov8n-seg.pt 作为备选
- fallback_model = 'yolov8n-seg.pt'
- if os.path.exists(fallback_model):
- print(f"尝试使用备选模型 -> {fallback_model}")
- model_path = fallback_model
- else:
- return
- # 加载模型
- print(f"正在加载模型: {model_path} ...")
- model = YOLO(model_path)
- # 确保输出目录存在
- if not os.path.exists(output_dir):
- os.makedirs(output_dir)
- print(f"创建输出目录: {output_dir}")
- # 支持的图片格式
- img_extensions = ('.jpg', '.jpeg', '.png', '.bmp', '.webp')
-
- # 获取图片列表
- image_files = [f for f in os.listdir(image_dir) if f.lower().endswith(img_extensions)]
- total_files = len(image_files)
-
- print(f"找到 {total_files} 张图片,开始自动标注...")
- count = 0
- for idx, img_file in enumerate(image_files):
- img_path = os.path.join(image_dir, img_file)
- txt_filename = os.path.splitext(img_file)[0] + ".txt"
- txt_path = os.path.join(output_dir, txt_filename)
- # 推理
- # stream=True 可以节省内存,但对于单张处理差异不大
- results = model(img_path, conf=conf, verbose=False)
- for result in results:
- with open(txt_path, 'w') as f:
- # 优先尝试保存分割掩码
- if save_segmentation and result.masks is not None:
- # result.masks.xyn 获取归一化的多边形坐标片段
- if hasattr(result.masks, 'xyn'):
- for i, seg in enumerate(result.masks.xyn):
- cls = int(result.boxes.cls[i]) # 对应的类别
- # 格式: class x1 y1 x2 y2 ...
- # flatten() 将数组展平,tolist() 转为列表
- coords = " ".join([f"{p[0]:.6f} {p[1]:.6f}" for p in seg])
- f.write(f"{cls} {coords}\n")
- else:
- pass # 兼容性处理
-
- # 如果没有分割结果或未启用分割,保存检测框
- elif result.boxes is not None:
- for box in result.boxes:
- cls = int(box.cls)
- # xywhn: x_center, y_center, width, height (normalized)
- x, y, w, h = box.xywhn[0].tolist()
- f.write(f"{cls} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\n")
-
- count += 1
- if count % 10 == 0:
- print(f"进度: {count}/{total_files}")
- print(f"完成!已生成 {count} 个标签文件。保存位置: {output_dir}")
- if __name__ == "__main__":
- # --- 配置区域 (请在此修改路径) ---
-
- # 待标注图片文件夹 (例如: d:\data\20251204)
- IMAGE_DIR = r'd:\data\20251204'
-
- # 标签保存文件夹 (例如: d:\data\20251204\labels_auto)
- OUTPUT_DIR = r'd:\data\20251204\labels_auto'
-
- # 模型路径 (例如: d:\data\model\best.pt)
- MODEL_PATH = r'd:\data\best.pt'
-
- # 置信度阈值
- CONF_THRESHOLD = 0.5
-
- # 是否保存分割点 (True=保存多边形, False=只保存矩形框)
- SAVE_SEGMENTATION = True
- # --------------------------------
-
- # 检查输入目录是否存在,防止报错
- if not os.path.exists(IMAGE_DIR):
- print(f"错误: 图片目录不存在 -> {IMAGE_DIR}")
- print("请打开脚本修改 IMAGE_DIR 为正确的路径。")
- else:
- auto_label(IMAGE_DIR, OUTPUT_DIR, MODEL_PATH, CONF_THRESHOLD, SAVE_SEGMENTATION)
|