如何在 Python 中删除部分 PNG 图像以使其不透明
How to remove part of a PNG image in Python to make it Opaque
我有一个在 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 in boxes.iterrows():
shape = [(row['topleftcornerxpx'], row['topleftcornerypx']), (row['topleftcornerxpx'] + row['sizepx'], 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['topleftcornerxpx'] + row['sizepx'], 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')
我有一个在 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 in boxes.iterrows():
shape = [(row['topleftcornerxpx'], row['topleftcornerypx']), (row['topleftcornerxpx'] + row['sizepx'], 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['topleftcornerxpx'] + row['sizepx'], 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')