html5のcanvasのピクセル単位の処理を試してみた。ここで動かせる → http://dev.shokai.org/test/canvas/cv/

ソースはここ https://github.com/shokai/js-canvas-test/tree/master/cv


輪郭抽出とかしてみた
html5 canvas edge detect


■canvasでのピクセル処理方法
canvasはgetContext(‘2d’)してからgetImageDataするとImageDataオブジェクトが手に入る。
あとの処理はこんな感じ(画像をグレースケールにする例、cv/main.jsの39行目あたり

var canvas = $('canvas#img');
var ctx = canvas[0].getContext('2d');

var img = ctx.getImageData(0, 0, canvas[0].width, canvas[0].height);
for(var i = 0; i < img.data.length; i+=4){
var r = img.data[i]&0xFF;
var g = img.data[i+1]&0xFF;
var b = img.data[i+2]&0xFF;
// var a = img.data[i+3]&0xFF;
var gray = (r+g+b)/3;
img.data[i] = gray;
img.data[i+1] = gray;
img.data[i+2] = gray;
}
ctx.putImageData(img, 0, 0);
データが1次元配列になっていて、RGBAの順に値が格納されている。なのでImageData.dataの要素数はピクセル数の4倍になる。
x,y座標でデータを取れる関数が無いので、自分で色々試して作ってみたけどどうしても3〜6倍ぐらい遅くなってしまうので1次元配列のまま扱う事にした。
JavaScriptで多値を扱うには配列やオブジェクトを使わなければならないんだけどどうやらそれらの生成コストがかなり高いらしく、1ピクセルずつ処理したらひどく遅くなった。


■クロスドメイン
別ドメインの画像をcanvasに読み込んで、getImageDataはできない。chromeだと “Uncaught Error: SECURITY_ERR: DOM Exception 18” というエラーが開発パネルに出る。
ローカルでの開発時にローカルのhtmlからローカルの画像を読み込んでgetImageDataしてもこのセキュリティエラーが出るので、rubyで簡単なhttpサーバーを作っておいたのでコレ使うといい。
実行するとそのディレクトリでhttpサーバーが起動する。


■実行速度
端末によって実行速度が違う。

下の画像は、今年の2月に買った11インチMacbook Airのchromeで、1000×1000の画像を4段階量子化したところ。
だいたい50ミリ秒で量子化できた。遅いパソコンでも毎秒数回は実行できそう。
iPodTouch 4Gや初代iPadはMacbook Airより30倍ぐらい遅くて2秒弱かかる。Nexus Sが意外なことに更に遅くて25秒ぐらいかかる。Macの500倍遅い。
html5 canvas qunatize