首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

[保姆式教程]使用目标检测模型YOLO11 OBB进行旋转目标检测:训练自己的数据集(基于卫星和无人机的农业大棚数据集)

  • 25-02-18 09:21
  • 3521
  • 10227
blog.csdn.net

        之前写了一个基于YOLOv8做旋转目标检测(OBB)的文章,内容写得不够好,内容也有些杂乱无序。现如今YOLO已经更新到11了,数据集也集齐了无人机和卫星的农业大棚,所以这次就写一个基于YOLO11 OBB的农业大棚旋转检测。

1. 下载源码配置环境

        在https://github.com/ultralytics/ultralytics网页下载YOLO11源码,解压缩后创建虚拟环境即可,环境创建不是很难,这里就不细说了。

2. 数据集准备

2.1 数据标注

        这里我使用LabelImg2标注无人机和卫星影像,我是在一整张大幅影像上对影像中的农业大棚进行标注的,最后面使用算法将影像裁剪成合适的尺寸用于训练,后面会详细介绍整个流程。

 卫星影像中的农业大棚

无人机影像中的农业大棚

        在LabelImg2上标注好数据,LabelImg2标注是五点式,即旋转框的中心x,y坐标、旋转框的长度和宽度、旋转角度。如下图所示:

         从图中可以看到影像大小为 7176 X 5080 ,影像为RGB3通道,标注了两个旋转框,旋转框标签为默认的"dog"。

2.2 XML标注文件转DOTA格式标签文件(TXT)

       新建一个名为roxml_to_dota.py的python脚本,复制粘贴下面的代码:

  1. # 文件名称 :roxml_to_dota.py
  2. # 功能描述 :把rolabelimg标注的xml文件转换成dota能识别的xml文件,
  3. # 再转换成dota格式的txt文件
  4. # 把旋转框 cx,cy,w,h,angle,或者矩形框cx,cy,w,h,转换成四点坐标x1,y1,x2,y2,x3,y3,x4,y4
  5. import os
  6. import xml.etree.ElementTree as ET
  7. import math
  8. cls_list = ['dog'] # 修改为自己的标签
  9. def edit_xml(xml_file, dotaxml_file):
  10. """
  11. 修改xml文件
  12. :param xml_file:xml文件的路径
  13. :return:
  14. """
  15. # dxml_file = open(xml_file,encoding='gbk')
  16. # tree = ET.parse(dxml_file).getroot()
  17. tree = ET.parse(xml_file)
  18. objs = tree.findall('object')
  19. for ix, obj in enumerate(objs):
  20. x0 = ET.Element("x0") # 创建节点
  21. y0 = ET.Element("y0")
  22. x1 = ET.Element("x1")
  23. y1 = ET.Element("y1")
  24. x2 = ET.Element("x2")
  25. y2 = ET.Element("y2")
  26. x3 = ET.Element("x3")
  27. y3 = ET.Element("y3")
  28. # obj_type = obj.find('bndbox')
  29. # type = obj_type.text
  30. # print(xml_file)
  31. if (obj.find('robndbox') == None):
  32. obj_bnd = obj.find('bndbox')
  33. obj_xmin = obj_bnd.find('xmin')
  34. obj_ymin = obj_bnd.find('ymin')
  35. obj_xmax = obj_bnd.find('xmax')
  36. obj_ymax = obj_bnd.find('ymax')
  37. # 以防有负值坐标
  38. xmin = max(float(obj_xmin.text), 0)
  39. ymin = max(float(obj_ymin.text), 0)
  40. xmax = max(float(obj_xmax.text), 0)
  41. ymax = max(float(obj_ymax.text), 0)
  42. obj_bnd.remove(obj_xmin) # 删除节点
  43. obj_bnd.remove(obj_ymin)
  44. obj_bnd.remove(obj_xmax)
  45. obj_bnd.remove(obj_ymax)
  46. x0.text = str(xmin)
  47. y0.text = str(ymax)
  48. x1.text = str(xmax)
  49. y1.text = str(ymax)
  50. x2.text = str(xmax)
  51. y2.text = str(ymin)
  52. x3.text = str(xmin)
  53. y3.text = str(ymin)
  54. else:
  55. obj_bnd = obj.find('robndbox')
  56. obj_bnd.tag = 'bndbox' # 修改节点名
  57. obj_cx = obj_bnd.find('cx')
  58. obj_cy = obj_bnd.find('cy')
  59. obj_w = obj_bnd.find('w')
  60. obj_h = obj_bnd.find('h')
  61. obj_angle = obj_bnd.find('angle')
  62. cx = float(obj_cx.text)
  63. cy = float(obj_cy.text)
  64. w = float(obj_w.text)
  65. h = float(obj_h.text)
  66. angle = float(obj_angle.text)
  67. obj_bnd.remove(obj_cx) # 删除节点
  68. obj_bnd.remove(obj_cy)
  69. obj_bnd.remove(obj_w)
  70. obj_bnd.remove(obj_h)
  71. obj_bnd.remove(obj_angle)
  72. x0.text, y0.text = rotatePoint(cx, cy, cx - w / 2, cy - h / 2, -angle)
  73. x1.text, y1.text = rotatePoint(cx, cy, cx + w / 2, cy - h / 2, -angle)
  74. x2.text, y2.text = rotatePoint(cx, cy, cx + w / 2, cy + h / 2, -angle)
  75. x3.text, y3.text = rotatePoint(cx, cy, cx - w / 2, cy + h / 2, -angle)
  76. # obj.remove(obj_type) # 删除节点
  77. obj_bnd.append(x0) # 新增节点
  78. obj_bnd.append(y0)
  79. obj_bnd.append(x1)
  80. obj_bnd.append(y1)
  81. obj_bnd.append(x2)
  82. obj_bnd.append(y2)
  83. obj_bnd.append(x3)
  84. obj_bnd.append(y3)
  85. tree.write(dotaxml_file, method='xml', encoding='utf-8') # 更新xml文件
  86. # 转换成四点坐标
  87. def rotatePoint(xc, yc, xp, yp, theta):
  88. xoff = xp - xc;
  89. yoff = yp - yc;
  90. cosTheta = math.cos(theta)
  91. sinTheta = math.sin(theta)
  92. pResx = cosTheta * xoff + sinTheta * yoff
  93. pResy = - sinTheta * xoff + cosTheta * yoff
  94. return str(int(xc + pResx)), str(int(yc + pResy))
  95. def totxt(xml_path, out_path):
  96. # 想要生成的txt文件保存的路径,这里可以自己修改
  97. files = os.listdir(xml_path)
  98. i = 0
  99. for file in files:
  100. tree = ET.parse(xml_path + os.sep + file)
  101. root = tree.getroot()
  102. name = file.split('.')[0]
  103. output = out_path + '\\' + name + '.txt'
  104. file = open(output, 'w')
  105. i = i + 1
  106. objs = tree.findall('object')
  107. for obj in objs:
  108. cls = obj.find('name').text
  109. box = obj.find('bndbox')
  110. x0 = int(float(box.find('x0').text))
  111. y0 = int(float(box.find('y0').text))
  112. x1 = int(float(box.find('x1').text))
  113. y1 = int(float(box.find('y1').text))
  114. x2 = int(float(box.find('x2').text))
  115. y2 = int(float(box.find('y2').text))
  116. x3 = int(float(box.find('x3').text))
  117. y3 = int(float(box.find('y3').text))
  118. if x0 < 0:
  119. x0 = 0
  120. if x1 < 0:
  121. x1 = 0
  122. if x2 < 0:
  123. x2 = 0
  124. if x3 < 0:
  125. x3 = 0
  126. if y0 < 0:
  127. y0 = 0
  128. if y1 < 0:
  129. y1 = 0
  130. if y2 < 0:
  131. y2 = 0
  132. if y3 < 0:
  133. y3 = 0
  134. for cls_index, cls_name in enumerate(cls_list):
  135. if cls == cls_name:
  136. file.write("{} {} {} {} {} {} {} {} {} {}\n".format(x0, y0, x1, y1, x2, y2, x3, y3, cls, cls_index))
  137. file.close()
  138. # print(output)
  139. print(i)
  140. if __name__ == '__main__':
  141. # -----**** 第一步:把xml文件统一转换成旋转框的xml文件 ****-----
  142. roxml_path = r'D:\yolo11\data\origin_xml' # labelimg2标注生成的原始xml文件路径
  143. dotaxml_path = r'D:\yolo11\data\dota_xml' # 转换后dota能识别的xml文件路径,路径需存在,不然报错
  144. out_path = r'D:\yolo11\data\dota_txt' # 转换后dota格式的txt文件路径,路径需存在,不然报错
  145. filelist = os.listdir(roxml_path)
  146. for file in filelist:
  147. edit_xml(os.path.join(roxml_path, file), os.path.join(dotaxml_path, file))
  148. # -----**** 第二步:把旋转框xml文件转换成txt格式 ****-----
  149. totxt(dotaxml_path, out_path)

        注意事项:小心修改文件路径,别搞错了,即

  1. if __name__ == '__main__':
  2. # -----**** 第一步:把xml文件统一转换成旋转框的xml文件 ****-----
  3. roxml_path = r'D:\data\yolov8_obb\origin_xml' # labelimg2标注生成的原始xml文件路径
  4. dotaxml_path = r'D:\data\yolov8_obb\dota_xml' # 转换后dota能识别的xml文件路径,路径需存在,不然报错
  5. out_path = r'D:\data\yolov8_obb\dota_txt' # 转换后dota格式的txt文件路径,路径需存在,不然报错
  6. filelist = os.listdir(roxml_path)
  7. for file in filelist:
  8. edit_xml(os.path.join(roxml_path, file), os.path.join(dotaxml_path, file))
  9. # -----**** 第二步:把旋转框xml文件转换成txt格式 ****-----
  10. totxt(dotaxml_path, out_path)

         下面是转换后的TXT格式的标签文件(此时的标签还不是YOLO OBB数据集的格式,还需要再转换)

2.3 标签更改

        我在标注的过程中使用的是LabelImg2软件中默认的标签名,即"dog"。在这里我使用代码将其中的标签修改为自己的标签,即"dp"。

        新建一个名为change_label.py的python文件,复制粘贴下面的代码:

  1. import os
  2. def replace_text_in_files(folder_path, old_text, new_text):
  3. # 遍历指定文件夹
  4. for filename in os.listdir(folder_path):
  5. # 检查文件是否是.txt文件
  6. if filename.endswith(".txt"):
  7. file_path = os.path.join(folder_path, filename)
  8. # 读取文件内容
  9. with open(file_path, 'r', encoding='utf-8') as file:
  10. file_data = file.read()
  11. # 替换文本
  12. updated_data = file_data.replace(old_text, new_text)
  13. # 写入更改后的内容
  14. with open(file_path, 'w', encoding='utf-8') as file:
  15. file.write(updated_data)
  16. # 调用函数,将'dog'替换为'dp'
  17. replace_text_in_files(r'D:\yolo11\greenhouse\roxml_to_dota\xml_to_txt', 'dog', 'dp')

        下面是更改标签后的txtTXT文件内容:

2.4 DOTA格式标签文件转换为YOLO OBB训练所需的格式

(1)TIF格式影像(下载的卫星影像是tif格式)转换为PNG格式

        创建一个名为tif_to_png.py的python文件,复制粘贴下面的代码:

  1. import os
  2. import tifffile
  3. from PIL import Image
  4. import numpy as np
  5. def tif2png_high_quality(tif_folder, png_folder):
  6. """
  7. 将tif文件夹中的所有tif图像转换为png图像,并尽可能保持图像质量。
  8. Args:
  9. tif_folder: 包含tif图像的文件夹路径。
  10. png_folder: 保存png图像的文件夹路径。
  11. """
  12. if not os.path.exists(png_folder):
  13. os.makedirs(png_folder)
  14. for filename in os.listdir(tif_folder):
  15. if filename.endswith(".tif") or filename.endswith(".tiff"):
  16. tif_filepath = os.path.join(tif_folder, filename)
  17. png_filepath = os.path.join(png_folder, filename.replace(".tif", ".png").replace(".tiff", ".png"))
  18. try:
  19. # 使用tifffile库读取tif图像,可以更好地处理各种tif格式和元数据
  20. tif_image = tifffile.imread(tif_filepath)
  21. # 如果tif图像是多通道的,需要进行一些处理,例如转换为RGB图像或者分别保存每个通道
  22. if tif_image.ndim == 3 and tif_image.shape[2] > 3: #处理多波段图像,例如大于3个波段的遥感图像
  23. # 可以选择需要的波段合成RGB图像,或者保存所有波段为单独的png文件
  24. # 这里以合成RGB图像为例,假设前三个波段是RGB波段
  25. tif_image = tif_image[:,:,:3] # 取前三个波段
  26. tif_image = np.clip(tif_image, 0, 255).astype(np.uint8) # 裁剪像素值到0-255,并转换为uint8类型
  27. img = Image.fromarray(tif_image)
  28. elif tif_image.dtype == np.uint16: #16位图像处理,转换为8位
  29. img = Image.fromarray((tif_image / 256).astype(np.uint8))
  30. else: # 其他情况直接转换
  31. img = Image.fromarray(tif_image)
  32. # 使用 Pillow 库保存 png 图像, 可以指定更高的压缩质量
  33. img.save(png_filepath, "PNG", compress_level=1) # compress_level 1 表示最小压缩,质量最高
  34. print(f"已将 {tif_filepath} 转换为 {png_filepath}")
  35. except Exception as e:
  36. print(f"转换 {tif_filepath} 时出错: {e}")
  37. # 示例用法:
  38. tif_folder = "tif_images" # 替换为你的tif图像文件夹路径
  39. png_folder = "png_images" # 替换为你想保存png图像的文件夹路径
  40. tif2png_high_quality(tif_folder, png_folder)

        设置好图像文件夹路径,将TIF图像转换为PNG格式的图像 

 (2)在项目代码目录下面创建下面的文件夹结构,然后将划分好的图像和标签文件放到相应的文件夹中 (这里我直接使用v8教程里面的图)

(3)编写转换标注格式的代码

        创建一个名为convert_dota_to_yolo_obb.py的python文件,复制粘贴下面的代码:

  1. import sys
  2. # yolo11源码文件夹
  3. sys.path.append('D:\yolo11')
  4. from ultralytics.data.converter import convert_dota_to_yolo_obb
  5. # 上一步骤中设置的文件夹结构根目录
  6. convert_dota_to_yolo_obb('D:\yolo11\greenhouse\data')

        由于官方源码转换代码用的是VOC数据集,所以这里我们需要修改ultralytics/data/

converter.py中的类别名,改成自己的数据集类别名。修改ultralytics/data/converter.py中的代码:先注释掉原有的class_mapping代码,然后按照原有格式写入自己的类别,我的即为:

  1. class_mapping = {
  2. "dp": 0,
  3. }

        转换后的YOLO OBB数据集格式的标签会保存在labels\train和labels\val中(训练需要使用的就是这两个文件夹,train_original和val_original用不到)

        转换后的OBB数据集格式的标签文件中的内容

2.5 png格式影像裁剪

       在项目代码目录下面创建下面的文件夹结构,然后将OBB格式的标签文件和对应的图像放到相应的文件夹中 (labels里面的train_original和val_original文件夹不需要,不用创建这两个文件夹,截图里面多余了)

        创建一个名为split_images.py的python文件,复制粘贴下面的代码:

  1. from ultralytics.data.split_dota import split_test, split_trainval
  2. # 分割训练集和验证集,同时包含标签。标签需要是YOLO格式的,
  3. # 即:0 0.332813 0.164062 0.403125 0.15 0.45 0.373437 0.379688 0.389062
  4. #
  5. # @param data_root str,数据根目录的路径。
  6. # @param save_dir str,保存分割后数据集的目录路径。
  7. # @param rates list,用于设定不同尺度分割比例的列表,例如[0.5, 1.0, 1.5]表示三个尺度。
  8. # @param gap int,设定在数据集中间隔多少个像素进行一次分割。
  9. split_trainval(
  10. data_root=r"D:\yolo11\datasets",
  11. save_dir=r"D:\yolo11\DOTAv1.0-split",
  12. rates=[0.5, 1.0, 1.5], # multiscale
  13. gap=100,
  14. )
  15. # 分割测试集,不包含标签。
  16. #
  17. # @param data_root str,数据根目录的路径。
  18. # @param save_dir str,保存分割后数据集的目录路径。
  19. # @param rates list,用于设定不同尺度分割比例的列表,例如[0.5, 1.0, 1.5]表示三个尺度。
  20. # @param gap int,设定在数据集中间隔多少个像素进行一次分割。
  21. split_test(
  22. data_root=r"D:\yolo11\datasets",
  23. save_dir=r"D:\yolo11\DOTAv1.0-split",
  24. rates=[0.5,1.0, 1.5], # multiscale
  25. gap=100,

        裁剪的图像尺寸可以在split_dota里面修改,可以修改成自己需要的,比如说1280,1024,

960,768,640等等。如果设置裁剪大小为640 x 640,那么rates中的0.5代表图像大小为320 X 320,1.5代表图像大小为960 X 960。建议设置合适的多尺度图像大小用于训练和验证,这样泛化性能可能会好一些。rates可以设置为[0.3, 1.0, 1.3]。

        运行代码之后裁剪的图像和对应的标注文件会在DOTAv1.0-split文件夹中。要查看裁剪得到了多少张图像,可以直接看DOTAv1.0-split\labels里面对应的文件夹,看DOTAv1.0-split\images是难以知道的,因为images里面包含了有标签的图像和没有标签的图像。

        这里我其实有点疑惑,我原本是想把所有图像裁剪了再划分数据集,但是这里按照ultralytics里面的代码意思,似乎是先将所有的大幅影像先划分为训练影像、验证影像和测试影像,裁剪之后即是对应的数据集,但是先将所有的大幅影像先划分为训练影像、验证影像和测试影像的做法似乎不太科学,因为这样的话每个数据集中的图像差异可能比较大,这样训练得到的结果可能泛化性并不好。我觉得可能不如统一裁剪之后随机划分数据集的做法,个人目前比较粗浅的看法。。。

2.6 挑选有标签的图像

        上一步骤中裁剪得到的图像数量和标签数量是不匹配的,因为有些没有标签的图像没有舍弃掉。所有这里需要写个算法将有标签的图像挑选出来,与标签一一对应。

        创建一个名为pick_images.py的python文件,复制粘贴下面的代码:

  1. import os
  2. import shutil
  3. # 裁剪得到的标签的文件夹
  4. labels_dir = r'D:\yolo11\DOTAv1.0-split\labels\train'
  5. # 裁剪得到图像的文件夹
  6. images_dir = r'D:\yolo11\DOTAv1.0-split\images\train'
  7. # 存放挑选出来的图像的文件夹
  8. pick_dir = r'D:\yolo11\DOTAv1.0-split\images\pick'
  9. # 确保 pick_dir 存在
  10. os.makedirs(pick_dir, exist_ok=True)
  11. # 获取 labels_dir 下的所有 .txt 文件
  12. label_files = [f for f in os.listdir(labels_dir) if f.endswith('.txt')]
  13. for label_file in label_files:
  14. # 提取文件名(不包括扩展名)
  15. base_name = os.path.splitext(label_file)[0]
  16. # 构建对应的图像文件路径
  17. image_jpg_path = os.path.join(images_dir, base_name + '.jpg')
  18. image_png_path = os.path.join(images_dir, base_name + '.png')
  19. # 检查是否存在对应的图像文件
  20. if os.path.exists(image_jpg_path):
  21. # 复制图像文件到 pick_dir
  22. shutil.copy(image_jpg_path, pick_dir)
  23. print(f"已复制 {image_jpg_path} 到 {pick_dir}")
  24. elif os.path.exists(image_png_path):
  25. # 复制图像文件到 pick_dir
  26. shutil.copy(image_png_path, pick_dir)
  27. print(f"已复制 {image_png_path} 到 {pick_dir}")
  28. else:
  29. print(f"未找到与 {label_file} 对应的图像文件")

2.7 数据集划分

        先构建好文件夹结构,文件夹结构如下(用的YOLOv8中的图,所有图像放在img文件夹下,所有txt放在dotatxt文件夹下),至于文件夹为什么是这样的结构我现在还不懂。。。

        使用下面的代码划分数据集

  1. import os
  2. import random
  3. import shutil
  4. random.seed(42)
  5. """
  6. 该脚本用于将给定的数据集分割成训练集和测试集。
  7. 数据集应包含图像和对应的标注文件。
  8. 脚本会按照90%训练集和10%测试集的比例进行分割,并将图像和标注文件分别复制到相应的文件夹中。
  9. """
  10. # 设置数据集文件夹路径和输出文件夹路径
  11. data_folder = 'data_mouse_ro'
  12. img_folder = 'data_mouse_ro/dataset/images'
  13. label_folder = 'data_mouse_ro/dataset/labels'
  14. # 计算每个子集的大小
  15. # 总文件数乘以0.9得到训练集大小,其余为测试集大小
  16. total_files = len(os.listdir(os.path.join(data_folder, 'img')))
  17. train_size = int(total_files * 0.9)
  18. test_size = int(total_files - train_size)
  19. # 获取所有图像文件的文件名列表,并进行随机打乱
  20. image_files = os.listdir(os.path.join(data_folder, 'img'))
  21. random.shuffle(image_files)
  22. # 复制图像和标注文件到相应的子集文件夹中
  23. # 枚举每个图像文件,根据索引决定复制到训练集还是测试集文件夹
  24. for i, image_file in enumerate(image_files):
  25. base_file_name = os.path.splitext(image_file)[0] # 获取文件名(不包括扩展名)
  26. image_path = os.path.join(data_folder, 'img', image_file)
  27. label_path = os.path.join(data_folder, 'dotatxt', base_file_name + '.txt')
  28. # 根据索引判断文件应复制到训练集还是测试集
  29. if i < train_size:
  30. shutil.copy(image_path, os.path.join(img_folder, 'train')) # 复制图像到训练集
  31. shutil.copy(label_path, os.path.join(label_folder, 'train_original')) # 复制标注到训练集
  32. else:
  33. shutil.copy(image_path, os.path.join(img_folder, 'val')) # 复制图像到测试集
  34. shutil.copy(label_path, os.path.join(label_folder, 'val_original')) # 复制标注到测试集

3. 模型配置

(1)新建模型配置文件my-data-obb.yaml

        在yolo11\ultralytics\cfg\datasets路径下,新建my-data-obb.yaml文件(复制粘贴其中某一个yaml文件改个名字),写入如下代码,其中参数根据自己的情况设置

  1. # Ultralytics YOLO ?, AGPL-3.0 license
  2. # COCO 2017 dataset https://cocodataset.org by Microsoft
  3. # Documentation: https://docs.ultralytics.com/datasets/detect/coco/
  4. # Example usage: yolo train data=coco.yaml
  5. # parent
  6. # ├── ultralytics
  7. # └── datasets
  8. # └── coco ← downloads here (20.1 GB)
  9. # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
  10. path: datasets # dataset root dir
  11. train: images/train # train images (relative to 'path') 118287 images
  12. val: images/val # val images (relative to 'path') 5000 images
  13. test: images/val # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
  14. # Classes----我的数据集类别只有一个,即dp----
  15. names:
  16. 0: dp

(2)修改模型配置文件yolo11-obb.yaml

        在yolo11\ultralytics\cfg\models\11路径下,修改yolo11-obb.yaml文件,将nc参数修改为自己的数据集类别数。我听别的博主说这里不改没有关系,会根据前面设置的my-data-obb.yaml文件修改。

4. 训练

(1)根据自己的实际情况修改yolo11\ultralytics\cfg\default.yaml文件中的训练参数

        训练参数设置

        下面是其他的参数设置

        验证、测试参数设置

        推理参数设置

       可视化参数设置

        导出参数设置

        超参数设置

(2)运行下面的代码即可开始训练(路径和参数根据自己的情况设置)

        不使用权重进行训练

  1. from ultralytics import YOLO
  2. # Load a model
  3. model = YOLO("/home/jun/object_detect/yolo11/ultralytics/cfg/models/11/yolo11-obb.yaml")
  4. # Train the model
  5. train_results = model.train(
  6. data="/home/jun/object_detect/yolo11/ultralytics/cfg/datasets/my-data-obb.yaml", # path to dataset YAML
  7. epochs=1400, # number of training epochs
  8. batch=4,
  9. workers=0,
  10. amp=False,
  11. imgsz=640, # training image size
  12. device="0", # device to run on, i.e. device=0 or device=0,1,2,3 or device=cpu
  13. pretrained=False,
  14. verbose=True,
  15. optimizer="AdamW",
  16. )
  17. # Evaluate model performance on the validation set
  18. metrics = model.val()

        使用权重进行训练(这里就不需要模型配置文件yolo11-obb.yaml了,除非你修改了模型结构)

  1. from ultralytics import YOLO
  2. # Load a model-----这里直接加载权重文件
  3. model = YOLO("yolo11n-obb.pt")
  4. # Train the model
  5. train_results = model.train(
  6. data="/home/jun/object_detect/yolo11/ultralytics/cfg/datasets/my-data-obb.yaml", # path to dataset YAML
  7. epochs=1400, # number of training epochs
  8. batch=4,
  9. workers=0,
  10. amp=False,
  11. imgsz=640, # training image size
  12. device="0", # device to run on, i.e. device=0 or device=0,1,2,3 or device=cpu
  13. pretrained=False,
  14. verbose=True,
  15. optimizer="AdamW",
  16. )
  17. # Evaluate model performance on the validation set
  18. metrics = model.val()

5. 验证

        在yolo11目录下创建一个名为val.py的脚本,复制粘贴下面的代码,其中的参数根据自己的情况设置

  1. from ultralytics import YOLO
  2. # Load a model----加载自己训练好的权重
  3. model = YOLO("yolo11n-obb.pt")
  4. # Customize validation settings
  5. validation_results = model.val(data="my-data-obb.yaml", imgsz=640, batch=16, conf=0.25, iou=0.6, device="0")
  6. metrics.box.map # map50-95
  7. metrics.box.map50 # map50
  8. metrics.box.map75 # map75
  9. metrics.box.maps # a list contains map50-95 of each category

6. 推理

        在yolo11目录下创建一个名为predict.py的脚本,复制粘贴下面的代码,其中的参数根据自己的情况设置

  1. from ultralytics import YOLO
  2. # Load a model
  3. model = YOLO("yolo11n-obb.pt") # pretrained YOLO11n model
  4. # Run batched inference on a list of images
  5. results = model(["image1.jpg", "image2.jpg"]) # return a list of Results objects
  6. # results = model("path/to/your/images") # 这里可以直接放文件夹路径,会推理完里面的全部图像
  7. # Process results list
  8. for result in results:
  9. boxes = result.boxes # Boxes object for bounding box outputs
  10. masks = result.masks # Masks object for segmentation masks outputs
  11. keypoints = result.keypoints # Keypoints object for pose outputs
  12. probs = result.probs # Probs object for classification outputs
  13. obb = result.obb # Oriented boxes object for OBB outputs
  14. result.show() # display to screen
  15. # result.save(filename="result.jpg") # save to disk

        模型配置、训练、验证、推理的更多细节可以阅读ultralytics的官方文档,里面会有详细的说明。

        农业大棚无人机图像234张,卫星图像999张,两者数量不均衡,总体数量也不用够多,下次会解决这些问题。

        这只是一个篇分享经验的文章,难免有错误或者遗漏的地方,欢迎交流指正。

PS:

这里插播一下RT-DETR模型的训练代码:

  1. from ultralytics import RTDETR
  2. # Load a COCO-pretrained RT-DETR-l model
  3. model = RTDETR("/home/jun/yolo11/ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml")
  4. # Display model information (optional)
  5. model.info()
  6. # Train the model
  7. train_results = model.train(
  8. data="/home/jun/yolo11/ultralytics/cfg/datasets/my-data.yaml", # path to dataset YAML
  9. epochs=1400, # number of training epochs
  10. batch=4,
  11. amp=False,
  12. workers=0,
  13. imgsz=640, # training image size
  14. device="0", # device to run on, i.e. device=0 or device=0,1,2,3 or device=cpu
  15. pretrained=False,
  16. verbose=True,
  17. optimizer="AdamW",
  18. )
  19. # Evaluate model performance on the validation set
  20. metrics = model.val()

注:本文转载自blog.csdn.net的君不见~的文章"https://blog.csdn.net/qq_23865133/article/details/143128776"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

117
前沿技术
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top