Remove moving objects from images using an image stack

Dear all,

removing moving objects from a scene can be achieved by using a stack of images and apply a median filter to a vector that hold the pixel values of every at the same pixel-coordinate.
The result of the median would be the output image pixel value at that very pixel-coordinate.

Out of curiosity I tried to apply this in Scilab with the IPCV-toolbox … mainly to read and show RGB images.

Below you may find an example code, which seem to do what I expect…however it contains two
for-loops, for iterating through the pixel locations.

This is very slow and i wonder if there is a way to avoid these.
I tried to work straight with

 output = median(input, 'anInteger')     // anInteger = 1,2,3

but with no real success.

The principle idea is example wise explained here:

Thank you,
Philipp

inDir = get_absolute_file_path('imageStack.sce');
chdir(inDir);

// get the file names
imgDir = inDir + 'SubFolderThatContainsAllImages';
imgFiles =  findfiles(imgDir);

// get the number of images
nrOfImg = max(size(imgFiles));

// build a vector that contains all absolute image paths ... only for convenience
for i = 1:nrOfImg
    imgPath(i) = imgDir + '\' + imgFiles(i);
end

// init image
imgIn = imread(imgPath(1));

// get the image size = size of output image 
[imHeight imWidth imCh] = size(imgIn)

// initiating the RGB-planes of the output image
imgOut_R = zeros(imHeight, imWidth);
imgOut_G = zeros(imHeight, imWidth);
imgOut_B = zeros(imHeight, imWidth);

// initiating the output image
imgOut = zeros(imHeight, imWidth, 3);

// building the image stack
for i = 1:nrOfImg
    disp(i);
    imgStack(i,:,:,: ) = imread(imgPath(i));         // note:  (i, :,:,:) creates a smiley in the post
end

// extracting the according RGB-planes from each image
pxVals_R = imgStack(:,:,:,1);
pxVals_G = imgStack(:,:,:,2);
pxVals_B = imgStack(:,:,:,3);

// iterating through all pixel locations to find the median value 
// from all images at each specific pixel location
// do this for each color channel

for j = 1:imWidth
    disp(j);
    for i = 1:imHeight
        imgOut_R(i,j) = median(pxVals_R(:,i,j));
        imgOut_G(i,j) = median(pxVals_G(:,i,j));
        imgOut_B(i,j) = median(pxVals_B(:,i,j));
    end
end

// compose the output image
imgOut(:,:,1) = imgOut_R;
imgOut(:,:,2) = imgOut_G;
imgOut(:,:,3) = imgOut_B;

// show the result
imshow(imgOut./256);  // imshow requires range 0-1

printf("end of script");

Hi,

It should works but may be some the issue might be mixing up the datatype of uint8 and double.

Theoretically the code could be simplify by:

  1. Create image sequences with for loop by adding the images in 4th dim
  2. Use media(S_seq, 4)

You shall get the result.

However, due to the median function might not be optimum in Scilab, doing so will either takes long, or might have crash Scilab.

Following codes should be working code, by breaking the images into blocks, so that it could be processed in chuck of blocks and combined back to whole image.

fn = ls(['*.png','*.jpg','*.jpeg']);

// Combine Images
S = imread(fn(1));
for i = 2:size(fn,1);
    S(:,:,:,i) = imread(fn(i));    
end

// Break into blocks of 64x64
block_sz = 64;

// Init output as uint8
S_out = uint8(zeros(S(:,:,:,1)));

// Calculate total block and init counter (for display only)
total_block = size(S,1)/block_sz * size(S,2)/block_sz;
cnt_block = 1;

// Processing by block
for r = 1:size(S,1)/block_sz
    r_start = (r - 1) * block_sz + 1;
    r_end = r * block_sz;

    for c = 1:size(S,2)/block_sz
        c_start = (c - 1) * block_sz + 1;
        c_end = c * block_sz;

        S2 = S(r_start:r_end,c_start:c_end,:,:);
        S3 = median(S2,4);
        S_out(r_start:r_end,c_start:c_end,:) = S3;

        disp('Processing Block : ' + string(cnt_block) + ' of ' + string(total_block));
        cnt_block = cnt_block + 1;
    end

end

imshow(S_out);


This will be slow, but working. Consider to optimize the median function with c, or using other processing technique such as column processing technique for faster processing.

hope this helps.

rgds,
CL

1 Like

Hi,

Thanks for the example code.

  • the code is faster
  • the code is working
  • the code did not (yet) chrashed Scilab

Best Regards,
Philipp

1 Like