sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.27k stars 1.11k forks source link

On what Image Processing Algorithm is WebCam Capture implemented? #714

Closed promise24o closed 5 years ago

promise24o commented 5 years ago

Hi Sarxos, i am working on my Final Year Project, Surveillance System Based on Motion Detection and i am Using WebCam Capture in Java. Can you tell me what image processing algorithm you used in its implementation please? So I can discuss that in my literature review.

Thanks as i anticipate your favourable response.

sarxos commented 5 years ago

Hi @lilblazekonceptz

The motion detection algorithm I used is very simple. The individual parts may be described somewhere in a literature, but to be honest I never checked and implemented it based solely on some very pragmatic assumptions which are described later.

The fundamental steps are the following:

1) Blur image. 2) Convert pixels to gray scale. 3) Calculate modified area. 4) Decide if there is motion.

Blur Image

This is done to reduce noise. We use a filter which performs a box blur on an image. Box blur is based on the moving window in which we calculate average values for every channel in RGB space. The blur filter I'm using is derived from JHLabs filters library by Jerry Huxtable. I cannot describe in details how it works, but you can check the code to understand more, but believe me - there is no magic there.

https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/main/java/com/github/sarxos/webcam/util/jh/JHBlurFilter.java

In general this is implementation of https://en.wikipedia.org/wiki/Box_blur

Convert Pixels to Gray Scale

This is done so we can work on luminance data. It is much easier to do conversion from RGB to luminance because if we stay within RGB we will need to perform motion detection for every channel separately and then average the output, which is generally more complex.

The conversion is done by changing RGB data from every pixel to NTSC luminance (aka brightness). The formulation used for this is based on old NTSC spec (from 1953). It's deprecated, but we don't care, because this is not used to display anything on screen and we only need it for calculation. If we would need to display resultant luma on screen, then I would use newer spec.

The newest formula used to calculate luma, defined in sRGB spec, is 1:

Y = 0.212 * R + 0.715 * G + 0.072 * B

And the 1953 formula used to convert RGB to luma is:

Y = 0.299 * R + 0.587 * G + 0.114 * B

This is done in code https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/main/java/com/github/sarxos/webcam/util/jh/JHGrayFilter.java#L62 (the variable names in code are different, but please don't be mislead by this).

final int y = (r * 77 + g * 151 + b * 28) >> 8;

The values 77, 151 and 28 are equivalents of 0.299, 0.587 and 0.114 which are coefficients resulting from CIE color matching functions and standard chromaticities of RGB channels. RGB values used in algorithm are in range from 0 to 255 and luma coefficients are in range of 0 to 1, so:

 77 = 255 * 0.299
151 = 255 * 0.587
 28 = 255 * 0.114

Luma is later converted back to RGB in such a way that resultant pixel is gray. Each channel value (R, G, and B) has the same value which is equal to luma. There is also alpha channel used in formulation, but this does not matter in our case because we use JPG data which has no alpha channel present.

return a | (y << 16) | (y << 8) | y;

Calculate Modified Area

This is done by by comparing all pixels with the previous values (from previous image) to calculate how many of these pixels are different. Pixel intensity difference must be greater than a given threshold (configurable value). If this is true, increase number of different pixels by one. At the end calculate percentage value of modified area by using this simple formulation:

area = count * 100d / (width * height);

Where:

Decide If There is Motion

After we have percentage value of modified area we can then compare this value with a configured value. If percentage area is higher than a given value, then motion detection is fired and motion detector is engaged. If percentage area is lower than a configured value, then there is no motion and motion detector is disengaged.


When you take a look into the code:

https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamMotionDetectorDefaultAlgorithm.java

You may see that there are other things happening. For example a center of gravity is calculated, a threshold points are stored, but these have no connection to the motion detection algorithm itself. It's just so you can get these values from the object and visualize on your image (e.g. mark different pixels with a different colours, mark motion centre of gravity, etc).

The code may look a little bit crappy so please do not use it as a reference on how one should implement such algorithms. It was implemented mainly to serve a very basic purpose and was much shorter, but later was modified by a community to add no-engage zones, support for pluggable algorithms, etc, and today I would implement it differently.

Take care and I wish you a best luck with your Final Year Project! Computer engineering is awesome :)

sarxos commented 5 years ago

Hi @lilblazekonceptz,

One more thought. The default driver is derived from OpenIMAJ so it would be very nice if you reference it in your literature:

https://dl.acm.org/citation.cfm?id=2072421

promise24o commented 5 years ago

Thank you so much for these, I am really grateful.

On Fri, May 10, 2019 at 11:53 AM Bartosz Firyn notifications@github.com wrote:

Hi @lilblazekonceptz https://github.com/lilblazekonceptz,

One more thought. The default driver is derived from OpenIMAJ http://openimaj.org/ so it would be very nice if you reference it in your literature:

https://dl.acm.org/citation.cfm?id=2072421

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sarxos/webcam-capture/issues/714#issuecomment-491247771, or mute the thread https://github.com/notifications/unsubscribe-auth/AIROEF6H2NG523EYE7IU63DPUVH4PANCNFSM4HL57HLA .

shinobisoft commented 4 years ago

@sarxos Sorry to reopen this, but is the method mentioned above also suitable for light detection? I have an old Android phone that I use as a security camera but it doesn't have or support night vision. I've written a DVR for this camera but I'd like to figure a way to detect day light changes to enable or disable recording at certain times of day. If the above method isn't suitable do you have any ideas how to implement what I'm looking to do?

Thanks for your time!