5
votes

I have a set of transparent PNG images with black artifacts around the edges, like this:

Example image

I'm looking for a way to clean up the borders automatically. I tried simply masking out pixels under a certain RGB value, but the images themselves can also contain black pixels, and those then get filtered out. I'm using Python3 and opencv3/PIL.

My question is: How can I get rid of the black edges, while preserving black pixels that are not part of an edge?

EDIT: As usr2564301 pointed out below, very few (if any) of the edge pixels are pure black. I still need to remove them, so I'd want to use some threshold value and remove pixels that are neighbors to a transparent pixel and are either:

  • Darker than the threshold, or
  • Darker by at least threshold than any neighboring non-transparent pixel.
2
The edges are not all black, only some pixels are. Very, very few, actually. Clicking here and there I can't even find one. What do you want to happen with pixels on the border that are not black, dark, or even medium – but still 'darker than a random adjecent pixel'?Jongware
Good catch! In that case, I guess it'd make sense to consider some threshold value, and remove pixels that 1) border a transparent pixel, and 2) are at least threshold darker than any of the surrounding non-transparent pixels, or at least threshold lighter than pure black.Nee
Generally, you can't get the real slash in binary mode.Kinght 金
use the transparency channel to find all the object pixels (create a mask from it). Then erode that mask or remove all the mask points where there are sharp color changes at the border with a pixel value near black.Micka
How would I find the color changes? That's one thing I couldn't find an explanation on how to do, and iterating over all pixels (and then checking four or more neighbors) seems unnecessary.Nee

2 Answers

2
votes

Try taking the alpha channel and eroding it by a couple of pixels. I am illustrating the technique with ImageMagick because that's easier, but you can do the same thing with OpenCV:

convert pinkboythingwithcathead.png \( +clone -alpha extract -morphology erode disk:2 \) -compose copy-alpha -composite result.png

enter image description here

2
votes

You can antialias the edges of the alpha channel in ImageMagick as follows:

Input:

enter image description here

convert image.png -channel a -blur 0x2 -level 50x100% +channel result.png

enter image description here

Adjust the 2 using smaller values than 2 if thinner black border and larger than 2 if broader black borders.