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

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)

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

@Walter Roberson Thank you! This works. I am working with PNG images, so this should be good enough.

Sign in to comment.

Try using imwrite with the actual image variable, not with using getframe() to get a screenshot of the displayed image.

8 Comments

I believe they want to trim away the gray around the color background -- I think the title is asking about how to remove the white borders
The image I see doesn't have a white background, just a gray background frame and a cyan background in the image. The gray frame can be avoided by using imwrite instead of getframe, saveas, print, exportgraphics, or however else they generated the image file.
DGM
DGM on 14 Apr 2023
Edited: DGM on 14 Apr 2023
You know I strongly discourage figure capture if it can be avoided, but it's not clear that it can be easily avoided here. We'd really need to know how the figure is being created in order to know if it's an image or can be converted to a standard image compatible with imwrite()'s expectations.
With any luck, it is. If it's just a pseudocolored arbitrarily-scaled data, that might need to be converted.
@Image Analyst The image shows a white backgroud frame, when I display it on my laptop. Howevr, it looks gray when I upload here. I am not sure why.
I have used imwrite with just the data and filename (see the codes below), and it still saves the white background frame.
ice = imread('output_iceland.png');
imwrite(ice, 'output_iceland2.png');
Doing that would not change the image to add a white frame padding around the outside if the image. Please attach the original output_iceland.png so we can check it. But I strongly doubt it because I used that code and it does not add a white outer frame.
Also, it actually looks like you maybe started with a gray scale (i.e. indexed) image and then you applied a colormap to it to produce the pseudocolored RGB image. If you wanted the pseudocolored image you should not use getframe, you should use ind2rgb like this.
cmap = turbo(256); % Whatever colormap you want to use.
rgbImage = ind2rgb(grayImage, cmap);
imwrite(rgbImage, 'output_iceland2.png');
@Image Analyst, @DGM I did start with a grayscale image, and ran 'CoherenceFilter' on it. I displayed the output with 'imagesc', and saved it as a .png. I needed to give this output image to a domain expert (for him to assign class labels on smaller/split frames), and he wanted a color image, as that makes his job easier while labelling the small frames (250x250). In the end, I was able to remove the white/gray frame using the above code snippet of @Walter Roberson.
Is there any other way I could have saved the imagesc display, which would not have this gray frame? Thank you very much. Also, my apologies to both of you for a late late response. My proposal defense made these past couple of moths super hectic. I apprrciate you taking the time out and responding to my question.
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()?
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.

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

I agree. That's what I told him : don't use saveas() which I suspect he was using. However first he said he was using getframe(), then he said that he didn't and just a simple call to imread followed immediately by a call to imwrite() (rather than saveas). So now I'm not really sure what was done. But hopefully with 3 of us saying to use imwrite() instead of saveas() and getframe() he will follow our advice.
DGM
DGM on 14 Apr 2023
Edited: DGM on 14 Apr 2023
I thought that he was misunderstanding the solution and thought that rewriting the padded image would remove the padding. I mean the padding has to come from somewhere, and it's not from an imread()/imwrite() cycle.
It is strange that it's gray. The default figure color hasn't been gray for a long time. It may be that the working images are rather old. That wouldn't bode well for the likelihood of the underlying data being available.
EDIT: no wait. I'm being dumb. That's the current figure color (240). The older color was 204. I'm just forgetting what colors things are because I run MATLAB on an inverted display.
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 Images in Help Center and File Exchange

Products

Release

R2021b

Asked:

on 13 Apr 2023

Edited:

DGM
on 27 May 2023

Community Treasure Hunt

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

Start Hunting!