概要
Robertsフィルタを使用して画像のエッジ検出をしてみましょう。
var filterY:Array =
[[0, 0, 0],
[0, 1, 0],
[0, 0, -1]];
var filterX:Array =
[[ 0, 0, 0],
[ 0, 0, 1],
[ 0, -1, 0]];
Robertsフィルタでは交差させるように差分を取ります。
グレイスケール、二値化
プログラム
画像の読み込み
画像の読み込み方法については、画像処理用のテンプレートを参照してください。
エッジ検出(Robertsフィルタ版)
private function edgeDetection(bd:BitmapData):BitmapData
{
var dest:BitmapData = bd.clone();
var color:ColorRGB = new ColorRGB();
var filterY:Array =
[[0, 0, 0],
[0, 1, 0],
[0, 0, -1]];
var filterX:Array =
[[ 0, 0, 0],
[ 0, 0, 1],
[ 0, -1, 0]];
for (var y:int = 0; y < bd.height; y++)
{
for (var x:int = 0; x < bd.width; x++)
{
var redX:int = 0, greenX:int = 0, blueX:int = 0;
var redY:int = 0, greenY:int = 0, blueY:int = 0;
for (var yy:int = -1; yy <= 1; yy++)
{
for (var xx:int = -1; xx <= 1; xx++)
{
if (x + xx < 0 || bd.width <= x + xx ||
y + yy < 0 || bd.height <= y + yy) continue;
color.value = bd.getPixel(x + xx, y + yy);
redX += color.r * filterX[yy + 1][xx + 1];
greenX += color.g * filterX[yy + 1][xx + 1];
blueX += color.b * filterX[yy + 1][xx + 1];
redY += color.r * filterY[yy + 1][xx + 1];
greenY += color.g * filterY[yy + 1][xx + 1];
blueY += color.b * filterY[yy + 1][xx + 1];
}
}
color.r = Math.sqrt(redX * redX + redY * redY);
color.g = Math.sqrt(greenX * greenX + greenY * greenY);
color.b = Math.sqrt(blueX * blueX + blueY * blueY);
dest.setPixel(x, y, color.value);
}
}
return dest;
}
全体のコードはこのようになります。
検証用コード
package
{
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.system.Security;
import flash.filters.ConvolutionFilter;
import flash.filters.ColorMatrixFilter;
import frocessing.color.ColorRGB;
public class Main extends Sprite
{
private const WIDTH:int = 250; // 幅
private const HEIGHT:int = 250; // 高さ
public function Main()
{
stage.scaleMode = "noScale";
Security.loadPolicyFile("http://farm3.static.flickr.com/crossdomain.xml");
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, initHandler);
loader.load(new URLRequest("http://farm4.static.flickr.com/3340/3482832404_5cc678c11e.jpg"), new LoaderContext(true)); // 読み込みたい画像URL
}
private function initHandler(event:Event):void
{
var loader:Loader = event.currentTarget.loader;
var matrix:Matrix = new Matrix();
matrix.scale(WIDTH / loader.width, HEIGHT / loader.height); // 設定したいサイズ / 元サイズ
var bd:BitmapData = new BitmapData(WIDTH, HEIGHT); // 設定したいサイズ
bd.draw(loader, matrix);
addChild(new Bitmap(edgeDetection(bd)));
}
private function edgeDetection(bd:BitmapData):BitmapData
{
var dest:BitmapData = bd.clone();
var color:ColorRGB = new ColorRGB();
var filterY:Array =
[[0, 0, 0],
[0, 1, 0],
[0, 0, -1]];
var filterX:Array =
[[ 0, 0, 0],
[ 0, 0, 1],
[ 0, -1, 0]];
for (var y:int = 0; y < bd.height; y++)
{
for (var x:int = 0; x < bd.width; x++)
{
var redX:int = 0, greenX:int = 0, blueX:int = 0;
var redY:int = 0, greenY:int = 0, blueY:int = 0;
for (var yy:int = -1; yy <= 1; yy++)
{
for (var xx:int = -1; xx <= 1; xx++)
{
if (x + xx < 0 || bd.width <= x + xx ||
y + yy < 0 || bd.height <= y + yy) continue;
color.value = bd.getPixel(x + xx, y + yy);
redX += color.r * filterX[yy + 1][xx + 1];
greenX += color.g * filterX[yy + 1][xx + 1];
blueX += color.b * filterX[yy + 1][xx + 1];
redY += color.r * filterY[yy + 1][xx + 1];
greenY += color.g * filterY[yy + 1][xx + 1];
blueY += color.b * filterY[yy + 1][xx + 1];
}
}
color.r = Math.sqrt(redX * redX + redY * redY);
color.g = Math.sqrt(greenX * greenX + greenY * greenY);
color.b = Math.sqrt(blueX * blueX + blueY * blueY);
dest.setPixel(x, y, color.value);
}
}
return dest;
}
}
}
このwikiの更新情報RSS