public class motiondetector1 : imotiondetector { private ifilter grayscalefilter = new grayscalebt709( ); private difference differencefilter = new difference( ); private threshold thresholdfilter = new threshold( 15 ); private 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 { { return calculatemotionlevel; } set { calculatemotionlevel = value; } } // motion level - amount of changes in percents public double motionlevel { { return (double) pixelschanged / ( width * height ); } } // constructor public motiondetector1( ) { } // reset detector 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 ); // image dimension width = image.width; height = image.height; // return first time return; } bitmap tmpimage; // apply grayscale file tmpimage = grayscalefilter.apply( image ); // set backgroud frame overlay difference filter differencefilter.overlayimage = backgroundframe; // apply difference filter bitmap tmpimage2 = differencefilter.apply( tmpimage ); // lock temporary image , apply filters on 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 current backgroundframe = tmpimage; // extract red channel original image bitmap redchannel = extrachchannel.apply( image ); // merge red channel moving object mergefilter.overlayimage = tmpimage3; bitmap tmpimage4 = mergefilter.apply( redchannel ); redchannel.dispose( ); tmpimage3.dispose( ); // replace red channel in 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( ); ( int y = 0; y < height; y++ ) { ( int x = 0; x < width; x++, ptr++ ) { count += ( (*ptr) >> 7 ); } ptr += offset; } } // unlock image image.unlockbits( data ); return count; } }
}
Comments
Post a Comment