0

我有一个在 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')
4

1 回答 1

0

解决了感谢@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')
于 2021-05-19T02:38:36.377 回答