Image Background Removal

9 ビュー (過去 30 日間)
Mazvydas Tadaravicius
Mazvydas Tadaravicius 2011 年 1 月 26 日
移動済み: DGM 2023 年 2 月 12 日
For my gesture recognition uni project I have developed simple code that removes background from the image. For it to work there has to be an image of background scene and an image with an object that partially covers same background scene (a hand with a background of a room scene for example).
function [outIm] = makeMask(bg, im, tol)
%bg - background image
%im - input image
%tol - tolerance
[h,w] = size(bg);
outIm = false(h, w);
for ch = 1:h
for cw = 1:w
imPix = im(ch,cw);
bgPix = bg(ch,cw);
if ((bgPix == imPix) || (bgPix > imPix && bgPix <= imPix + tol) || (bgPix < imPix && bgPix >= imPix - tol))
outIm(ch, cw) = 0;
else
outIm(ch, cw) = 1;
end
end
end
end
As You see, code checks every single pixel and decides if it belongs to background scene. All this works well, however I want to ask is there more efficient way to achieve the same?

採用された回答

Egon Geerardyn
Egon Geerardyn 2011 年 1 月 26 日
You can try vectorizing that code, but that will be most likely destroy any short-circuiting you have in there.
Just by the top of my head, following code should be able to replace your for-loops:
brighterThanBg = (im > bg + tol);
darkerThanBg = (im < bg - tol);
outIm = (brighterThanBg | darkerThanBg);
That will also check every pixel but it will be faster as MATLAB is quite slow on loops. Also, by inverting your logic (you check for background, split into 3 regions, 2 of which require 2 conditions to be satisfied), while this codes only takes care of 2 regions (pixels too bright to be background, pixels too dark to be background), each only requiring a single condition.
  2 件のコメント
Walter Roberson
Walter Roberson 2011 年 1 月 26 日
Newer versions of Matlab have improved loop speed considerably, apparently.
Mazvydas Tadaravicius
Mazvydas Tadaravicius 2011 年 1 月 26 日
移動済み: DGM 2023 年 2 月 12 日
function [outIm] = makeMask2(bg, im, tol)
outIm = ((im > bg + tol) | (im < bg - tol));
end
This function does the job so much faster, have a look at these figs:
>> tic; m1 = makeMask(bgg, ig, 20); toc; tic; m2 = makeMask2(bgg, ig, 20); toc;
Elapsed time is 0.004686 seconds.
Elapsed time is 0.001663 seconds.
>> tic; m1 = makeMask(bgg, ig, 20); toc; tic; m2 = makeMask2(bgg, ig, 20); toc;
Elapsed time is 0.004764 seconds.
Elapsed time is 0.001655 seconds.
>> tic; m1 = makeMask(bgg, ig, 20); toc; tic; m2 = makeMask2(bgg, ig, 20); toc;
Elapsed time is 0.005040 seconds.
Elapsed time is 0.001660 seconds.
Thanks for the tip Egon Geerardyn.

サインインしてコメントする。

その他の回答 (1 件)

Siddharth Shankar
Siddharth Shankar 2011 年 1 月 26 日
Have you considered using the imabsdiff method. The difference of the two images is basically the object obstructing the background.
  1 件のコメント
Mazvydas Tadaravicius
Mazvydas Tadaravicius 2011 年 1 月 27 日
I could use imabsdiff method, however it does not tkae into consideration the change of lighting when object covers background. Also, it is way slower than my method or method suggested by Egon.
>> tic; imabsdiff(bgg, ig); im2bw(ans, graythresh(ans)); toc;
Elapsed time is 0.115902 seconds.
>> tic; imabsdiff(bgg, ig); im2bw(ans, graythresh(ans)); toc;
Elapsed time is 0.030604 seconds.

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by