要求:图片按照适当的比例缩小到1280*720画布中,其中画布颜色随机,图片在画布中的位置也是随机的;标签随着图片变化而变化,只是标注的位置从原图片中的手机变成标注整个原图片变化后的尺寸的宽和高再向内各5各像素。
1.利用脚本创建随机画布
import cv2
import random
import numpy as np
# 初始化一个彩色的画布 - cv2版本
for i in range(8200):
def init_canvas(width, height, color=(255, 255, 255)):
canvas = np.ones((height, width, 3), dtype="uint8")
# 将原来的三个通道抽离出来, 分别乘上各个通道的值
(channel_b, channel_g, channel_r) = cv2.split(canvas)
# 颜色的值与个通道的全1矩阵相乘
channel_b *= color[0]
channel_g *= color[1]
channel_r *= color[2]
# cv.merge 合并三个通道的值
return cv2.merge([channel_b, channel_g, channel_r])
canvas = init_canvas(1280, 720, color=(random.randint(0,255),random.randint(0,255),random.randint(0,255)))
cv2.imwrite("D:/AI/dataset/canvas/"+"/"+str(i+1)+".jpg", canvas)
# cv2.imshow('canvas', canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.将原图随机粘贴到画布上
def handle_img(imgdir, imgFlodName, img_path):
imgs = os.listdir(imgdir + imgFlodName)
imgNum = len(imgs)
print(imgNum)
image_ori = os.listdir(img_path)
image_Num = len(image_ori)
print(image_Num)
for i in range(imgNum): #for循环将每一个图片按照尺寸缩小并放入画布上
img1 = Image.open(imgdir + imgFlodName + "/" + imgs[i])
img0 = img1.size
oriImg = Image.open(img_path + "/" + image_ori[i])
image = oriImg.size
if img0[0] > 1280 or img0[1] > 720: #对原图片尺寸进行调整
if 1280 < img0[0] < 1600 or 720 < img0[1] < 900:
img = img1.resize((int(img0[0] * 0.65), int(img0[1] * 0.65)))
elif 1280 < img0[0] < 2560 or 720 < img0[1] < 1440:
img = img1.resize((int(img0[0] * 0.25), int(img0[1] * 0.25)))
elif 2560 < img0[0] < 5120 or 1440 < img0[1] < 2880:
img = img1.resize((int(img0[0] * 0.2), int(img0[1] * 0.2)))
else:
img = img1.resize((int(img0[0] * 0.1), int(img0[1] * 0.1)))
else:
img = img1
img2 = img.size
r1 = random.randint(0, 1280 - img2[0]) #创建随机数并记录下来,便于进行后续标签的移动
r2 = random.randint(0, 720 - img2[1])
oriImg.paste(img, (r1, r2)) #把原图粘贴到画布的随机位置(r1,r2);此时以画布左上角为原点
# oriImg.show()
oriImg1 = oriImg.convert('RGB')
oriImg1.save("C:/Users/A/Desktop/ai/demo/random on canvas/random canvas" + "/" + imgs[i])
list = []
list.append(r1)
list.append(r2)
list_all.append(list) #通过列表把每一组的随机数记录下来,再放入总的列表中,便于后续取用
3.改变标签xml文件的box
def resize_box(AnnoPath, OutPath):
files = os.listdir(AnnoPath)
i = 0
for xmlfile in files:
DomTree = xdm.parse(AnnoPath + xmlfile)
root = DomTree.documentElement # 获得xml文档对象
objectlist = root.getElementsByTagName('object') # 获得xml文档目标名称
sizelist = root.getElementsByTagName('size')
for size in sizelist:
w_list = size.getElementsByTagName('width')
h_list = size.getElementsByTagName('height')
w1 = int(w_list[0].childNodes[0].data)
h1 = int(h_list[0].childNodes[0].data)
if w1 > 1280 or h1 > 720:
if 1280 < w1 < 1600 or 720 < h1 < 900:
w = w1 * 0.65
h = h1 * 0.65
elif 1280 < w1 < 2560 or 720 < h1 < 1440:
w = w1 * 0.25
h = h1 * 0.25
elif 2560 < w1 < 5120 or 1440 < h1 < 2880:
w = w1 * 0.2
h = h1 * 0.2
else:
w = w1 * 0.1
h = h1 * 0.1
else:
w = w1
h = h1 #对高宽做出相同的变化
for objects in objectlist:
bndbox = objects.getElementsByTagName('bndbox')
for box in bndbox:
x1_list = box.getElementsByTagName('xmin')
y1_list = box.getElementsByTagName('ymin')
x2_list = box.getElementsByTagName('xmax')
y2_list = box.getElementsByTagName('ymax')
xmin = int(x1_list[0].childNodes[0].data)
ymin = int(y1_list[0].childNodes[0].data)
xmax = int(x2_list[0].childNodes[0].data)
ymax = int(y2_list[0].childNodes[0].data)
"下列四行代码是调整后坐标值与未调整前的坐标关系"
x1min = 5 + list_all[i][0]
y1min = 5 + list_all[i][1]
x1max = w - 5 + list_all[i][0]
y1max = h - 5 + list_all[i][1] #对box做出相同的粘贴,再向内5个像素点
x1_list[0].childNodes[0].data = int(x1min)
y1_list[0].childNodes[0].data = int(y1min)
x2_list[0].childNodes[0].data = int(x1max)
y2_list[0].childNodes[0].data = int(y1max)
if not os.path.exists(OutPath):
os.makedirs(OutPath)
save_file = OutPath + xmlfile
with open(save_file, 'w') as newxml:
DomTree.writexml(newxml)
# print("{}重写入完成".format(xmlfile))
i += 1
print("共计修改%s个xml文件" % i)
4.修改标签xml文件的size
def resize_size(AnnoPath1, OutPath1):
files = os.listdir(AnnoPath1)
i = 0
for xmlfile in files:
DomTree = xdm.parse(AnnoPath1 + xmlfile)
root = DomTree.documentElement # 获得xml文档对象
sizelist = root.getElementsByTagName('size') # 获得xml文档目标名称
for size in sizelist:
w_list = size.getElementsByTagName('width')
h_list = size.getElementsByTagName('height')
w = int(w_list[0].childNodes[0].data)
h = int(h_list[0].childNodes[0].data)
"下列四行代码是调整后坐标值与未调整前的坐标关系"
w1 = 1280
h1 = 720
w_list[0].childNodes[0].data = int(w1)
h_list[0].childNodes[0].data = int(h1) #将图片的宽和高改成画布大小1280*720,便于后续进行归一化操作(归一化操作需要标签尺寸和图片尺寸的比例以确标签在图片中的位置)
if not os.path.exists(OutPath1):
os.makedirs(OutPath1)
save_file = OutPath1 + xmlfile
with open(save_file, 'w') as newxml:
DomTree.writexml(newxml)
# print("{}重写入完成".format(xmlfile))
i += 1
print("共计修改%s个xml文件" % i)
5.效果观察
符合要求。



