江苏昆山网站建设,wordpress标题间隔符修改,今天安阳最新消息,kencms内容管理系统目录
前言
具体方法
使用介绍
完整代码 前言
在目标检测任务中#xff0c;模型的训练依赖于大量高质量的标注数据。然而#xff0c;获取足够多的标注数据集往往代价高昂#xff0c;并且某些情况下#xff0c;数据集中的样本分布不均衡#xff0c;这会导致模型的泛化能…目录
前言
具体方法
使用介绍
完整代码 前言
在目标检测任务中模型的训练依赖于大量高质量的标注数据。然而获取足够多的标注数据集往往代价高昂并且某些情况下数据集中的样本分布不均衡这会导致模型的泛化能力不足。为此数据增强成为提升模型性能的常用方法之一。
在数据增强的各种方法中裁剪是一种高效且常用的技术。通过对图片进行随机或特定区域的裁剪能够生成更多的训练样本提高模型对不同尺度和位置目标的鲁棒性。此外裁剪还可以有效解决原始图片尺寸过大的问题避免对训练性能造成影响。大尺寸图片会增加模型的计算开销导致训练速度变慢、内存消耗增大。而通过裁剪图片尺寸得以缩小训练效率随之提升。
然而裁剪不仅仅是简单地对图片进行操作目标检测任务中每个目标的边界框标签必须与图片裁剪过程同步更新否则裁剪后的标签将失去准确性影响模型的训练效果。本篇文章将重点介绍如何在进行目标检测数据集图片裁剪时同时对目标的标签进行精确调整确保裁剪后的图片和标签保持一致从而构建高质量的增强数据集助力模型的准确性与泛化能力提升。
具体方法
本文所使用的裁剪方式为图片的宽度和高度各自从中间切开将一个图片分为左上右上左下右下四个部分其中保留含有标签的那部分图片其余未含有标签的部分则不保留。
def crop_image(image, save_dir, name, suf, boxes):H, W, _ image.shape# 左上区域if boxes[0] 1:img_top_left image[0:H // 2, 0:W // 2]save_path os.path.join(save_dir, f{name}_1{suf})cv.imwrite(save_path, img_top_left)# 右上区域if boxes[1] 1:img_top_right image[0:H // 2, W // 2:W]save_path os.path.join(save_dir, f{name}_2{suf})cv.imwrite(save_path, img_top_right)# 左下区域if boxes[2] 1:img_bottom_left image[H // 2:H, 0:W // 2]save_path os.path.join(save_dir, f{name}_3{suf})cv.imwrite(save_path, img_bottom_left)# 右下区域if boxes[3] 1:img_bottom_right image[H // 2:H, W // 2:W]save_path os.path.join(save_dir, f{name}_4{suf})cv.imwrite(save_path, img_bottom_right)
这部分为裁剪图片的函数定义可以看到只保留含有标签的部分图像
def split_box(box, shape):W, H shape[1], shape[0]n, xmin, ymin, xmax, ymax boxregions []# 左上区域if xmin W / 2 and ymin H / 2:xmin_new max(0, xmin)ymin_new max(0, ymin)xmax_new min(W / 2, xmax)ymax_new min(H / 2, ymax)regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, left_top))# 右上区域if xmax W / 2 and ymin H / 2:xmin_new max(W / 2, xmin) - W / 2ymin_new max(0, ymin)xmax_new min(W, xmax) - W / 2ymax_new min(H / 2, ymax)regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, right_top))# 左下区域if xmin W / 2 and ymax H / 2:xmin_new max(0, xmin)ymin_new max(H / 2, ymin) - H / 2xmax_new min(W / 2, xmax)ymax_new min(H, ymax) - H / 2regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, left_bottom))# 右下区域if xmax W / 2 and ymax H / 2:xmin_new max(W / 2, xmin) - W / 2ymin_new max(H / 2, ymin) - H / 2xmax_new min(W, xmax) - W / 2ymax_new min(H, ymax) - H / 2regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, right_bottom))normalized_regions []for region in regions:box region[1:5] # 获取 (xmin, ymin, xmax, ymax)normalized_box xyxy2xywhn((W/2, H/2), box) # 归一化normalized_regions.append((region[0], *normalized_box, region[5])) # 保留标签return normalized_regions
这部分函数为标签裁剪这里我将每个标签都完整的分割出来避免因为标签在图片中间交界处而导致的标签发生丢失现象同时每部分标签加入一定的标志全部运行完之后返回这部分标志经过处理后传入图片裁剪中就可以知道哪部分图片需要保留避免了图片重复写入。
使用介绍
完整代码如下修改其中路径部分即可使用需要注意本文仅支持标签文件为yolo格式的txt文件如果对于转换格式不熟悉的可以去看我下面这篇文章里面有相关的介绍及方法
VOC格式转YOLO格式xml文件转txt文件简单通用代码_voc转yolo-CSDN博客文章浏览阅读509次点赞8次收藏4次。很多人在进行目标检测训练时习惯将得到的数据标注为XML文件的VOC格式或者在网上获取的数据集被标注为XML文件但是不同的标注工具进行的标注会产生不同的标注xml文件这里我写了一种通用的针对含有最基本图片和标注坐标信息的xml进行转换在这里简单介绍并分享出来xml文件中最基本需要含有的信息为sizeobject下的name和bndbox具体示例如下图如果xml文件中没有size也就是图片的宽和高则需要单独对每个图片进行读取感兴趣可以私聊这里不展开介绍_voc转yolohttps://blog.csdn.net/qq_67105081/article/details/140000193?spm1001.2014.3001.5501转换过之后想要再次转换回voc格式的xml文件可以去查看我的下面这篇博客
yolov8等目标检测数据集YOLO格式转VOC格式txt文件转xml文件格式转换_yolo格式标签转voc格式-CSDN博客文章浏览阅读255次点赞3次收藏8次。YOLO格式的标注文件是归一化之后的数据每一行有5个数值从左到右分别是类别中心坐标x中心坐标y宽度w高度h这些数据经过计算后即可得到xminyminxmaxymax的值将这些信息相应的填入xml文件中即可。还有一个关键部分是xml文件的构建如下代码构建变量确认后替换。_yolo格式标签转voc格式https://blog.csdn.net/qq_67105081/article/details/142915326?spm1001.2014.3001.5501
完整代码
# 作者CSDN-笑脸惹桃花 https://blog.csdn.net/qq_67105081?typeblog
# github:peng-xiaobai https://github.com/peng-xiaobai/Data-Augmentor
import os
import numpy as np
import cv2 as cvdef GetFileList(dir):l []files os.listdir(dir)for file in files:if file.endswith((.png, .jpg, .jpeg, .bmp, .tif)):l.append(os.path.join(dir, file))return ldef xywhn2xyxy(x, w, h):y np.copy(x) if isinstance(x, np.ndarray) else x.copy() if hasattr(x, copy) else xy[0] w * (x[0] - 0.5 * x[2])y[1] h * (x[1] - 0.5 * x[3])y[2] w * (x[0] 0.5 * x[2])y[3] h * (x[1] 0.5 * x[3])return ydef xyxy2xywhn(size, box):x_center (box[0] box[2]) / 2.0y_center (box[1] box[3]) / 2.0w box[2] - box[0]h box[3] - box[1]x x_center / size[0]y y_center / size[1]w w / size[0]h h / size[1]return x, y, w, hdef crop_image(image, save_dir, name, suf, boxes):H, W, _ image.shape# 左上区域if boxes[0] 1:img_top_left image[0:H // 2, 0:W // 2]save_path os.path.join(save_dir, f{name}_1{suf})cv.imwrite(save_path, img_top_left)# 右上区域if boxes[1] 1:img_top_right image[0:H // 2, W // 2:W]save_path os.path.join(save_dir, f{name}_2{suf})cv.imwrite(save_path, img_top_right)# 左下区域if boxes[2] 1:img_bottom_left image[H // 2:H, 0:W // 2]save_path os.path.join(save_dir, f{name}_3{suf})cv.imwrite(save_path, img_bottom_left)# 右下区域if boxes[3] 1:img_bottom_right image[H // 2:H, W // 2:W]save_path os.path.join(save_dir, f{name}_4{suf})cv.imwrite(save_path, img_bottom_right)def split_box(box, shape):W, H shape[1], shape[0]n, xmin, ymin, xmax, ymax boxregions []# 左上区域if xmin W / 2 and ymin H / 2:xmin_new max(0, xmin)ymin_new max(0, ymin)xmax_new min(W / 2, xmax)ymax_new min(H / 2, ymax)regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, left_top))# 右上区域if xmax W / 2 and ymin H / 2:xmin_new max(W / 2, xmin) - W / 2ymin_new max(0, ymin)xmax_new min(W, xmax) - W / 2ymax_new min(H / 2, ymax)regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, right_top))# 左下区域if xmin W / 2 and ymax H / 2:xmin_new max(0, xmin)ymin_new max(H / 2, ymin) - H / 2xmax_new min(W / 2, xmax)ymax_new min(H, ymax) - H / 2regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, left_bottom))# 右下区域if xmax W / 2 and ymax H / 2:xmin_new max(W / 2, xmin) - W / 2ymin_new max(H / 2, ymin) - H / 2xmax_new min(W, xmax) - W / 2ymax_new min(H, ymax) - H / 2regions.append((n, xmin_new, ymin_new, xmax_new, ymax_new, right_bottom))normalized_regions []for region in regions:box region[1:5] # 获取 (xmin, ymin, xmax, ymax)normalized_box xyxy2xywhn((W/2, H/2), box) # 归一化normalized_regions.append((region[0], *normalized_box, region[5])) # 保留标签return normalized_regionsdef save_boxes(label_path, boxes):# 先获取标注文件的基本路径和扩展名base_label_path, ext os.path.splitext(label_path)for box in boxes:# 获取区域标识左上、右上、左下、右下region box[5]if region left_top:suffix _1elif region right_top:suffix _2elif region left_bottom:suffix _3elif region right_bottom:suffix _4else:continue # 如果区域标识不在预期范围内跳过specific_label_path f{base_label_path}{suffix}{ext}with open(specific_label_path, a) as f:f.write(f{int(box[0])} .join(map(str, box[1:5])) \n)fileDir rE:\peanut_data\j # 原图片路径
label_path rE:\peanut_data\txt # 原label的路径
list1 GetFileList(fileDir)image_save_path_head rE:\peanut_data\j1 # 分割后有标注图片储存路径
label_save_path_head rE:\peanut_data\txt1 # 标签储存路径if not os.path.exists(image_save_path_head):os.makedirs(image_save_path_head)
if not os.path.exists(label_save_path_head):os.makedirs(label_save_path_head)for i in list1:l [0, 0, 0, 0]img cv.imread(i)shape img.shapeseq 1name, suf os.path.splitext(os.path.basename(i))labelname os.path.join(label_path, name) .txt # 找到对应图片的labelpos []with open(labelname, r) as f1:#print(labelname)while True:lines f1.readline()if lines \n:lines Noneif not lines:breakp_tmp [float(i) for i in lines.split()]pos.append(p_tmp)pos np.array(pos)for k in pos:k[1:] xywhn2xyxy(k[1:], shape[1], shape[0])regions split_box(k, shape)labelname_new os.path.join(label_save_path_head, name) .txtsave_boxes(labelname_new, regions)for region in regions:region_name region[-1]if region_name left_top:l[0] 1print(The region is left_top.)elif region_name right_top:l[1] 1print(The region is right_top.)elif region_name left_bottom:l[2] 1print(The region is left_bottom.)elif region_name right_bottom:l[3] 1print(The region is right_bottom.)f1.close()crop_image(img, image_save_path_head, name, suf, l)