How to remove white borders/space from an RGB image?

26 views (last 30 days)
I have an RGB image that has white spaces around that I want to remove. I have tried imwrite using getframe but it did not work. It still shows the white spaces around the image. The attached png is the image I am working with and it is a 3-channel image. Thank you.

Answers (3)

Walter Roberson
Walter Roberson on 14 Apr 2023
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/1355503/image.png';
img = imread(filename);
R = img(:,:,1);
G = img(:,:,2);
B = img(:,:,3);
mask = R == R(1,1) & G == G(1,1) & B == B(1,1);
vertprofile = ~all(mask,1);
horzprofile = ~all(mask,2);
first_nb_column = find(vertprofile, 1);
last_nb_column = find(vertprofile, 1, 'last');
first_nb_row = find(horzprofile, 1);
last_nb_row = find(horzprofile, 1, 'last');
clipped = img(first_nb_row:last_nb_row, first_nb_column:last_nb_column, :);
imwrite(clipped, 'clipped_img.png');
imshow(img); title('with background')
imshow(clipped); title('without background')
Note that this will not work as well for JPEG images: it is likely to end up with a bit of background around the image. That is because JPEG blurs straight lines. The JPEG blurring process is not deliberately designed as a form of anti-aliasing, but it has the same effect.
  1 Comment
Jay Ghosh
Jay Ghosh on 14 Apr 2023
@Walter Roberson Thank you! This works. I am working with PNG images, so this should be good enough.

Sign in to comment.


Image Analyst
Image Analyst on 14 Apr 2023
Try using imwrite with the actual image variable, not with using getframe() to get a screenshot of the displayed image.
  8 Comments
Image Analyst
Image Analyst on 27 May 2023
Again, "Please attach the original output_iceland.png "
and tell us how you saved it. Did you use a toolbar icon? Or save() or saveas() in the command window? Or use imwrite()?
DGM
DGM on 27 May 2023
Edited: DGM on 27 May 2023
There is no method that I know of that will consistently save an image from a figure at the correct size and without padding or interpolation artifacts, though using truesize() for image objects would be an improvement that the example in that link couldn't afford.
There are various ways to get the image without saving the figure, some of which are more convenient than others. You could do it using mat2gray() to normalize the data with respect to its extents (or optionally to some other limits). At that point, you could quantize it to the desired number of levels with gray2ind() and then apply an appropriate-length colormap using ind2rgb().
The problem with doing it that way is simply that gray2ind() and imagesc() do the quantization slightly differently. It might not matter much for a long color table, but it can be avoided. The answer I posted below uses a simplified version of MIMT gray2pcolor(), which does all the normalization/quantization/colormapping in one, and it can optionally emulate the quantization used by imagesc(). All you need is an arbitrarily-scaled grayscale image and a colormap. If the input range is unspecified, it will normalize with respect to data extrema, as does imagesc().
outpict = gray2pcolor(mydata,parula(256),'cdscale'); % scale WRT extrema
% ... or
outpict = gray2pcolor(mydata,parula(256),myclimits,'cdscale'); % scale WRT some other limits

Sign in to comment.


DGM
DGM on 14 Apr 2023
If you have some arbitrarily-scaled data, you need to map it however you mapped it when you plotted it. There's no reason to assume that it can be interpreted as an indexed image using direct mapping.
% some arbitrarily-scaled data
z = peaks(300); % 300x300
zrange = imrange(z); % the data extrema
% a colormap
CT = turbo(16);
% show the image and save it
imshow(z,[]) % colormapping is scaled to data extrema
colormap(CT)
saveas(gcf,'no.png') % some random size (759x611) and padded
Look at all that padding! How do you get saveas() to reliably save an image in the correct size with no padding? You don't.
% do the same thing, but generate an actual image
% this uses the same colormap, the same scaling limits
% and does the same quantization (gray2ind() won't)
outpict = gray2pcolor(z,CT,zrange,'cdscale');
imwrite(outpict,'yes.png') % the correct size (300x300), no padding
If you had tried to do direct colormapping using the same CT and zdata like so:
outpictdirect = ind2rgb(z,CT);
imwrite(outpictdirect,'notquite.png')
You would just get an error. Indexed images are maps of integer indices into the rows of a color table. Again, there is no reason to expect the z data to be integer-valued or to be on a scale that corresponds to the length of a color table.
Direct mapping like this is what you'd use when you have an actual indexed image (e.g. a GIF file). Scaled mapping is what you might be used to if you just want to display a single-channel image or data in pseudocolor with imagesc() or imshow(). While ind2rgb() alone works for direct mapping, the attached function does the latter.
  4 Comments
Image Analyst
Image Analyst on 15 Apr 2023
Or is the default application background color taken from the operating system colors?
DGM
DGM on 15 Apr 2023
Edited: DGM on 15 Apr 2023
I don't think so. The colors shown in the various screenshots I can find seem to correspond to either 204 or 240, and those were all taken over the course of 20 years on both Linux and Windows. If MATLAB respected system theming, then I wouldn't be running an inverted X display, and we wouldn't have a giant contentious thread about dark themes.
That said, I have no idea what exactly newer versions do, and I haven't touched Windows in about a decade.

Sign in to comment.

Categories

Find more on Convert Image Type in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!