YOLO v11的学习记录(六) 把标注好的大图切割成小图

有一个工程,从相机获取到训练图的尺寸是4096*3072像素,图上有很多密集的小目标,用anylabeling进行标注后,送进YOLO训练时出了问题,由于电脑显存不大,如果用原图尺寸训练,即使很小的batch_size,也会显存溢出,如果用YOLO默认的imgsz=640,则由于缩小倍数过大,小目标被过度压缩,造成学习效果不佳。解决问题的办法是将大图裁切成小图(640*640)后再训练,下面的脚本实现了这个目的,并且在裁切图片的同时将已经标注好的数据随图片裁切。

python 复制代码
import copy
import json

import cv2
import os
from pathlib import Path


# 将图像尺寸调整为640的倍数
def split_image_into_blocks(image_path, output_dir, block_width=640, block_height=640):
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    # 读取图片
    image = cv2.imread(image_path)
    if image is None:
        raise ValueError(f"无法读取图片: {image_path}")
    # 调整图片尺寸
    height, width = image.shape[:2]
    _, b = divmod(width, block_width)
    w_out = width + block_width - b  # 调整为640的倍数
    _, b = divmod(height, block_height)
    h_out = height + block_height - b   # 调整为640的倍数
    img = cv2.resize(image, (w_out, h_out), interpolation=cv2.INTER_CUBIC)
    # 放大比例
    w_scale = w_out / width
    h_scale = h_out / height


    # 获取同名json文件
    file_name = Path(image_path).stem
    with open(file_name + '.json', encoding="utf-8") as f:
        json_data = json.load(f)  # 同名图片文件的json数据

    # 获取图片尺寸
    height, width = img.shape[:2]
    print(f"调整后的大图片尺寸: 宽{width} x 高{height}")
    print(f"分割块尺寸: 宽{block_width} x 高{block_height}")

    # 计算可以分割的块数(按完整块计算)
    num_blocks_width = width // block_width
    num_blocks_height = height // block_height

    print(f"将分割为 {num_blocks_width}x{num_blocks_height} 个图片块")

    # 分割并保存块
    block_count = 0
    for i in range(num_blocks_height):
        for j in range(num_blocks_width):
            # 计算当前块的坐标(左上角开始)
            start_x = j * block_width
            start_y = i * block_height
            end_x = start_x + block_width
            end_y = start_y + block_height

            # 提取图片块
            block = img[start_y:end_y, start_x:end_x]

            # 保存图片块(文件名包含行列信息)
            block_filename = os.path.join(
                output_dir,
                f"{file_name}_row{i}_col{j}_index{block_count}.jpg"
            )
            json_filename = os.path.join(
                output_dir,
                f"{file_name}_row{i}_col{j}_index{block_count}.json"
            )

            cv2.imwrite(block_filename, block)
            # 更新json文件
            data= copy.deepcopy(json_data)
            for shape in data['shapes']:
                points  = []
                for point in shape['points']:
                    w = round(point[0] * w_scale, 0) - start_x  # 坐标按照小块的0点重新定位
                    h = round(point[1] * h_scale, 0) - start_y
                    if 0 <= w <= block_width and 0 <= h <= block_height:  # 如果坐标在小块内,则添加到points中
                        points.append([w, h])
                # 如果points的长度大于20,则保留,否则删除
                if len(points) > 20:
                    shape['points'] = points
                else:
                    shape['points'] = []

            data['shapes'] = [item for item in data['shapes'] if item['points'] != []]   # 删除points为空的形状
            data['imagePath'] = f"{file_name}_row{i}_col{j}_index{block_count}.jpg"   # 更新图片路径
            data['imageHeight'] = block_height   # 更新图片高度
            data['imageWidth'] = block_width    # 更新图片宽度
            # 更新json文件
            with open(json_filename, 'w', encoding="utf-8") as f:
                json.dump(data, f)
            block_count += 1

    print(f"分割完成,共生成 {block_count} 个块")



if __name__ == "__main__":
    # 替换为你的图片路径
    input_image_path = "img00002.jpg"

    split_image_into_blocks(
        image_path=input_image_path, output_dir='custom_blocks')

标注好的大图(4096*3072像素):

裁切得到的其中一张小图(640*640像素):

相关推荐
鬼手点金8 小时前
KV Cache 未必是一次性的:可编辑、可组合的“笔记”
java·人工智能·笔记·学习·自动化·1024程序员节
xsd202411188 小时前
智慧园区算法平台搭建详解:从模型仓到统一推理,多模型怎么管起来
人工智能·深度学习
kyrie_sakura9 小时前
大模型学习18 大模型学习 - LangChain2_Model I/O
学习·自然语言处理
宝绿特塑业再生科技10 小时前
板材收缩率不稳,户外家具装配尺寸为何对不上:从切割尺寸变化到接缝不一的系统性排查与对策
笔记·科技·学习·生活·户外家具·hdpe再生颗粒·hdpe
Smoothcloud润云10 小时前
远程纳管GPU怎么安全升级?驱动、组件灰度与回滚实战
人工智能·深度学习·安全·gpu算力·gpu·数据库管理员
~城南花已开~10 小时前
Intel E810 SR-IOV VF Spoofcheck 防伪造测试-KVM3
服务器·网络·笔记·学习·ubuntu·etl工程师
tellmewhoisi10 小时前
深度学习19:PyTorch:自动微分模块
人工智能·pytorch·深度学习
怎么全是重名11 小时前
CLIP-Learning Transferable Visual Models From Natural Language Supervision
人工智能·深度学习·计算机视觉·异常检测
米饭是菜qy11 小时前
动手学深度学习(李沐)——现代循环神经网络读书笔记
人工智能·rnn·深度学习
我命由我1234513 小时前
6-3.Python 异常处理 - 异常处理进阶(else 块与 finally 块、异常传递、自定义异常)
开发语言·前端·数据库·后端·python·学习·java-ee