Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Motion detection using OpenCV

I see queries related to opencv motion detection, but my requirement is much simpler , so i am asking the question again . I would like to analyse video frames and see if something has changed in the frame. Any kind of motion occurring in the frame has be recognized. I just want to get notified if something happens. I don't need to track/ draw contours.

Attempts made :

1) Template matching using OpenCV ( TM_CCORR_NORMED ).

I get the similarity index using cvMinMaxLoc &

if( sim_index > threshold ) 
    "Nothing chnged"
   else
    "Changed


Problem faced :

I couldn't find a way to decide on how to set thresholds. The values of false match and perfect were very close.

2) Method 2
a) Make running average
b) Take abs difference between current frame and moving average.
c) Threshold it and made it binary
d) Count the number of non zero values
Again am stuck with how to threshold it, because i am getting a large number of non zero values even for very similar frames.

Please advice me on what approach i should take. Am i going in the right direction with the above two methods, or is there a simple method which can work in all most generic scenarios.

like image 218
user1919600 Avatar asked Oct 05 '22 14:10

user1919600


1 Answers

Method 2 is generally regarded as the most simple method for motion detection, and is very effective if you have no water, swaying trees or highly variable lighting conditions in your video. Normally you implement it like this:

motion_frame=abs(newframe-running_avg);
running_avg=(1-alpha)*running_avg+alpha*newframe;

You can threshold the motion_frame if you want, then count the nonzeroes. But you could also just sum the elements of the motion_frame and threshold that instead (be sure to work with floating point numbers). Optimizing the parameters for this is pretty easy, just make two trackbars and play around with it. Typically alpha is around [0.1; 0.3].

Lastly, it is probably overkill to do this on entire frames, you could just use subsampled versions and the result will be very similar.

like image 111
dvhamme Avatar answered Oct 10 '22 04:10

dvhamme