As a continuation of my previous post, here is a simple algorithm for motion detection in a live video stream using OpenCV. It basically follows a few simple steps:
1. Subtract frames and generate a binary image
cvAbsDiff(
frameTime1,
frameTime2,
frameForeground
);
cvShowImage( "AbsDiff", frameForeground); //AbsDiff window
cvThreshold(
frameForeground,
frameForeground,
20, //Threshold
255, //Saturate up to 255
CV_THRESH_BINARY);
//CV_THRESH_BINARY_INV);
//CV_THRESH_TRUNC);
//CV_THRESH_TOZERO);
//CV_THRESH_TOZERO_INV);
//
cvShowImage( "AbsDiffThreshold", frameForeground); //AbsDiffThreshold window
The threshold as one may guess, can be used as a primitive noise supression parameter.
2. Run through the binary image and accumulate events.
int row, col;
uchar sig1, sig2;
unsigned long int rowsum[frameForeground->height], totalsum;
totalsum = 0;
for( row = 0; row < frameForeground->height; row++ )
{
rowsum[row] = 0;
for ( col = 0; col < frameForeground->width; col++ )
{
sig1 = CV_IMAGE_ELEM( frameForeground, uchar, row, col * 2 );
sig2 = CV_IMAGE_ELEM( frameForeground, uchar, row, col * 2 + 1 );
rowsum[row] += (sig1 + sig2);
//printf("Y: %d X: %d Val: %d \n", row, col, sig1);
//printf("Y: %d X: %d Val: %d \n", row, col, sig2);
}
totalsum += rowsum[row];
}
printf("Totalsum: %20d \n", totalsum);
if (totalsum >= 80000) // Motion detection threshold
{
cvRectangle(image,cvPoint(10,10), cvPoint(310, 230),cvScalar(0, 255, 0, 0),1,8,0); // Draw a green rectangle
}
cvShowImage( "Camera", image ); //Display the original image w/wo added green rectangle
After all event accumulation, a comparison with a motion detection coefficient is made. Once the total event count is larger than the detection coefficient a green rectangle is embedded on the original frame.
Here is my dead simple example, which should work straight out of the box.
Comments
No comments yet





