ホーム DoRuby Webカメラからの入力動画に対してActionScriptで2値化を行う

Webカメラからの入力動画に対してActionScriptで2値化を行う

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

こんにちは。

KBMJの佐藤です。

今回はActionScript3.0を使って、

Webカメラからの入力動画に対して2値化を行ってみます。

http://farm3.static.flickr.com/2284/2983782725_3acc71f952.jpg

ソースコード

package{
    import flash.display.*;
    import flash.events.*;
    import flash.media.*;
    import flash.system.*;
    import flash.text.*;
    import flash.geom.*;
    import flash.filters.*;

    [SWF(width="640", height="480")]

    public class Threshold2 extends Sprite {
	private var video:Video;
	private var camera:Camera;
	private var msg:String;
	public var txtArea:TextField = new TextField();
	public var bdTmp:BitmapData;
	public var bmp:Bitmap;

	public function Threshold2()
	{
	    stage.scaleMode = StageScaleMode.NO_SCALE;
	    stage.align = StageAlign.TOP_LEFT;

	    // (1)
	    camera = Camera.getCamera();
	    if(camera != null){
		camera.addEventListener(StatusEvent.STATUS, statusHandler);
		camera.setMode(640, 480, 15);
		camera.setMotionLevel(10);
		camera.setQuality(0, 50);

		// (2)
		video = new Video(camera.width, camera.height);
		video.attachCamera(camera);

		addEventListener(Event.ENTER_FRAME, tick);
	    }else{
		msg = "使用可能なカメラがありません。";
		txtArea.text = msg;
	    }

	    txtArea.autoSize = TextFieldAutoSize.LEFT;
	    txtArea.text = "Threshold";
	    txtArea.textColor = 0xffffff;
	    txtArea.x = 2;
	    txtArea.y = this.height - txtArea.textHeight - 10;
	    this.addChild(txtArea);

	    // (3)
	    bdTmp = new BitmapData(video.width, video.height, false, 0xffffff);
	    bmp = new Bitmap(bdTmp);
	    this.addChild(bmp);
	}

	private function statusHandler(evt:StatusEvent):void{
	    if(camera.muted){
		msg = "カメラへのアクセスが拒否されました。";
		msg += "カメラの映像を表示するにはアクセスを許可してください。";
		txtArea.text = msg;
		Security.showSettings(SecurityPanel.PRIVACY);
	    }else{
		msg = "使用中のカメラ : " + camera.name + "\n";
		msg += "幅x高さ : " + camera.width + "x" + camera.width;
		txtArea.text = msg;
	    }
	}

	private function tick(event:Event):void{
	    if(video == null || camera == null){
		return;
	    }
	    if(camera.muted == true){
		return;
	    }
	    // (4)
	    var s:BitmapData = new BitmapData(video.width, video.height);
	    s.draw(video);

	    // (5)
	    var r:Rectangle = new Rectangle(0, 0, video.width, video.height);
	    bdTmp.fillRect(r, 0xffffffff);

	    // (6)
	    var threshold:uint = 0x00800000;
	    var color:uint = 0x00000000;
	    var maskColor:uint = 0x00ff0000;
	    bdTmp.threshold(s, r, new Point(0, 0), "<=", threshold, color, maskColor, false);
	}
    }
}

コード解説(1)

camera = Camera.getCamera();

Webカメラに対して各種操作の行えるCameraオブジェクトを取得します。

コード解説(2)

video = new Video(camera.width, camera.height);
video.attachCamera(camera);

Webカメラからの入力映像をVideoオブジェクトに流し込みます。

コード解説(3)

bdTmp = new BitmapData(video.width, video.height, false, 0xffffff);
bmp = new Bitmap(bdTmp);
this.addChild(bmp);

画像操作用のバッファとしてBitmapDataオブジェクトを作成し、

Bitmapオブジェクトに関連づけて、画面に表示します。

コード解説(4)

var s:BitmapData = new BitmapData(video.width, video.height);
s.draw(video);

Webカメラからの入力をBitmapDataオブジェクトにコピーします。

コード解説(5)

var r:Rectangle = new Rectangle(0, 0, video.width, video.height);
bdTmp.fillRect(r, 0xffffffff);

処理対象の矩形をRectangleオブジェクトとして作成し、

BitmapDataオブジェクトの内容を白でクリアします。

コード解説(6)

var threshold:uint = 0x00800000;
var color:uint = 0x00000000;
var maskColor:uint = 0x00ff0000;
bdTmp.threshold(s, r, new Point(0, 0), "<=", threshold, color, maskColor, false);

thresholdメソッドを用いて2値化を行います。

対象のカラー要素をmaskColor(0x0ff0000)によって抽出し、

閾値threshold(0x00800000)より大きい場合は

ピクセル値color(0x00000000)に設定します。

さいごに

2値化には様々な方法があるのですが、

この記事では非常に簡単な方法を用いました。

ヒストグラムなどを作成した上でそれを元に2値化を行えば

より良い処理結果を得ることができます。

次回以降もActionScriptで様々な画像処理を紹介していきたいと思います。

お楽しみに!

個人ブログ 拡張現実ライフ

記事を共有

最近人気な記事