How to preserve transparent edges in images after image processing?

2 views (last 30 days)
Hello, everyone!
I'm facing a problem related to the processing of .png images with transparent edges obtained in a simulation software. Whenever I convert the image (RGB) to grayscale, together with a Graussian filter, the transparent edges become white, and this hinders the reading and training of the neural network model I'm using.

A input (with transparent edges) and output instance (no transparent edges)

Information: size = [480 480]

Notice how in the first image we have transparent edges, and in the following images the edges become white and threrefore suffer from changes.

Code

path = 'C:\Users\W11\OneDrive\Desktop\dataset\pla_50\';
files = dir(fullfile(path,'*.png*'));
sizeImg = 160;
fileSize = [sizeImg, sizeImg];
numFiles = length(files);
file = zeros([fileSize, numFiles], 'like', imread(fullfile(path, files(1).name)));
time = zeros(numFiles, 1);
for i = 1:length(files)
img = imread(fullfile(path, files(i).name));
[~, name, ext] = fileparts(files(i).name);
if size(img, 3) == 3
grayImg = rgb2gray(img);
else
grayImg = img;
end
mean=0; variance=0.01;
noisedImg = imnoise(grayImg, 'gaussian', mean, variance);
imgDeformed = elasticDeform(noisedImg, 8, 30);
file(:, :, 1, i) = imresize(imgDeformed, fileSize);
separatorIndex = strfind(name, '-');
depth(i, 1) = round(str2double(name(1:separatorIndex-1)), 2);
time(i, 1) = round(str2double(name(separatorIndex+1:end)));
end
[train_idx, ~, val_idx] = dividerand(numFiles, 0.7, 0, 0.3);
XTrain = file(:, :, 1, train_idx);
YTrain = depth(train_idx, 1);
XVal = file(:, :, 1, val_idx);
YVal = depth(val_idx, 1);
save('data.mat', 'XTrain', 'XVal', 'YTrain', 'YVal');
Where elasticDeform is:
function imgDeformed = elasticDeform(img, alpha, sigma)
[rows, cols] = size(img);
dx = alpha * randn(rows, cols);
dy = alpha * randn(rows, cols);
dx = imgaussfilt(dx, sigma);
dy = imgaussfilt(dy, sigma);
[X, Y] = meshgrid(1:cols, 1:rows);
X_new = X + dx; Y_new = Y + dy;
imgDeformed = interp2(X, Y, double(img), X_new, Y_new, 'linear', 0);
imgDeformed = uint8(imgDeformed);
end

Saving a 4-D array and the depth

save('data.mat', 'XTrain', 'XVal', 'YTrain', 'YVal');
The data is saved in .mat format.
  4 Comments
Matt J
Matt J on 22 Aug 2024
Edited: Matt J on 22 Aug 2024
I hope the changes in my ask have allowed my problem to be understood.
I don't see any changes to the code, nor any image attachments.

Sign in to comment.

Answers (1)

Walter Roberson
Walter Roberson on 22 Aug 2024
Moved: Walter Roberson on 22 Aug 2024
Notice how in the first image we have transparent edges
img = imread(fullfile(path, files(i).name));
The images are not being treated as if they have transparency. To read transparency, you need
[img, Cmap, Alpha] = imread(fullfile(path, files(i).name));
if ~isempty(Cmap)
img = ind2rgb(img, Cmap);
end
if isempty(Alpha)
Alpha = uint8(255)+zeros(size(img,1), size(img,2),'uint8');
end
Afterwards, Alpha contains the transparency information.
  3 Comments
Walter Roberson
Walter Roberson on 22 Aug 2024
Well... you don't. It is not obvious that the transparency of the image has any effect on the calculations.
But I would suggest,
imgDeformed_cleaned = im2uint8(im2double(imgDeformed) .* im2double(Alpha));
Walter Roberson
Walter Roberson on 22 Aug 2024
You currently have
imgDeformed = elasticDeform(noisedImg, 8, 30);
What would it mean to "preserve transparency" in imgDeformed?
I mean, you could
imgDeformed = cat(3, imgDeformed, Alpha);
to end up with an RGBA array, but that is of questionable utility, since there isn't much you can do with RGBA images other than use the Tiff library to write them out.
You would have more utility to continue to hold the transparency separately, as at least then you can imwrite('FILENAME.png', imgDeformed, [], Alpha)
You can "clean up" the edges of imgDeformed by weighting it by the Alpha matrix, using the code I already posted,
imgDeformed_cleaned = im2uint8(im2double(imgDeformed) .* im2double(Alpha));
But you then proceed to
file(:, :, 1, i) = imresize(imgDeformed, fileSize);
imresize() is going to mess with edges all over again. You might want to
temp = imresize(imgDeformed, fileSize);
temp_Alpha = imresize(Alpha, fileSize);
cleaned_resized = im2uint8(im2double(temp) .* im2double(temp_Alpha));
file(:, :, 1, i) = cleaned_resized;
but this is likely to still generate edges that are a bit blurry, as the resized Alpha is likely to contain intermediate values between 0 and 255.
You might want to
temp = imresize(imgDeformed, fileSize);
temp_Alpha = round(im2double(imresize(Alpha, fileSize)));
cleaned_resized = im2uint8(im2double(temp) .* temp_Alpha);
file(:, :, 1, i) = cleaned_resized;
This will produce sharp Alpha boundaries in the resized image.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!