问题描述
我有一个在 PNG 图像上创建遮挡的脚本。来自https://arxiv.org/pdf/2001.04086.pdf的数据增强遮挡技术。
脚本在创建遮挡方面运行良好,但它们在 PNG 上绘制为黑色矩形。
我希望他们做的是从 PNG 中切出这些矩形,并使它们成为 PNG 的 alpha 层的一部分,这样当粘贴到背景上时,背景就会通过矩形显示出来。基本上使黑色矩形透明。
当前的实现输出如下所示:
完整的脚本如下,但需要在这里工作的区域:
# Draw each Box onto the image
for index,row in Boxes.iterrows():
shape = [(row['topleftcornerxpx'],row['topleftcornerypx']),(row['topleftcornerxpx'] + row['sizepx'],row['topleftcornerypx'] + row['sizepx'])]
img1 = ImageDraw.Draw(img)
img1.rectangle(shape,fill = "black")
已尝试添加 alpha 蒙版,但这会从背景中移除 alpha 通道并使矩形保持黑色。
# Draw each Box onto the image
for index,row['topleftcornerypx'] + row['sizepx'])]
mask = Image.new('L',img.size,color = 255)
draw=ImageDraw.Draw(mask)
img1 = ImageDraw.Draw(img)
img1.rectangle(shape,fill=0)
img.putalpha(mask)
完整的脚本(有人可能会喜欢):
import os
from pandas import DataFrame
from PIL import Image,ImageDraw
import numpy as np
#set directories
directory = str("C:/GIT/Temp/Test/test/")
target_directory = str("C:/GIT/Temp/Test/test/occluded/")
occlusion_scales = [.20,.125,.08] #Percent of image the occlusions will cover. Add or remove as many as required.
image_padding = int(5)
existing_files = os.listdir(target_directory)
#print(existing_files)
#Get files
for filename in os.listdir(directory):
if filename.endswith('.png'):
# Process for each occlusion scale in the list.
for scales in occlusion_scales:
img = Image.open(directory + filename)
# Get image dimensions
imgwidth,imgheight = img.size
# Get smallest value out of x & y to scale Box size by.
Box1sizepx = round(min(imgwidth,imgheight) * scales)
print(filename)
#Dont process files already processed,can comment out for replace.
if (filename.replace('.png','') + '_occluded_' + str(scales)+'.png') not in existing_files:
#print(filename + ' not in list')
# Calculate number of Boxes accross and down required
Boxesaccross = round((imgwidth/2) / Box1sizepx)
Boxesdown = round((imgheight/2) / Box1sizepx)
# Create dataframe for Boxes
Boxes = DataFrame(columns=['sizepx','topleftcornerxpx','topleftcornerypx'])
# Set row counter for loop.
Boxrow = 0
#Draw a Box for each row and within that each column
while Boxesdown >= 1:
Boxesdown = Boxesdown -1
Boxcolumn = 0
while Boxesaccross >= 1:
Boxesaccross = Boxesaccross -1
new_Box = {'sizepx':Box1sizepx,'topleftcornerxpx':round(Box1sizepx*.8) + (Box1sizepx * Boxcolumn),'topleftcornerypx':round(Box1sizepx*.8) + (Box1sizepx * Boxrow)}
Boxes = Boxes.append(new_Box,ignore_index=True)
Boxcolumn = Boxcolumn + 2
Boxrow = Boxrow + 2
Boxesaccross = round((imgwidth/2) / Box1sizepx)
# Draw each Box onto the image
for index,row in Boxes.iterrows():
shape = [(row['topleftcornerxpx'],row['topleftcornerypx'] + row['sizepx'])]
img1 = ImageDraw.Draw(img)
img1.rectangle(shape,fill = "black")
#Save the image
print(target_directory + filename.replace('.png','') + '_occluded_' + str(scales)+'.png')
#Crop the image with some padding
cropped_object = img.crop(((0 - image_padding),(0 - image_padding),(imgwidth + image_padding),(imgheight + image_padding)))
cropped_object.save(target_directory + filename.replace('.png','') + '_occluded_' + str(scales)+'.png')
解决方法
解决了感谢@furas,将填充设置为0而不是“黑色”。如果有人想要的话,更新了脚本。
import os
from pandas import DataFrame
from PIL import Image,ImageDraw
import numpy as np
#set directories
directory = str("C:/GIT/Temp/Test/test/")
target_directory = str("C:/GIT/Temp/Test/test/occluded/")
occlusion_scales = [.20,.125,.08] #Percent of image the occlusions will cover. Add or remove as many as required.
image_padding = int(5)
existing_files = os.listdir(target_directory)
#print(existing_files)
#Get files
for filename in os.listdir(directory):
if filename.endswith('.png'):
# Process for each occlusion scale in the list.
#pixdata = filename.load()
#print(pixdata)
for scales in occlusion_scales:
img = Image.open(directory + filename)
# Get image dimensions
imgwidth,imgheight = img.size
# Get smallest value out of x & y to scale box size by.
box1sizepx = round(min(imgwidth,imgheight) * scales)
print(filename)
#Dont process files already processed,can comment out for replace.
if (filename.replace('.png','') + '_occluded_' + str(scales)+'.png') not in existing_files:
#print(filename + ' not in list')
# Calculate number of boxes accross and down required
boxesaccross = round((imgwidth/2) / box1sizepx)
boxesdown = round((imgheight/2) / box1sizepx)
# Create dataframe for boxes
boxes = DataFrame(columns=['sizepx','topleftcornerxpx','topleftcornerypx'])
# Set row counter for loop.
boxrow = 0
#Draw a box for each row and within that each column
while boxesdown >= 1:
boxesdown = boxesdown -1
boxcolumn = 0
while boxesaccross >= 1:
boxesaccross = boxesaccross -1
new_box = {'sizepx':box1sizepx,'topleftcornerxpx':round(box1sizepx*.8) + (box1sizepx * boxcolumn),'topleftcornerypx':round(box1sizepx*.8) + (box1sizepx * boxrow)}
boxes = boxes.append(new_box,ignore_index=True)
boxcolumn = boxcolumn + 2
boxrow = boxrow + 2
boxesaccross = round((imgwidth/2) / box1sizepx)
# Draw each box onto the image
for index,row in boxes.iterrows():
shape = [(row['topleftcornerxpx'],row['topleftcornerypx']),(row['topleftcornerxpx'] + row['sizepx'],row['topleftcornerypx'] + row['sizepx'])]
img1 = ImageDraw.Draw(img)
img1.rectangle(shape,fill = 0)
#Save the image
print(target_directory + filename.replace('.png','') + '_occluded_' + str(scales)+'.png')
#Crop the image with some padding
cropped_object = img.crop(((0 - image_padding),(0 - image_padding),(imgwidth + image_padding),(imgheight + image_padding)))
cropped_object.save(target_directory + filename.replace('.png','') + '_occluded_' + str(scales)+'.png')