この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
こんにちは。
KBMJの佐藤です。
今回はActionScript3.0を使って、
Webカメラからの入力動画に対して2値化を行ってみます。
ソースコード
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で様々な画像処理を紹介していきたいと思います。
お楽しみに!
個人ブログ 拡張現実ライフ