hough transform

by wh0
♥0 | Line 124 | Modified 2010-10-25 14:01:51 | MIT License
play

ActionScript3 source code

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

package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.media.*;
    
    import com.actionscriptbible.Example;
    [SWF(frameRate=4)]
    public class HoughMoney extends Sprite {
        
        private var w:int;
        private var h:int;
        private var cam:Camera;
        private var vidContainer:Sprite;
        private var img:BitmapData;
        private var edge:BitmapData;
        private var out:BitmapData;
        private var found:Graphics;
        
        public function HoughMoney() {
            Wonderfl.disable_capture();
            
            w = stage.stageWidth / 2;
            h = stage.stageHeight / 2;
            
            img = new BitmapData(w, h, false);
            addChild(new Bitmap(img)).x = w;
            edge = new BitmapData(w, h, false);
            with(addChild(new Bitmap(edge))) { x = w; y = h; }
            out = new BitmapData(w, h, false);
            addChild(new Bitmap(out)).y = h;
            var foundShape:Shape = new Shape();
            addChild(foundShape).x = w;
            found = foundShape.graphics;
            
            cam = Camera.getCamera();
            if (cam == null) {
                // uh-oh
            } else {
                cam.setMode(w, h, stage.frameRate, false);
                cam.addEventListener(StatusEvent.STATUS, camStatus);
                var vid:Video = new Video();
                vid.width = w;
                vid.height = h;
                vid.attachCamera(cam);
                vidContainer = new Sprite();
                vidContainer.addChild(vid);
                addChild(vidContainer);
            }
        }
        /*
        private function drawCircles():void {
            var shape:Shape = new Shape();
            shape.graphics.beginFill(0x000000);
            shape.graphics.drawRect(0, 0, img.width, img.height);
            shape.graphics.endFill();
            shape.graphics.lineStyle(1, 0xffffff);
            var r:int = 20;
            for (var rr:int = 0; rr < 20; rr++)
                shape.graphics.drawCircle(
                    Math.random() * (img.width - 2 * r) + r,
                    Math.random() * (img.height - 2 * r) + r,
                    r
                );
            edge.draw(shape);
            edge.colorTransform(edge.rect, new ColorTransform(
                1./64, 1./64, 1./64
            ));
        }
        */
        private function camStatus(e:StatusEvent):void {
            if (e.code != 'Camera.Unmuted')
                return;
            stage.addEventListener(Event.ENTER_FRAME, capture);
        }
        
        private function capture(e:Event=null):void {
            found.clear();
            img.draw(vidContainer);
            
            highpass();
            hough(20);
            search(20, 0xff0000);
        }
        
        private function highpass():void {
            edge.applyFilter(img, img.rect, new Point(), new ConvolutionFilter(
                3, 3,
                [ 0, -1,  0,
                 -1,  4, -1,
                  0, -1,  0],
                1
            ));
            edge.applyFilter(edge, edge.rect, new Point(), new ColorMatrixFilter(
                [0.5, 0.5, 0.5, 0.0, 0.0,
                 0.5, 0.5, 0.5, 0.0, 0.0,
                 0.5, 0.5, 0.5, 0.0, 0.0,
                 0.0, 0.0, 0.0, 1.0, 0.0]
            ));
            edge.colorTransform(edge.rect, new ColorTransform(
                1./32, 1./32, 1./32
            ));
            img.colorTransform(edge.rect, new ColorTransform(
                0.5, 0.5, 0.5
            ));
        }
              
        private function hough(radius:int):void {
            out.fillRect(out.rect, 0xff000000);
            out.lock();
            for (var i:int = 0; i < 64; i++)
                out.draw(edge, new Matrix(1, 0, 0, 1,
                    radius * Math.cos(2 * Math.PI * i / 64),
                    radius * Math.sin(2 * Math.PI * i / 64)
                ), null, BlendMode.ADD);
            out.unlock();
        }
        
        private function search(radius:int, color:uint):int {
            var grid:int = radius / Math.SQRT2;
            var total:int = 0;
            for (var y:int = 0; y < h; y++) {
                for (var x:int = 0; x < w; x++) {
                    var v:int = out.getPixel(x, y) & 0xff;
                    if (v > 64) {
                        var left:int = Math.max(0, x - grid);
                        var right:int = Math.min(w, x + grid);
                        var bottom:int = Math.min(h, y + grid);
                        var mx:int = x;
                        var my:int = y;
                        var mv:int = v;
                        for (var iy:int = y; iy < bottom; iy++) {
                            for (var ix:int = left; ix < right; ix++) {
                                var iv:int = out.getPixel(ix, iy) & 0xff;
                                if (iv > mv) {
                                    mx = ix;
                                    my = iy;
                                    mv = iv;
                                }
                            }
                        }
                        out.fillRect(
                            new Rectangle(mx - grid, my - grid, grid * 2, grid * 2),
                            0x000000
                        );
                        found.lineStyle(1, color);
                        found.drawCircle(mx, my, radius);
                        if (++total > 100) return total;
                    }
                }
            }
            return total;
        }
        
    }
}