forked from: Corner Detection [少し軽くなった]
forked from Corner Detection [すんげー重い] (diff: 69)
少し軽くなったが画像のアウトライン化の畳み込みがいまいち
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;
};
}
}
