package { import com.bit101.components.HUISlider; import com.bit101.components.ProgressBar; import com.bit101.components.PushButton; import com.bit101.components.RadioButton; import flash.display.*; import flash.events.*; import flash.text.*; import flash.geom.ColorTransform; import flash.utils.setTimeout; import com.bit101.components.CheckBox; /** * explainations FR * http://xphilipp.developpez.com/articles/meanshift/ * * source code * http://rsbweb.nih.gov/ij/plugins/mean-shift.html * * @author nicoptere */ public class Main extends Sprite { public function Main():void { if (stage) { init(); } else{ addEventListener(Event.ADDED_TO_STAGE, init) }; } //[Embed(source = '../lib/plants.jpg')]private var plants:Class; [Embed(source = '../lib/ourson.jpg')]private var plants:Class; [Embed(source = '../lib/lizard.jpg')]private var lizard:Class; [Embed(source = '../lib/carabus.jpg')]private var carabus:Class; [Embed(source = '../lib/statue.jpg')]private var statue:Class; private var src:Bitmap; private var bd:BitmapData; private var noise:BitmapData; private var bmp:Bitmap; private var settings:TextField; private var meanshift:MeanShift; private var running:Boolean = false; private var showOriginal:Boolean = false; private var image0:RadioButton; private var image1:RadioButton; private var image2:RadioButton; private var image3:RadioButton; private var btn:PushButton; private var distance:HUISlider; private var radius:HUISlider; private var _noise:CheckBox; private var prog:ProgressBar; private var scanline:Shape = new Shape(); private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; /* BITMAPS */ src = Bitmap( new plants() ); noise = src.bitmapData.clone(); noise.noise( 0, 0, 255, 7, false ); bd = src.bitmapData.clone(); //var _bmp:Bitmap = Bitmap( addChild( new Bitmap( bd ) ) ); //_bmp.x = 0; /* SETTINGS */ radius = new HUISlider( this, 3, bd.height + 1, 'radius' ); radius.minimum = 0; radius.maximum = 10; radius.value = 2; distance = new HUISlider( this, radius.x+radius.width, bd.height + 1, 'distance' ); distance.minimum = 10; distance.maximum = 100; distance.value = 20; btn = new PushButton( this, bd.width - 100 - 4, bd.height + 4, 'render' ); _noise = new CheckBox( this, 8, radius.y + radius.height + 8, 'apply noise' ); image0 = new RadioButton( this, _noise.x + 70, _noise.y , 'plants', true, changePicture ); image1 = new RadioButton( this, image0.x + 50, _noise.y , 'carabus auratus', false, changePicture ); image2 = new RadioButton( this, image1.x + 90, _noise.y , 'lizard', false, changePicture ); image3 = new RadioButton( this, image2.x + 50, _noise.y , 'statue', false, changePicture ); prog = new ProgressBar(this, btn.x, _noise.y ); prog.width = 100; var container:Sprite = Sprite( addChild( new Sprite() ) ); container.addEventListener( MouseEvent.MOUSE_DOWN, swapBitmap ); settings = TextField( addChild( new TextField( ))); settings.autoSize = TextFieldAutoSize.LEFT; btn.addEventListener( MouseEvent.MOUSE_DOWN, run ); stage.addEventListener( Event.ENTER_FRAME, status ); scanline.graphics.lineStyle( 0, 0xFFFFFF ); scanline.graphics.lineTo( bd.width, 0 ); addChild( scanline ); /* MEAN SHIFT FILTER */ meanshift = new MeanShift( radius.value, distance.value ); meanshift.bitmapData = bd; bmp = Bitmap( container.addChild( new Bitmap( meanshift.bitmapData ) ) ); } public function swapBitmap( e:Event ):void { showOriginal = ( !showOriginal ) ? true : false; if ( showOriginal ) { bmp.bitmapData = bd; } else { bmp.bitmapData = meanshift.bitmapData; } } public function run( e:Event ):void { scanline.y = 0; if ( !meanshift.running ) { meanshift.addEventListener( ProgressEvent.PROGRESS, progress ); meanshift.addEventListener( Event.COMPLETE, completeHandler ); if ( showOriginal ) swapBitmap( null ); bd.draw( src ); if ( _noise.selected ) { bd.draw( noise, null, new ColorTransform(1,1,1,1,0,0,0,-200), BlendMode.HARDLIGHT ); } meanshift.bitmapData = bd; meanshift.radius = radius.value; meanshift.distance = distance.value; meanshift.process(); } else { meanshift.stop(); } } public function changePicture( e:Event ):void { scanline.y = 0; meanshift.stop(); switch( ( e.currentTarget as RadioButton ).label ) { case 'plants': src = new plants() as Bitmap; break; case 'carabus auratus': src = new carabus() as Bitmap; break; case 'lizard': src = new lizard() as Bitmap; break; case 'statue': src = new statue() as Bitmap; break; } bd.draw( src ); bmp.bitmapData = bd; } public function completeHandler( e:Event):void { stage.removeEventListener( Event.ENTER_FRAME, progress ); meanshift.removeEventListener( Event.COMPLETE, completeHandler ); } public function progress( e:ProgressEvent):void { var pct:Number = meanshift.percent; prog.value = pct / 100; scanline.y = ( prog.value * bd.height ) + 1; if ( !showOriginal ) { bmp.bitmapData = meanshift.bitmapData; } } public function status( e:Event ):void { settings.text = 'radius: ' + meanshift.radius.toFixed(2) +' distance: ' + meanshift.distance.toFixed(2) +' | '+( (showOriginal)? 'original' : 'meanshift' ); settings.setTextFormat( new TextFormat( 'verdana', 10, 0xFFFFFF ) ); } } }