Python随机切割图像

前言

今天做荔枝果园冠层目标检测数据集,感觉无人机拍摄拼接后的图片面积太大。试着用Python做一下图像的随机切割,得到更多的数据。先实现一下简单的中心点切割。

思路

1.利用PIL库的image.size获取图像的宽高。

2.得到图像中心点像素坐标mid_point_x ,mid_point_y。

3.构建感兴趣区域BOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN。

4.利用PIL库的image.crop切割。保存图像。

源码

from PIL import Image
import os
import random


# 定义待批量裁剪图像的路径地址
IMAGE_INPUT_PATH = 'C:\\Users\\27651\Desktop\crops_canopy\Lab_me\img_jpg'
# 定义裁剪后的图像存放地址
IMAGE_OUTPUT_PATH = 'C:\\Users\\27651\Desktop\crops_canopy\Lab_me\img_crop'

for each_image in os.listdir(IMAGE_INPUT_PATH):
# 每个图像全路径
    image_input_fullname = IMAGE_INPUT_PATH + "/" + each_image
# PIL库打开每一张图像
    img = Image.open(image_input_fullname)
# 定义裁剪图片左、上、右、下的像素坐标
    x_max = img.size[0]
    y_max = img.size[1]
    
    mid_point_x = int(x_max/2)
    mid_point_y = int(y_max/2)

    down = mid_point_y+random.randint(0,mid_point_y)
    up = mid_point_y-(down-mid_point_y)
    right = mid_point_x+(down-mid_point_y)
    left = mid_point_x-(down-mid_point_y)

    BOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN = left,up,right,down
# 从原始图像返回一个矩形区域,区域是一个4元组定义左上右下像素坐标
    box = (BOX_LEFT, BOX_UP, BOX_RIGHT , BOX_DOWN )
# 进行roi裁剪
    roi_area = img.crop(box)
# 裁剪后每个图像的路径+名称
    image_output_fullname = IMAGE_OUTPUT_PATH + "/" + each_image
# 存储裁剪得到的图像
    roi_area.save(image_output_fullname)
    print('{0} crop done.'.format(each_image))

效果

原图

 切割后

总结

实现了简单的基于图像中心点的正方形切割,接着进一步优化可以将“中心点”随机移动增强感兴趣区边界的约束条件(如判断上下左右边界到“中心点”的区间范围)。

2021/11/18 更新

完善了中心点随机移动,并进行多轮次的随机切割输出。修改代码如下

for i in range(0,5):
        crop_x = mid_point_x+random.randint(int(-mid_point_x/5),int(mid_point_x/5))
        crop_y = mid_point_y+random.randint(int(-mid_point_y/5),int(mid_point_y/5)) #中心点移动
        
        dis_x = x_max-crop_x
        dis_y = y_max-crop_y 

        dis_min = min(dis_x,dis_y,crop_x,crop_y)#获取变动范围

        down = crop_y+random.randint(0,dis_min)
        up = crop_y-(down-crop_y)
        right = crop_x+(down-crop_y)
        left = crop_x-(down-crop_y)

        BOX_LEFT, BOX_UP, BOX_RIGHT, BOX_DOWN = left,up,right,down
# 从原始图像返回一个矩形区域,区域是一个4元组定义左上右下像素坐标
        box = (BOX_LEFT, BOX_UP, BOX_RIGHT , BOX_DOWN )
# 进行roi裁剪
        roi_area = img.crop(box)
# 裁剪后每个图像的路径+名称
        image_output_fullname = IMAGE_OUTPUT_PATH + "/" + str(i) + "_" + each_image
# 存储裁剪得到的图像
        roi_area.save(image_output_fullname)
        print('{0} crop done.'.format(each_image))

效果

猜你喜欢

转载自blog.csdn.net/weixin_47666981/article/details/121358252