src/Foundation/Media/Gimela.Media.Vision.Motion/MotionProcessors/GridMotionAreaProcessing.cs
/// <summary>
/// Process video and motion frames doing further post processing after
/// performed motion detection.
/// </summary>
/// 
/// <param name="videoFrame">Original video frame.</param>
/// <param name="motionFrame">Motion frame provided by motion detection
/// algorithm (see <see cref="IMotionDetector"/>).</param>
/// 
/// <remarks><para>Processes provided motion frame and calculates motion level
/// for each grid's cell. In the case if <see cref="HighlightMotionGrid"/> property is
/// set to <see langword="true"/>, the cell with motion level above threshold are
/// highlighted.</para></remarks>
///
Process video and motion frames doing further post processing after
performed motion detection.
Process video and motion frames doing further post processing after performed motion detection .
public unsafe void ProcessFrame(UnmanagedImage videoFrame, UnmanagedImage motionFrame)
    {
      int width = videoFrame.Width;
      int height = videoFrame.Height;
      if ((motionFrame.Width != width) || (motionFrame.Height != height))
        return;
      int cellWidth = width / gridWidth;
      int cellHeight = height / gridHeight;
      int xCell, yCell;
      byte* motion = (byte*)motionFrame.ImageData.ToPointer();
      int motionOffset = motionFrame.Stride - width;
      for (int y = 0; y < height; y++)
      {
        yCell = y / cellHeight;
        if (yCell >= gridHeight)
          yCell = gridHeight - 1;
        for (int x = 0; x < width; x++, motion++)
        {
          if (*motion != 0)
          {
            xCell = x / cellWidth;
            if (xCell >= gridWidth)
              xCell = gridWidth - 1;
            motionGrid[yCell, xCell]++;
          }
        }
        motion += motionOffset;
      }
      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)
      {
        byte* src = (byte*)videoFrame.ImageData.ToPointer();
        int srcOffset = videoFrame.Stride - width * 3;
        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 += 3)
          {
            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;
        }
      }
    }
public unsafe void ProcessFrame ( UnmanagedImage videoFrame , UnmanagedImage motionFrame ) { int width = videoFrame . Width ; int height = videoFrame . Height ; if ( ( motionFrame . Width != width ) || ( motionFrame . Height != height ) ) return ; int cellWidth = width / gridWidth ; int cellHeight = height / gridHeight ; int xCell , yCell ; byte * motion = ( byte * ) motionFrame . ImageData . ToPointer ( ) ; int motionOffset = motionFrame . Stride - width ; for ( int y = 0 ; y < height ; y ++ ) { yCell = y / cellHeight ; if ( yCell >= gridHeight ) yCell = gridHeight - 1 ; for ( int x = 0 ; x < width ; x ++ , motion ++ ) { if ( * motion != 0 ) { xCell = x / cellWidth ; if ( xCell >= gridWidth ) xCell = gridWidth - 1 ; motionGrid [ yCell , xCell ] ++ ; } } motion += motionOffset ; } 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 ) { byte * src = ( byte * ) videoFrame . ImageData . ToPointer ( ) ; int srcOffset = videoFrame . Stride - width * 3 ; 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 += 3 ) { 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 ; } } }
Process video and motion frames doing further post processing after
performed motion detection.
Process video and motion frames doing further post processing after performed motion detection .
// temporary variables // process motion frame calculating amount of changed pixels // in each grid's cell // get current grid's row // correct row number if image was not divided by grid equally // get current grid's collumn // correct column number if image was not divided by grid equally // update motion grid converting absolute number of changed // pixel to relative for each cell // highlight motion grid - cells, which have enough motion
videoFrame
UnmanagedImage
Original video frame.
Original video frame .
motionFrame
UnmanagedImage
Motion frame provided by motion detection
algorithm (see


Motion frame provided by motion detection algorithm ( see
remarks
Processes provided motion frame and calculates motion level
for each grid's cell. In the case if  property is
set to , the cell with motion level above threshold are
highlighted.
Processes provided motion frame and calculates motion level for each grid ' s cell . In the case if property is set to the cell with motion level above threshold are highlighted .