Accord.Vision.Motion.GridMotionAreaProcessing.ProcessFrame C# (CSharp) Method

ProcessFrame() public method

Process video and motion frames doing further post processing after performed motion detection.

Processes provided motion frame and calculates motion level for each grid's cell. In the case if HighlightMotionGrid property is set to , the cell with motion level above threshold are highlighted.

Motion frame is not 8 bpp image, but it must be so. Video frame must be 8 bpp grayscale image or 24/32 bpp color image.
public ProcessFrame ( UnmanagedImage videoFrame, UnmanagedImage motionFrame ) : void
videoFrame Accord.Imaging.UnmanagedImage Original video frame.
motionFrame Accord.Imaging.UnmanagedImage Motion frame provided by motion detection /// algorithm (see ).
return void
        public void ProcessFrame( UnmanagedImage videoFrame, UnmanagedImage motionFrame )
        {
            if ( motionFrame.PixelFormat != PixelFormat.Format8bppIndexed )
            {
                throw new InvalidImagePropertiesException( "Motion frame must be 8 bpp image." );
            }

            if ( ( videoFrame.PixelFormat != PixelFormat.Format8bppIndexed ) &&
                 ( videoFrame.PixelFormat != PixelFormat.Format24bppRgb ) &&
                 ( videoFrame.PixelFormat != PixelFormat.Format32bppRgb ) &&
                 ( videoFrame.PixelFormat != PixelFormat.Format32bppArgb ) )
            {
                throw new UnsupportedImageFormatException( "Video frame must be 8 bpp grayscale image or 24/32 bpp color image." );
            } 
            
            int width  = videoFrame.Width;
            int height = videoFrame.Height;
            int pixelSize = Bitmap.GetPixelFormatSize( videoFrame.PixelFormat ) / 8; 

            if ( ( motionFrame.Width != width ) || ( motionFrame.Height != height ) )
                return;

            int cellWidth  = width  / gridWidth;
            int cellHeight = height / gridHeight;

            // temporary variables
            int xCell, yCell;

            unsafe
            {
                // process motion frame calculating amount of changed pixels
                // in each grid's cell
                byte* motion = (byte*) motionFrame.ImageData.ToPointer( );
                int motionOffset = motionFrame.Stride - width;

                for ( int y = 0; y < height; y++ )
                {
                    // get current grid's row
                    yCell = y / cellHeight;
                    // correct row number if image was not divided by grid equally
                    if ( yCell >= gridHeight )
                        yCell = gridHeight - 1;

                    for ( int x = 0; x < width; x++, motion++ )
                    {
                        if ( *motion != 0 )
                        {
                            // get current grid's collumn
                            xCell = x / cellWidth;
                            // correct column number if image was not divided by grid equally
                            if ( xCell >= gridWidth )
                                xCell = gridWidth - 1;

                            motionGrid[yCell, xCell]++;
                        }
                    }
                    motion += motionOffset;
                }

                // update motion grid converting absolute number of changed
                // pixel to relative for each cell
                int gridHeightM1 = gridHeight - 1;
                int gridWidthM1  = gridWidth  - 1;

                int lastRowHeight   = height - cellHeight * gridHeightM1;
                int lastColumnWidth = width - cellWidth   * gridWidthM1;

                for ( int y = 0; y < gridHeight; y++ )
                {
                    int ch = ( y != gridHeightM1 ) ? cellHeight : lastRowHeight;

                    for ( int x = 0; x < gridWidth; x++ )
                    {
                        int cw = ( x != gridWidthM1 ) ? cellWidth : lastColumnWidth;

                        motionGrid[y, x] /= ( cw * ch );
                    }
                }

                if ( highlightMotionGrid )
                {
                    // highlight motion grid - cells, which have enough motion

                    byte* src = (byte*) videoFrame.ImageData.ToPointer( );
                    int srcOffset = videoFrame.Stride - width * pixelSize;

                    if ( pixelSize == 1 )
                    {
                        // grayscale case
                        byte fillG = (byte) ( 0.2125 * highlightColor.R +
                                              0.7154 * highlightColor.G +
                                              0.0721 * highlightColor.B );

                        for ( int y = 0; y < height; y++ )
                        {
                            yCell = y / cellHeight;
                            if ( yCell >= gridHeight )
                                yCell = gridHeight - 1;

                            for ( int x = 0; x < width; x++, src++ )
                            {
                                xCell = x / cellWidth;
                                if ( xCell >= gridWidth )
                                    xCell = gridWidth - 1;

                                if ( ( motionGrid[yCell, xCell] > motionAmountToHighlight ) && ( ( ( x + y ) & 1 ) == 0 ) )
                                {
                                    *src = fillG;
                                }
                            }
                            src += srcOffset;
                        }
                    }
                    else
                    {
                        // color case
                        byte fillR = highlightColor.R;
                        byte fillG = highlightColor.G;
                        byte fillB = highlightColor.B;

                        for ( int y = 0; y < height; y++ )
                        {
                            yCell = y / cellHeight;
                            if ( yCell >= gridHeight )
                                yCell = gridHeight - 1;

                            for ( int x = 0; x < width; x++, src += pixelSize )
                            {
                                xCell = x / cellWidth;
                                if ( xCell >= gridWidth )
                                    xCell = gridWidth - 1;

                                if ( ( motionGrid[yCell, xCell] > motionAmountToHighlight ) && ( ( ( x + y ) & 1 ) == 0 ) )
                                {
                                    src[RGB.R] = fillR;
                                    src[RGB.G] = fillG;
                                    src[RGB.B] = fillB;
                                }
                            }
                            src += srcOffset;
                        }
                    }
                }
            }
        }