1

I am trying to to subtract the background from a picture of an object to leave only the foreground object. I have found the RGB values of the background as 218 220 219 using imshow(). How can I use the RGB values with imsubtract()?

y = [218 220 219];
z = imsubtract(img,y);

Error using imsubtract (line 55) X and Y must have the same size and class, or Y must be a scalar double.

PencilCase

dertkw
  • 7,798
  • 5
  • 37
  • 45
Jak
  • 471
  • 5
  • 20
  • 1
    Your img is a `mxnx3` matrix. Where the 3 components corresponds to red blue green. Your `y` is also in those components. What you want is to subtract `img(:,:,1)-218` and so on. – The Minion Jun 10 '14 at 10:40
  • @TheMinion Maybe my idea was wrong but using your suggestion only leaves me with an image without the colour [220 220 220] for example. – Jak Jun 10 '14 at 11:02

2 Answers2

4

You can use to do that

z = bsxfun( @minus, img, permute( [218 220 219], [1 3 2] ) );

You need to pay attention to data type and range. If img is of type uint8 pixel values will be in range 0..255 but it will be difficult to subtract values as you'll see results underflowing at 0: uint8(4) - uint8(10) is 0...
Thus, you might want to convert img to double using im2double having pixel values in range 0..1. In that case you'll have to convert the "gray" vector [2218 220 219] to 0..1 range by dividing it by 255.
So, a more complete solution would be

z = bsxfun( @minus, im2double(img), permute( [218 220 219]/255, [1 3 2] ) );
Shai
  • 111,146
  • 38
  • 238
  • 371
  • 2
    also you should pay attention for neg. values after the subtraction – The Minion Jun 10 '14 at 10:44
  • 1
    @Jak because values of `z` are **not** in range 0..1 - `z` has negative values. Try `imagesc( abs( z ) );` or `imagesc( sum( abs( z ), 3 ) );` – Shai Jun 10 '14 at 11:01
-1

The following ended up getting me closer to the answer I was looking for, although not without your guidance!

img = imread('IMG_0792.jpg');
img = im2double(img);

rows = numel(img(:,1,1));
columns = numel(img(1,:,1));

for i = 1:rows
    for j = 1:columns
        if ( ( img(i,j,1) > 0.75) && ( img(i,j,2) > 0.7) && ( img(i,j,3) > 0.7) )
            img(i,j,1) = 1;
            img(i,j,2) = 1;
            img(i,j,3) = 1;
        end
    end
end

imshow(img);
Jak
  • 471
  • 5
  • 20
  • -1 for (a) using `numel` instead of [`size`](http://www.mathworks.com/help/matlab/ref/size.html). (b) using [`i` and `j` as variables in Matlab](http://stackoverflow.com/q/14790740/1714410) and (c) using nested loops instead of [tag:bsxfun]. – Shai Jun 18 '14 at 07:31