package
{
import __AS3__.vec.Vector;
import com.bit101.components.CheckBox;
import com.bit101.components.HSlider;
import com.bit101.components.Label;
import com.bit101.components.RadioButton;
import com.quasimondo.bitmapdata.CameraBitmap;
import com.quasimondo.bitmapdata.ThresholdBitmap;
import com.quasimondo.filters.AdaptiveThresholdFilter;
import flash.display.*;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import com.adobe.viewsource.ViewSource;
import net.hires.debug.Stats;
[SWF( width="640",height="480", backgroundColor="#000000")]
public class ThresholdAndEdges extends Sprite
{
private var camera:CameraBitmap;
private var adaptiveThresholdFilter:AdaptiveThresholdFilter;
private var histogramMap:BitmapData;
private var tempHistogramMap:BitmapData;
private var toleranceSlider:HSlider;
private var blurSlider:HSlider;
private var thresholdSlider:HSlider;
private var smoothSlider:HSlider;
private var rb_fixed:RadioButton;
private var rb_otsu:RadioButton;
private var rb_entropy:RadioButton;
private var rb_moment:RadioButton;
private var rb_discrimintant:RadioButton;
private var rb_adaptive:RadioButton;
private var cb_despeckle:CheckBox;
private var cb_edges:CheckBox;
private var cb_invert:CheckBox;
private var thresholdMap:ThresholdBitmap;
public function ThresholdAndEdges()
{
ViewSource.addMenuItem(this, "srcview/index.html");
stage.scaleMode = "noScale";
stage.align = "TL";
stage.frameRate = 61;
init();
}
protected function init():void
{
histogramMap = new BitmapData( 256, 100, false, 0 );
tempHistogramMap = histogramMap.clone();
camera = new CameraBitmap( 320, 240,25 );
thresholdMap = new ThresholdBitmap( camera.bitmapData );
rb_fixed = new RadioButton( this, 400, 150, "Fixed Threshold", true, changeMode );
rb_otsu = new RadioButton( this, 400, 164, "Otsu", false, changeMode );
rb_entropy = new RadioButton( this, 400, 178, "Entropy", false, changeMode );
rb_moment = new RadioButton( this, 400, 192, "Moment", false, changeMode );
rb_discrimintant = new RadioButton( this, 400, 206, "Discriminant", false, changeMode );
rb_adaptive = new RadioButton( this, 400, 220, "Adaptive Threshold", false, changeMode );
thresholdSlider = new HSlider( this, 460, 240 );
thresholdSlider.minimum = 0;
thresholdSlider.maximum = 255;
thresholdSlider.value = 127;
var lbl:Label = new Label(this,400,235,"Threshold");
toleranceSlider = new HSlider( this, 460, 260 );
toleranceSlider.minimum = 0;
toleranceSlider.maximum = 255;
toleranceSlider.value = 50;
lbl = new Label(this,400,255,"Tolerance");
blurSlider = new HSlider( this, 460, 280 );
blurSlider.minimum = 0;
blurSlider.maximum = 255;
blurSlider.value = 32;
lbl = new Label(this,400,275,"Radius");
smoothSlider = new HSlider( this, 460, 300 );
smoothSlider.minimum = 0;
smoothSlider.maximum = 16;
smoothSlider.value = 0;
lbl = new Label(this,400,295,"Smoothing");
cb_despeckle = new CheckBox( this, 400, 320, "Despeckle" );
cb_edges = new CheckBox( this, 400, 340, "Show Edges" );
cb_invert = new CheckBox( this, 400, 360, "Invert" );
camera.addEventListener( Event.RENDER, render );
var tbm:Bitmap = new Bitmap( thresholdMap );
tbm.y = 0;
tbm.x = 70;
addChild( tbm );
var cbm:Bitmap = new Bitmap( camera.bitmapData );
cbm.y = 240;
cbm.x = 70;
addChild( cbm );
var hbm:Bitmap = new Bitmap( histogramMap );
hbm.x = 400;
addChild( hbm );
var stats:Stats = new Stats();
addChild(stats);
}
private function render( event:Event ):void
{
thresholdMap.smooth = smoothSlider.value;
thresholdMap.adaptiveTolerance = toleranceSlider.value;
thresholdMap.thresholdValue = thresholdSlider.value;
thresholdMap.adaptiveRadius = blurSlider.value;
thresholdMap.applyDespeckle = cb_despeckle.selected;
thresholdMap.applyEdges = cb_edges.selected;
thresholdMap.invert = cb_invert.selected;
thresholdMap.render();
thresholdSlider.value = thresholdMap.thresholdValue;
var histo:Vector.<Vector.<Number>> ;
histo = camera.bitmapData.histogram(camera.bitmapData.rect);
var hRect:Rectangle = histogramMap.rect;
histogramMap.fillRect( hRect, 0 );
var j:int, i:int;
var maxValue:Number, value:Number;
var channel:Vector.<Number>;
hRect.width = 1;
for (var c:int = 0; c < 3; c++) {
channel = histo[c];
maxValue =0.0;
i = 256;
while ( i > 0 ) {
value = channel[--i];
if ( value > maxValue ) maxValue = value;
}
tempHistogramMap.fillRect( histogramMap.rect, 0 );
if ( thresholdMap.mode != ThresholdBitmap.ADAPTIVE )
{
hRect.x = thresholdSlider.value;
hRect.y = 0;
hRect.height = 100;
tempHistogramMap.fillRect( hRect, 0xffffffff );
}
for ( i=0; i<256; i++) {
hRect.x = i;
hRect.height = 100 * channel[i] / maxValue;
hRect.y = 100 - hRect.height;
tempHistogramMap.fillRect( hRect, i );
}
histogramMap.copyChannel( tempHistogramMap, tempHistogramMap.rect, tempHistogramMap.rect.topLeft, 4, 1 << c );
}
}
private function changeMode( event:MouseEvent ):void
{
switch ( event.currentTarget )
{
case rb_fixed:
thresholdMap.mode = ThresholdBitmap.FIXED;
break;
case rb_adaptive:
thresholdMap.mode = ThresholdBitmap.ADAPTIVE;
break;
case rb_discrimintant:
thresholdMap.mode = ThresholdBitmap.DISCRIMINANT;
break;
case rb_entropy:
thresholdMap.mode = ThresholdBitmap.ENTROPY;
break;
case rb_moment:
thresholdMap.mode = ThresholdBitmap.MOMENT;
break;
case rb_otsu:
thresholdMap.mode = ThresholdBitmap.OTSU;
break;
}
}
}
}