0
votes

I have 2 images. One is background image and other image has same background but with some foreground object. I want to extract foreground object from background. Simple subtraction operation in matlab will not suffice as it subtracts RGB value of background image from that of foreground image (as in below code).

im1 = imread('output/frame-1.jpg')
im2 = imread('output/frame-7.jpg')

%# subtract
deltaImage = im1 - im2;
imshow(deltaImage)

So if background color is white and foreground object is blue, then output (i.e. deltaImage) comes foreground object with orange color with black background. However the output I want is foreground object with blue color (i.e. original color) with black background. How can I get this ? I tried to do it using below code, but output image is incorrect.

im1 = imread('foreground.jpg')
im2 = imread('background.jpg')
[m n k]=size(im2);
deltaImage = zeros(m,n,3);
fprintf('%d %d %d.\n',m,n,k);
for l=1:k
    for i=1:m-1
        for j=1:n-1
           if  im1(i:j:l)~=im2(i:j:l)
               deltaImage(i,j,l) = im1(i,j,l);
           end
        end 
    end
end
imshow(deltaImage)
  1. Background IMAGE

enter image description here

  1. Foreground Image

enter image description here

  1. Output Image (Here I want color of man to be blue)

enter image description here

1
Only subtract the background image if the pixels are equal? - AnonSubmitter85
@hari_OM So, do you like my answer or not? Any questions? Comments? - Pablo Rivas

1 Answers

2
votes

You can use deltaImage to create a mask (zeros and ones image) that multiplies the foreground. However, note that you will have artifacts associated with lossy image compression (.jpeg). These can be reduced, to some extent, if you use a threshold, like the average difference or a specific value you want. Try this:

im1 = double(imread('~/Downloads/foreground.jpg'));
im2 = double(imread('~/Downloads/background.jpg'));

compute the difference of the averages of the 3 channels

deltaImage = mean(im2,3) - mean(im1,3);

then use the product of the mean by a standard deviation (~3), or uncomment the line below to use a specific threshold, like 128

mask = deltaImage>3*mean(deltaImage(:));  
% mask = deltaImage>128;                  

then assuming all original images are in 8-bit format produce a result also in 8-bit format:

result = uint8(cat(3, im1(:,:,1).*mask, im1(:,:,2).*mask, im1(:,:,3).*mask));
imshow(result)

And this is the result you should get:

output

Again the weird looking pixels around the main object are artifacts of lossy image compression (.jpeg), you should try working with lossless like .png formats.