本文章主要记录了本人在日常使用魔搭社区进行目标检测训练时的一些心得和代码,以供自己随时查看,同时也分享给大家,大家一起进步。
1. zip解压
1.1 在notebook环境下解压zip文件指令
注意:指令前方的‘!’必须添加,否则报错无法解压。
!unzip datasets.zip
1.2 在webIDE环境下解压zip文件
Jieya.py主要作用是将上传到云端的zip文件进行解压,核心为导入zipfile库。
import zipfile if __name__ == '__main__': zip_file_path = 'D:/test.zip' with zipfile.ZipFile(zip_file_path, 'r') as zip_ref: zip_ref.extractall('.') # .表示解压到当前目录
2. data.yaml训练配置文件
data.yaml是YOLO系列目标检测模型中用于配置数据集信息的核心文件基本结构为,train文件夹下的images路径,val文件夹下的images路径,nc类别数量,calsses类别名称。
train: /mnt/workspace/datasets/train/images val: /mnt/workspace/datasets/val/images nc: 8 names: ['test00', 'test01', 'test02', 'test03', 'test04', 'test05', 'test06', 'test07' ]
3. train.py训练文件
train.py文件为模型训练文件,主要逻辑为导入YOLO库,加载预训练权重文件,利用YOLO库的train方法以及data.yaml配置文件,及相关训练参数对我们的数据集进行训练。
from ultralytics import YOLO if __name__ == '__main__': model = YOLO("yolo11n.pt") model.train(data="data.yaml", epochs=200, imgsz=640, batch=-1, workers=4, patience=0)
4. 安装ultralytics及字体库指令
主要安装ultralytics库;创建/root/.config/Ultralytics/路径;复制文件到/root/.config/Ultralytics/路径下。
Arial.ttf和Arial.Unicode.ttf这两个文件可以提前下载好,然后上传到云端即可直接使用
pip install ultralytics mkdir -p /root/.config/Ultralytics/ cp Arial.ttf Arial.Unicode.ttf /root/.config/Ultralytics/
5.运行train.py文件(在notebook环境下)
当然也可以将运行代码直接写在notebook代码块下,点击运行即可。
%run train.py
6.best.pt文件转换
转换成onnx或者openvino格式文件。
from ultralytics import YOLO if __name__ == '__main__': model = YOLO(r'/mnt/workspace/runs/detect/train3/weights/best.pt') model.export(format='onnx') # 如果需要转换成openvion格式,将‘onnx'替换成'openvino'即可 #model.export(format='openvino')
7.model.yaml自动标注配置文件
type: yolo11 name: yolo11 display_name: yolo2025 model_path: G:\yolo\video\best.onnx nms_threshold: 0.45 confidence_threshold: 0.25 classes: - test - test - test - test - test - test - test
8.通过best.pt模型推理图片
在YOLO的参数里面增加检测模式 task='detect';在检测方法的参数里面增加stream=True,同时增加
for r in results:
boxes = r.boxes # Boxes object for bbox outputs
主要目的是,如果不添加上述操作,在对大量图片进行推理的时候随着推理图片的增加,内存占用会越来越高,导致推理速度减慢,电脑性能下降,添加以上代码,在推理的过程中会不断的释放内存,以达到最佳性能。
from ultralytics import YOLO if __name__ == '__main__': model = YOLO(r'runs/detect/train7/weights/best.pt', task='detect') results = model.predict(source=r'/mnt/workspace/deng/train/images/00000.jpg',save=True, stream=True) # 如果批量将图片进行推理,只需要将路径更换成图片文件夹路径即可 for r in results: boxes = r.boxes # Boxes object for bbox outputs
9.通过best.pt模型推理视频
from ultralytics import YOLO if __name__=='__main__': model = YOLO('best.pt', task='detect') results = model.predict(source='test_video.mp4', stream=True) for result in results: boxes = result.boxes
10.对视频进行推理并将推理结果逐帧保存
from ultralytics import YOLO if __name__ == '__main__': model = YOLO(r'C:\Users\HF03\Desktop\test02\datasets\best.pt') model.predict( source=r'C:\Users\HF03\Desktop\test_video.mp4', # 填写需要推理的视频路径 save=True save_frames=True, # 启用逐帧保存 #vid_stride=5, # 启用每隔5帧保存推理结果(按需启用) project=r'C:\Users\HF03\Desktop\test02\results5', # 指定保存文件夹路径 #name='prediction_frames' # 子文件夹名称 )
11.通过openvino模型推理图片
from ultralytics import YOLO if __name__ == '__main__': model = YOLO(r'G:\individual\study\YOLO\modelcar20250628\best (1)_openvino_model') # 更换成转换后的openvino文件夹路径 model.predict(source=r'/mnt/workspace/deng/train/images/00000.jpg',save=True) # 如果批量将图片进行推理,只需要将路径更换成图片文件夹路径即可
11.1 推理图片并打印置信度信息
from ultralytics import YOLO if __name__ == '__main__': model = YOLO(r'/mnt/workspace/runs/detect/train70/weights/best.pt') results = model.predict(source=r'/mnt/workspace/tuili', save=True, imgsz=1280) for i, result in enumerate(results): print(f"\n--- 图片 {i+1}/{len(results)}:{result.path} ---") boxes = result.boxes if len(boxes) == 0: print("未检测到目标") else: for j, box in enumerate(boxes): confidence = float(box.conf) cls_id = int(box.cls) cls_name = result.names[cls_id] if hasattr(result, 'names') else f"类别{cls_id}" print(f"目标 {j+1}/{len(boxes)}:{cls_name} (ID:{cls_id}),置信度:{confidence:.4f}")
12.推理时播放窗口可控
from ultralytics import YOLO import cv2 if __name__ == '__main__': # 加载模型 model = YOLO(r'E:\YOLO\model_20250626\best.pt', task='detect') # 视频预测 results = model.predict( source=r'E:\YOLO\video\WIN_20250625_11_26_18_Pro.mp4', show=False, # 关闭默认显示,使用自定义窗口 stream=True ) # 设置窗口大小 window_width = 1280 window_height = 720 # 创建自定义窗口并设置大小 cv2.namedWindow('YOLOv8 Detection', cv2.WINDOW_NORMAL) cv2.resizeWindow('YOLOv8 Detection', window_width, window_height) for result in results: # 获取当前帧 frame = result.orig_img # 显示检测结果 annotated_frame = result.plot() # 显示当前帧 cv2.imshow('YOLOv8 Detection', annotated_frame) # 按ESC或q退出 if cv2.waitKey(1) & 0xFF in [27, ord('q'), ord('Q')]: break # 释放资源 cv2.destroyAllWindows()
13.获取指定图片数量到指定文件夹,如果有相同图片,将其进行覆盖(不常用)
import os import shutil import argparse from typing import List def get_image_files(directory: str) -> List[str]: """获取目录中所有图片文件的路径""" image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'} return [ os.path.join(directory, filename) for filename in os.listdir(directory) if os.path.isfile(os.path.join(directory, filename)) and os.path.splitext(filename)[1].lower() in image_extensions ] def select_images_evenly(image_files: List[str], count: int) -> List[str]: """从图片列表中均匀选择指定数量的图片""" if not image_files: return [] if count >= len(image_files): return image_files step = (len(image_files) - 1) / (count - 1) return [image_files[int(round(i * step))] for i in range(count)] def copy_images(source_dir: str, dest_dir: str, count: int) -> None: """从源目录复制指定数量的图片到目标目录,自动覆盖已存在的文件""" # 确保源目录存在 if not os.path.exists(source_dir): raise FileNotFoundError(f"源目录不存在: {source_dir}") # 获取图片文件列表 image_files = get_image_files(source_dir) if not image_files: raise ValueError(f"源目录中没有找到图片文件: {source_dir}") # 选择均匀分布的图片 selected_images = select_images_evenly(image_files, count) # 确保目标目录存在 os.makedirs(dest_dir, exist_ok=True) # 复制图片(使用copy2保留元数据,存在时自动覆盖) for image_path in selected_images: filename = os.path.basename(image_path) dest_path = os.path.join(dest_dir, filename) # 检查目标文件是否存在 if os.path.exists(dest_path): print(f"警告: 目标文件已存在,将覆盖: {filename}") shutil.copy2(image_path, dest_path) print(f"已复制: {filename}") print(f"成功从 {source_dir} 复制 {len(selected_images)} 张图片到 {dest_dir}") def main(): # 直接设置参数值,而不是从命令行解析 source_dir = r"E:\YOLO\video\WIN_20250625_11_26_18_Pro" dest_dir = r"E:\YOLO\model_20250626\datasets\train\images" count = 80 try: copy_images(source_dir, dest_dir, count) except Exception as e: print(f"错误: {str(e)}") if __name__ == "__main__": main()
14.修改模型标签名称
如果发现训练出来的模型标签名称错误,但是又不能重新修正后再次进行训练,可以通过以下程序对训练后的模型文件的标签名称进行更改
from ultralytics import YOLO model = YOLO('/mnt/workspace/runs/detect/train/weights/best.pt') # 正确修改标签的方式 model.model.names = ['车型1', '轩逸'] # 注意是 model.model.names # 保存修改后的模型 model.save('best_new_labels.pt')
15.给图片增加前缀
主要的作用是如果想要将同样名字的文件放置到同一个文件夹下,此时会发生覆盖,为了避免此类问题的发生,可以将不同的文件增加特有的前缀,这样就避免同名文件的发生
import os def add_prefix_to_files(folder_path, prefix): """ 给指定文件夹中的所有文件添加前缀 :param folder_path: 目标文件夹路径 :param prefix: 要添加的前缀字符串 """ # 遍历文件夹中的所有条目 for filename in os.listdir(folder_path): # 获取文件的完整路径 original_path = os.path.join(folder_path, filename) # 确保是文件而不是目录 if os.path.isfile(original_path): # 构造新文件名 new_filename = prefix + filename new_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(original_path, new_path) print(f"Renamed: {filename} -> {new_filename}") # 使用示例 if __name__ == "__main__": target_folder = "D:\yolo11_shuzhi\照片模版202505\L21B-C4E9-普通标 上格栅全黑 下饰条金色" # 修改为你的文件夹路径 prefix_to_add = "L21B-C4E9" # 修改为你需要的前缀 add_prefix_to_files(target_folder, prefix_to_add)
16.均匀的选取一定数量图片移动到指定文件夹下
import os import shutil from pathlib import Path def extract_images(source_dir, target_dir, num_images=20): # 确保目标目录存在 Path(target_dir).mkdir(parents=True, exist_ok=True) # 获取所有图片文件 image_files = sorted([f for f in os.listdir(source_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]) total_images = len(image_files) if total_images == 0: print("源目录中没有找到图片文件") return # 计算间隔步长 step = max(1, total_images // num_images) # 均匀选取图片 selected_images = image_files[::step][:num_images] # 移动选中的图片 for img in selected_images: src_path = os.path.join(source_dir, img) dst_path = os.path.join(target_dir, img) shutil.move(src_path, dst_path) print(f"已移动: {img}") print(f"成功移动 {len(selected_images)} 张图片到目标目录") if __name__ == "__main__": source_dir = r"C:\Users\libok\Desktop\jinsai13\heiluntai" # 源数据文件夹 target_dir = r"C:\Users\libok\Desktop\jinsai13\datasets\val\images" #目标数据文件夹 extract_images(source_dir, target_dir, 20) # 需要移动的文件数量
17.视频切片
目的是将给定的视频切割成逐帧的图片。
import cv2 import os def extract_frames(video_path, output_dir, frame_interval=1, prefix="frame"): # 创建输出目录 if not os.path.exists(output_dir): os.makedirs(output_dir) # 打开视频文件 cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print("无法打开视频文件") return frame_count = 0 saved_count = 0 while True: ret, frame = cap.read() if not ret: break # 按间隔保存帧 if frame_count % frame_interval == 0: frame_name = f"{prefix}_{saved_count:05d}.jpg" output_path = os.path.join(output_dir, frame_name) cv2.imwrite(output_path, frame) saved_count += 1 frame_count += 1 cap.release() print(f"共提取 {saved_count} 帧图像,保存到 {output_dir}") # 使用示例 video_path = r"C:\Users\libok\Desktop\jinsai13\00009.MTS" # 需要切割的视频文件 output_dir = r"C:\Users\libok\Desktop\jinsai13\tupian" # 输出文件路径 frame_interval = 25 # 每30帧提取1帧 prefix = "luntai" # 图像前缀 extract_frames(video_path, output_dir, frame_interval, prefix)
持续更新……