トップページ > 画像処理 > 画像のエッジ検出(Robertsフィルタ編)



概要

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フィルタでは交差させるように差分を取ります。


グレイスケール、二値化

Prewitt, Sobelフィルタと同じように、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;
		}
	}
}
 

|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|
添付ファイル