i am modifying a simple motion detector from the Aforge Library. It simply compares 2 frames and draws the difference as semitransparent red pixels. I need to store the (constantly changing) average location of these red pixels (representing motion) as int tartgetX and int targetY. Here is the code:
Code:
public unsafe void ProcessFrame(Bitmap image)
{
BitmapData imageData = null;
// check previous frame
if (previousFrame == IntPtr.Zero)
{
// save image dimension
width = image.Width;
height = image.Height;
frameSize = width * height;
// alocate memory for previous and current frames
previousFrame = Marshal.AllocHGlobal(frameSize);
currentFrame = Marshal.AllocHGlobal(frameSize);
// temporary buffer
if (suppressNoise)
{
tempFrame = Marshal.AllocHGlobal(frameSize);
}
// lock source image
imageData = image.LockBits(
new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
// convert source frame to grayscale
ImageProcessingTools.GrayscaleImage(imageData, previousFrame);
// unlock source image
image.UnlockBits(imageData);
return;
}
// check image dimension
if ((image.Width != width) || (image.Height != height))
return;
// lock source image
imageData = image.LockBits(
new Rectangle(0, 0, width, height),
(highlightMotionRegions) ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
// convert current image to grayscale
ImageProcessingTools.GrayscaleImage(imageData, currentFrame);
// pointers to previous and current frames
byte* prevFrame = (byte*)previousFrame.ToPointer();
byte* currFrame = (byte*)currentFrame.ToPointer();
// difference value
int diff;
// 1 - get difference between frames
// 2 - threshold the difference
// 3 - copy current frame to previous frame
for (int i = 0; i < frameSize; i++, prevFrame++, currFrame++)
{
// difference
diff = (int)*currFrame - (int)*prevFrame;
// copy current frame to previous
*prevFrame = *currFrame;
// threshold
*currFrame = ((diff >= differenceThreshold) || (diff <= differenceThresholdNeg)) ? (byte)255 : (byte)0;
}
// calculate amount of motion pixels
pixelsChanged = 0;
if (suppressNoise)
{
// suppress noise and calculate motion amount
AForge.Win32.memcpy(tempFrame, currentFrame, frameSize);
byte* motion = (byte*)currentFrame.ToPointer() + width + 1;
byte* temp = (byte*)tempFrame.ToPointer() + width + 1;
int widthM1 = width - 1;
int heightM1 = height - 1;
// erosion is used to suppress noise
for (int y = 1; y < heightM1; y++)
{
for (int x = 1; x < widthM1; x++, motion++, temp++)
{
// check if it is motion pixel
if (*motion != 0)
{
*motion = (byte)(temp[-width - 1] & temp[-width] & temp[-width + 1] &
temp[width - 1] & temp[width] & temp[width + 1] &
temp[1] & temp[-1]);
pixelsChanged += (*motion & 1);
}
}
motion += 2;
temp += 2;
}
}
else
{
// calculate motion without suppressing noise
byte* motion = (byte*)currentFrame.ToPointer();
for (int i = 0; i < frameSize; i++, motion++)
{
pixelsChanged += (*motion & 1);
}
}
// highlight motion regions
if (highlightMotionRegions)
{
byte* src = (byte*)imageData.Scan0.ToPointer();
byte* motion = (byte*)currentFrame.ToPointer();
int srcOffset = imageData.Stride - width * 3;
// shift to the red channel
src += 2;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, motion++, src += 3)
{
*src |= *motion;
}
src += srcOffset;
}
}
// unlock source image
image.UnlockBits(imageData);
}
Comment