Corner Detection [すんげー重い]

by utabi forked from マーカー認識のための二値化 (diff: 84)
♥2 | Line 113 | Modified 2009-09-02 13:23:01 | 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/pnxK
 */

// 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.media.Camera;
	import flash.media.Video;
	import net.hires.debug.*;
	
	[SWF(frameRate="5")]
	
	public class CornerDetection extends Sprite {
		private var camera:Camera;
		private var video:Video;
		private var bd:BitmapData;
		private var threshold:uint=0xFF888888;
		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 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 = 5;
		private var outsideThreshold:int = 9;
		
		public function CornerDetection() {
			camera=Camera.getCamera();
			if (camera==null) {
			} else {
				start();
			}
		}
		private function start():void {
			camera.setMode(232, 116,5);
			video=new Video(232, 116);
			video.attachCamera(camera);
			bd=new BitmapData(video.width,video.height);
			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,bd.rect,new Point  ,new ColorMatrixFilter(grayConst));
			bd.applyFilter(bd, bd.rect, new Point(), 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
			]));
			bd.applyFilter(bd,bd.rect,new Point  ,new BlurFilter(3,3));

			// 二値化
			bd.threshold(bd,bd.rect,new Point  ,">",threshold,0xFFFFFFFF,0x0000FF00);
			bd.threshold(bd,bd.rect,new Point  ,"!=",0xFFFFFFFF,0xFF000000);
                        bd.unlock();
			detectCorners();
		}
		
		private function detectCorners():void {
			
			for (var posy:int=3; posy < bd.height+3; posy++) {
				for (var posx:int=3; posx < bd.width-3; posx++) {
					if (bd.getPixel(posx,posy) == 16777215) {
						var cornerMap:Vector.<int> = new Vector.<int>(15);
						for (var i:int=0; i<16; i++) {
							cornerMap[i] = bd.getPixel(posx+cornerPosX[i],posy+cornerPosY[i]);
						}
						var lastColor:int = cornerMap[15];
						var blackIndex:int = 0;
						var whiteIndex:int = 0;
						var entropyBlack:Array = [];
						var entropyWhite:Array = [];
						var seriality:int = 0;
						
						for (var ii:int=0; ii<16; ii++) {
							if(cornerMap[ii] == lastColor){
								seriality ++;
								if(cornerMap[ii] == 0){
									entropyBlack[blackIndex] = seriality;
								} else {
									entropyWhite[whiteIndex] = seriality; 
								}
							} else {
								seriality = 0;
								if(cornerMap[ii] == 0){
									blackIndex ++;
								} else {
									whiteIndex ++;
								}
								lastColor = cornerMap[ii];
							}
						}
						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;
		};
	}
}

Forked