forked from: Corner Detection [少し軽くなった]

by utabi forked from Corner Detection [すんげー重い] (diff: 69)
少し軽くなったが画像のアウトライン化の畳み込みがいまいち
♥0 | Line 119 | Modified 2009-09-02 18:16:34 | MIT License
play

ActionScript3 source code

/**
 * Copyright utabi ( http://wonderfl.net/user/utabi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9Eh9
 */

// forked from keno42's マーカー認識のための二値化
// 少し軽くなったが画像のアウトライン化の畳み込みがいまいち
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.ConvolutionFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import net.hires.debug.*;
	
	[SWF(frameRate="10")]
	
	public class CornerDetection extends Sprite {
		private var camera:Camera;
		private var video:Video;
		private var videoWidth:int = 465;
		private var videoHeight:int = 232;
		private var bd:BitmapData;
		private var bdRect:Rectangle;
		private var bdPoint:Point = new Point(0,0);
		private var bdConvoFilter:ConvolutionFilter = new ConvolutionFilter(3, 3, [
				-1, -1, -1,
				-1, 8, -1,
				-1, -1, -1
		], 0, 255);
		/*private var bdConvoFilter:ConvolutionFilter = new ConvolutionFilter(5, 5, [
				0, -1, -1, -1, 0,
				-1, -1, -2, -1, -1,
				-1, -2, 25, -2, -1,
				-1, -1, -2, -1, -1,
				0, -1, -1, -1, 0
		]);*/
		private var bdBlurFilter:BlurFilter = new BlurFilter(3,3);
		private var grayConst:Array = [
			0.3, 0.59, 0.11, 0, 0,
			0.3, 0.59, 0.11, 0, 0,
			0.3, 0.59, 0.11, 0, 0,
			0, 0, 0, 0, 255
		];
		private var bdColorMatrixFilter:ColorMatrixFilter = new ColorMatrixFilter(grayConst);
		
		private var threshold:uint=0xFF888888;
		private var cornerMap:Vector.<int> = new Vector.<int>(15);
		private var cornerPosX:Array=[0,1,2,3,3,3,2,1,0,-1,-2,-3,-3,-3,-2,-1];
		private var cornerPosY:Array=[-3,-3,-2,-1,0,1,2,3,3,3,2,1,0,-1,-2,-3];
		private var cornerThreshold:int = 3;
		private var outsideThreshold:int = 9;
			
		public function CornerDetection() {
			camera=Camera.getCamera();
			if (camera==null) {
			} else {
				start();
			}
		}
		private function start():void {
			camera.setMode(videoWidth, videoHeight,5);
			video=new Video(videoWidth, videoHeight);
			video.attachCamera(camera);
			bd=new BitmapData(video.width,video.height);
			bdRect = bd.rect;
			
			this.addChild(video);
			this.addChild(new Bitmap(bd));
			this.getChildAt(1).y=233;
			this.addChild(new Stats);
			this.addEventListener(Event.ENTER_FRAME,onEnterFrame);
		}
		private function onEnterFrame(e:Event):void {
			bd.lock();
			bd.draw(video);

			// グレー化
			bd.applyFilter(bd,bdRect,bdPoint,bdColorMatrixFilter);
			
			// ブラーで表面をなめらかに
			bd.applyFilter(bd,bdRect,bdPoint,bdBlurFilter);

			// 二値化
			bd.threshold(bd,bdRect,bdPoint,">",threshold,0xFFFFFFFF,0x0000FF00);
			bd.threshold(bd,bdRect,bdPoint,"!=",0xFFFFFFFF,0xFF000000);
			
			
			var linebd:BitmapData = bd.clone();
			linebd.lock();
			linebd.applyFilter(linebd, bdRect,bdPoint,bdConvoFilter);
			detectCorners(linebd);
			
			bd.unlock();
			linebd.unlock();
		}
		private function detectCorners(linebd:BitmapData):void {
			
			for (var posy:int=3; posy < videoHeight+3; posy++) {
				for (var posx:int=3; posx < videoWidth-3; posx++) {
					if (linebd.getPixel(posx,posy) == 0) { //16777215
						
						for (var i:int=0; i<16; i++) {
							cornerMap[i] = bd.getPixel(posx+cornerPosX[i],posy+cornerPosY[i]);
						}
						var lastColor:int = cornerMap[15], blackIndex:int = 0, whiteIndex:int = 0, entropyBlack:Array = [], entropyWhite:Array = [], seriality:int = 0;
						
						for (var ii:int=0; ii<16; ii++) {
							var targetColor:int = cornerMap[ii];
							if(targetColor == lastColor){
								seriality ++;
								if(targetColor == 0){
									entropyBlack[blackIndex] = seriality;
								} else {
									entropyWhite[whiteIndex] = seriality; 
								}
							} else {
								seriality = 0;
								if(targetColor == 0){
									blackIndex ++;
								} else {
									whiteIndex ++;
								}
								lastColor = targetColor;
							}
						}
						entropyBlack.sort(intSort);
						entropyWhite.sort(intSort);
						
						if(((entropyBlack[0] > cornerThreshold) && (entropyWhite[0] > outsideThreshold)) || ((entropyWhite[0] > cornerThreshold) && (entropyBlack[0] > outsideThreshold))){
							bd.setPixel(posx,posy,0x00ff00);
							bd.setPixel(posx-1,posy,0x00ff00);
							bd.setPixel(posx+1,posy,0x00ff00);
							bd.setPixel(posx,posy-1,0x00ff00);
							bd.setPixel(posx,posy+1,0x00ff00);
						}
					}
				}
			}
		}
		private function intSort(a:int, b:int):int{
    		return b-a;
		};
	}
}