ラベリング
http://www.microsoft.com/japan/msdn/academic/Articles/Algorithm/03/
これ使用
ImageProcessing.prototype.f= function(fnc){ return fnc(this); }; var ip = ImageProcessing.load("img.png"); // ImageDataを使用した方が速い ip.support.pixel = false; ip.initPixelControl(); var labels = []; var fil = 0; // ラベリングする色 ip.lock() // 閾値処理 .f(function(self){ var t = self.average().average(); //var t = (self.max().max() - self.min().min()) / 2; // 中央値 return self.each(function(px, x, y){ var c = px.average(); px = new ImageProcessing.Color(c, c, c); self.setPixel(x, y, px.threshold(t)); }); }) // ラベリング (4近傍) .f(function(self){ var labelN = 1; // label number var w = self.canvas.width; var h = self.canvas.height; for(var x = 0; x < w + 1; x++) labels.push([]); var setLabel = function(x, y, num){ if(0 > x || x >= w || 0 > y || y >= h || typeof labels[x][y] != "undefined") return; // 4近傍 var nb = [ [x + 1, y , num], [x - 1, y , num], [x , y - 1, num], [x , y + 1, num] ]; // 4近傍をチェック if(self.getPixel(x, y).r == fil){ labels[x][y] = num; nb.forEach(function(args){ setLabel.apply(null, args); }); } else labels[x][y] = 0; }; return self.each(function(px, x, y){ if(px.r != fil) labels[x][y] = 0; else setLabel(x, y, labelN++); }); }) // ラベルの番号が何故か変なので直す .f(function(self){ var labelN = 1; var labelNs = []; labels.forEach(function(_, x){ _.forEach(function(v, y){ if(v > 0 && !labelNs[v]) labelNs[v] = labelN++; labels[x][y] = labelNs[v]; }) }) return self; }) // 表示 .f(function(self){ var colors = [ ImageProcessing.Color.fromHex(0xff0000), ImageProcessing.Color.fromHex(0x00ff00), ImageProcessing.Color.fromHex(0x0000ff), ImageProcessing.Color.fromHex(0xffcc00), ImageProcessing.Color.fromHex(0xcc00ff), ImageProcessing.Color.fromHex(0x00ffcc), ]; labels.forEach(function(_, x){ _.forEach(function(n, y){ if(0 < n){ self.setPixel(x, y, colors[n % colors.length]); } }); }); return self; }) .unlock() .update();
エッジ処理 - 閾値処理 - ラベリング
あんまり連続でラベリングする範囲が広いと「too much recursion」と言われてしまう。タイマー使うといいのかな。