1

public class MotionDetector1 : IMotionDetector { private IFilter grayscaleFilter = new GrayscaleBT709( ); private Difference differenceFilter = new Difference( ); プライベートしきい値thresholdFilter = 新しいしきい値( 15 ); プライベート IFilter erosionFilter = new Erosion( ); private Merge mergeFilter = new Merge( );

    private IFilter extrachChannel = new ExtractChannel( RGB.R );
    private ReplaceChannel replaceChannel = new ReplaceChannel( RGB.R, null );

    private Bitmap  backgroundFrame;
    private BitmapData bitmapData;

    private bool    calculateMotionLevel = false;
    private int     width;  // image width
    private int     height; // image height
    private int     pixelsChanged;

    // Motion level calculation - calculate or not motion level
    public bool MotionLevelCalculation
    {
        get { return calculateMotionLevel; }
        set { calculateMotionLevel = value; }
    }

    // Motion level - amount of changes in percents
    public double MotionLevel
    {
        get { return (double) pixelsChanged / ( width * height ); }
    }


    // Constructor
    public MotionDetector1( )
    {
    }

    // Reset detector to initial state
    public void Reset( )
    {
        if ( backgroundFrame != null )
        {
            backgroundFrame.Dispose( );
            backgroundFrame = null;
        }
    }

    // Process new frame
    public void ProcessFrame( ref Bitmap image )
    {
        if ( backgroundFrame == null )
        {
            // create initial backgroung image
            backgroundFrame = grayscaleFilter.Apply( image );

            // get image dimension
            width   = image.Width;
            height  = image.Height;

            // just return for the first time
            return;
        }

        Bitmap tmpImage;

        // apply the grayscale file
        tmpImage = grayscaleFilter.Apply( image );

        // set backgroud frame as an overlay for difference filter
        differenceFilter.OverlayImage = backgroundFrame;

        // apply difference filter
        Bitmap tmpImage2 = differenceFilter.Apply( tmpImage );

        // lock the temporary image and apply some filters on the locked data
        bitmapData = tmpImage2.LockBits( new Rectangle( 0, 0, width, height ),
            ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed );

        // threshold filter
        thresholdFilter.ApplyInPlace( bitmapData );
        // erosion filter
        Bitmap tmpImage3 = erosionFilter.Apply( bitmapData );

        // unlock temporary image
        tmpImage2.UnlockBits( bitmapData );
        tmpImage2.Dispose( );

        // calculate amount of changed pixels
        pixelsChanged = ( calculateMotionLevel ) ?
            CalculateWhitePixels( tmpImage3 ) : 0;

        // dispose old background
        backgroundFrame.Dispose( );
        // set backgound to current
        backgroundFrame = tmpImage;

        // extract red channel from the original image
        Bitmap redChannel = extrachChannel.Apply( image );

        //  merge red channel with moving object
        mergeFilter.OverlayImage = tmpImage3;
        Bitmap tmpImage4 = mergeFilter.Apply( redChannel );
        redChannel.Dispose( );
        tmpImage3.Dispose( );

        // replace red channel in the original image
        replaceChannel.ChannelImage = tmpImage4;
        Bitmap tmpImage5 = replaceChannel.Apply( image );
        tmpImage4.Dispose( );

        image.Dispose( );
        image = tmpImage5;
    }

    // Calculate white pixels
    private int CalculateWhitePixels( Bitmap image )
    {
        int count = 0;

        // lock difference image
        BitmapData data = image.LockBits( new Rectangle( 0, 0, width, height ),
            ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed );

        int offset = data.Stride - width;

        unsafe
        {
            byte * ptr = (byte *) data.Scan0.ToPointer( );

            for ( int y = 0; y < height; y++ )
            {
                for ( int x = 0; x < width; x++, ptr++ )
                {
                    count += ( (*ptr) >> 7 );
                }
                ptr += offset;
            }
        }
        // unlock image
        image.UnlockBits( data );

        return count;
    }
}

}

4

0 に答える 0