Otsu thresholding
/**
* Copyright makc3d ( http://wonderfl.net/user/makc3d )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/shvq
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.ColorMatrixFilter;
import flash.media.Camera;
import flash.media.Video;
/**
* And now for something completely different...
* @see http://www.labbookpages.co.uk/software/imgProc/otsuThreshold.html
*/
[SWF(width=465,height=465,backgroundColor='#003F00')]
public class OtsuThreshold extends Sprite {
public var video:Video;
public var frame:BitmapData;
public var grayscale:ColorMatrixFilter;
public function OtsuThreshold () {
video = new Video; addChild (video);
video.attachCamera (Camera.getCamera ());
frame = new BitmapData (320, 240, false, 0);
grayscale = new ColorMatrixFilter (
[ 0.2989, 0.5866, 0.1145, 0, 0,
0.2989, 0.5866, 0.1145, 0, 0,
0.2989, 0.5866, 0.1145, 0, 0,
0, 0, 0, 1, 0 ]
);
addChild (new Bitmap (frame));
stage.addEventListener (Event.ENTER_FRAME, loop);
}
public function loop (e:Event):void {
frame.draw (video);
frame.applyFilter (frame, frame.rect, frame.rect.topLeft, grayscale);
var histData:Vector.<Number> = frame.histogram () [0];
// code from the above link
var total:int = 320 * 240;
var sum:Number = 0;
for (var t:int = 0; t < 256; t++) sum += t * histData [t];
var sumB:Number = 0;
var wB:int = 0;
var wF:int = 0;
var varMax:Number = 0;
var threshold:int = 0;
for (t = 0; t < 256; t++) {
wB += histData[t]; // Weight Background
if (wB == 0) continue;
wF = total - wB; // Weight Foreground
if (wF == 0) break;
sumB += t * histData[t];
var mB:Number = sumB / wB; // Mean Background
var mF:Number = (sum - sumB) / wF; // Mean Foreground
// Calculate Between Class Variance
var varBetween:Number = wB * wF * (mB - mF) * (mB - mF);
// Check if new maximum found
if (varBetween > varMax) {
varMax = varBetween;
threshold = t;
}
}
// apply threshold
frame.threshold (frame, frame.rect, frame.rect.topLeft,
'>=', threshold, 0xffffffff, 0xff);
frame.threshold (frame, frame.rect, frame.rect.topLeft,
'<', threshold, 0xff000000, 0xff);
}
}
}