2

Is there any way of removing a white background and turning it into black in MATLAB?

Say i have this image:

enter image description here

I get the following output when i apply the code suggested in the answer: Which isn't perfect

enter image description here

rcollyer
  • 10,475
  • 4
  • 48
  • 75
vini
  • 4,657
  • 24
  • 82
  • 170
  • 7
    It took me a while to realise that this was actually a fruit, and not some sort of computer-generated image of a lava planet. I think I need to turn off the Star Trek and go eat something healthy for once. – Polynomial Feb 07 '12 at 15:29
  • Can't you iterate through the image pixels and change all the white pixels to black? – Pulkit Goyal Feb 07 '12 at 15:35
  • @PulkitGoyal i think that could be done – vini Feb 07 '12 at 15:44
  • 1
    Check this question and see if it helps: http://stackoverflow.com/questions/8041703/remove-white-background-from-an-image-and-make-it-transparent – Mark Ransom Feb 07 '12 at 18:44

4 Answers4

6

The problem, as Andrey noticed, is that not all background pixels are "255 white". This probably is happening due to JPEG compression algorithm and also because there's a shadow of the fruit in the image.

To solve this problem, first get a binary mask of the fruit region by blurring the image (this is necessary to overcome the JPEG artifacts) and then threshold the image with a very high value, but a little lower than 255. Here's the solution in Matlab:

I = imread('https://i.stack.imgur.com/5p4jV.jpg'); % Load your image.
H = fspecial('gaussian'); % Create the filter kernel.
I = imfilter(I,H); % Blur the image.

Mask = im2bw(Ig, 0.9); % Now we are generating the binary mask.
I([Mask, Mask, Mask]) = 0; % Now we have the image.

Here's the output (you can also try different threshold values in im2bw):

enter image description here

Alceu Costa
  • 9,733
  • 19
  • 65
  • 83
  • 1
    Good post (+1). By the way, it doesn't have to be due to JPEG compression. If it is a natural image of fruit on white table, any digital camera nowadays does this kind of effect. – Andrey Rubshtein Feb 07 '12 at 20:01
  • On cameras this also happens because of JPEG compression. In professional or semi-profession cameras, however, you can choose to save the photos with no compression (also knows as raw format). Then you don't get that kind of effect. – Alceu Costa Feb 07 '12 at 20:04
  • 3
    Even in RAW images with custom processing to Bitmap you will get it. It is a natural property of optics and sensor limitation (Check out about MTF/PSF) - http://www.imatest.com/docs/sharpness/ – Andrey Rubshtein Feb 07 '12 at 20:06
  • Not to mention the noise that will be on the white background and will cause some of the white pixels become almost white. – Andrey Rubshtein Feb 07 '12 at 20:08
2

You fail due to the anti-aliasing effect that blurs the edges your image. These pixels that were not removed are not 255! They are a bit lower. Basically you have 2 options:

(I wrote them from the perspective of using Matlab).

  1. Select the relevant part by using imfreehand and then create a mask by calling createMask from the API.
  2. Finding the correct threshold level, which isn't 255. (Much harder - if possible)

Here is a Matlab code for the first:

function SO1
    im = imread('c:\x.jpg');
    figure();
    imshow(im);
    f = imfreehand();
    mask = f.createMask();
    mask = repmat(mask,[1 1 3]);
    im(~mask) = 0;
    figure;imshow(im);
end
Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
0

You should draw the image to a black background.

//Your bitmap
Bitmap originalImage = new Bitmap(100, 100);

//Black background
Bitmap bitmap = new Bitmap(100, 100);
Graphics g = Graphics.FromImage(bitmap);

//Draw the background
g.FillRectangle(Brushes.Black, 0, 0, 100, 100);

//Draw the original bitmap over the black one
g.DrawImage(originalImage, 0, 0);
Youri Leenman
  • 228
  • 2
  • 8
-1

yes. if your image is save as a variable called img:

thr = 255;
mask = sum(img,3)==thr*3;
for i=1:3
    c = img(:,:,i);
    c(mask)=0;
    img(:,:,i)=c;
end

|-)

Mercury
  • 1,886
  • 5
  • 25
  • 44
  • This algorithm does not solve the problem: the output would be the same as the second image shown in the question. – Alceu Costa Feb 07 '12 at 19:22
  • Try changing the thr from 255 to somthing smaller (and the second line to: mask = sum(img,3)>=thr*3 – Mercury Feb 08 '12 at 06:22
  • Or use distance from background measurement: thr =200; img = double(img); d = (255-img).^2; d = sqrt(sum(d,3)); d(d>thr)=thr; d = d/thr; newImg = img.* repmat(d,[1 1 3]); image(uint8(newImg)); – Mercury Feb 08 '12 at 06:38