In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

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);
		}
	}
}