前言
今天做荔枝果园冠层目标检测数据集,感觉无人机拍摄拼接后的图片面积太大。试着用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))
效果