Real-time background subtraction (Updated)

This is a quick test I made regarding background-substraction in Flash (which is also called Scene building etc.). I wanted to test this because of another experiment which I have in mind. The result is very nice, and it is acceptable fast.

A simplified description of the used technique. First of all I have the WebCam and a Video. A (grayscale) Snapshot of the scene will be taken which is called background. The background should not include the things you want to extract. From that moment on you create a grayscale picture from the webcam and substract the background from it. I draw the video onto the screen and for every pixel that has a difference greater than 8 I copy a pixel from the original webcam image.

Have a look
[as]var frame: BitmapData = webcam.getCurrentFrame();
videoBitmap.draw( videoDisplay );

//– create grayscale image of webcam frame
buffer.applyFilter( frame, frame.rect, new Point, bt709 );

//– substract the background
buffer.draw( background, null, null, ‘difference’ );

//– apply threshold
buffer.paletteMap( buffer, buffer.rect, new Point, null, null, alphaMap );

//– create mask using alpha channel
frame.copyChannel( buffer, buffer.rect, new Point, BitmapDataChannel.BLUE, BitmapDataChannel.ALPHA );

//– draw
smallScreen.draw( videoBitmap );
smallScreen.draw( frame );
screen.draw( smallScreen, scale );[/as]

I updated the way the resulting picture is drawn (thanks André!). Therefore the alpha-channel is abused as a mask applied with some thresholding. Instead of BitmapData.threshold I use BitmapData.paletteMap with a pre-cached table because it is a little bit faster. It is much better using the alpha-channel as a mask because of smooth edges. One last problem: Using only the Y-channel of a picture results in to many holes in the resulting image. I will try the same with three dimensions instead of one.

Related Posts

8 Responses to “Real-time background subtraction (Updated)”


  1. 1 Andre Michelle

    You can avoid the copy pixels-loop with the BitmapData.threshold method. Or isn’t it faster ?

  2. 2 joa

    I will have a try on that. It would be some sort of masking since I have to copy every pixel from the original webcam image onto the screen if the difference is higher than a threshold value. It could work with an alpha channel. Cutting out the alpha using BitmapData.threshold and then one simple draw().

  3. 3 hierro

    Hello guys, nice work…both of u :)

    As i already introduced to joa i’m working on the project on the link, now i’m goin to move some features in flex, hope it will be nice…let m eknow what do u think about kilyka :)

  4. 4 hierro

    More specific, i was thinking about use motion detection to extract a contour of subject and use it as bezier equation (…) to apply phisycs on it…what do u think about it ?

  5. 5 jdoklovic

    Would it be possible to get an example of this using loaded jpg data rather than the webcam?

    I’m having difficulties making it work properly with just and image, and the example posted above is somewhat incomplete (values for alphaMap, etc)

    Thanks.

  6. 6 Naomi

    Hi,
    I would love to see your full source code for this, I have been working on a similar project, but having trouble. Did you extend the MovieClip class or the sprite class?
    If you could send me your code, that would be amazing.
    Thanks,
    Naomi

  7. 7 David

    Hi Joa,

    I was wondering if you could offer a tip on the alpha map. I’m currently setting everything in the alphamap array halfway through (from index 127 upwards to 0xFFFFFF) with some decent results, but i think i could do better. Do you have any tips?

    Thanks,
    Dave

  8. 8 joa

    Yes, you should apply some morphological filters.

Leave a Reply






Close
E-mail It