Javascript画像処理の構想と実現コード

4413 ワード

構想
HTML 5のcanvasはgetImageDataインタフェースを提供してcanvasのデータを取得するので、drawImageインタフェースで画像をcanvasに描いてからgetImageDataで画像データマトリクスを得ることができます.
なお、IE 9はcanvasインタフェースをサポートし始めているが、getImageDataが取得したデータは標準的なTypedArray方式で格納されているわけではない、あるいは、IE 9はWebGL Native binary dataのサポートを提供していないため、IE 9のサポートが必要な場合、以下のマトリクスはArray方式で保存する必要がある.IE 9の次のバージョン(例えばIE 8)では、オープンソースプロジェクトexplorercanvasがcanvasサポートを提供していますが、残念ながらG_vmlCanvasManagerは、ビットマップデータ取得インタフェースを提供していません.TypedArrayの関連コンテンツはHTML 5の新しい配列を参照できます
きほんマトリクス
画像処理ではマトリクス計算が非常に重要な内容であるため,まずマトリクスモデルを構築する.
getImageDataインタフェースで取得したImageDataはマトリクスのような構造を持っていますが、彼の構造は可変で拡張には向いていないので、Javascriptでマトリクスを作成することを選択しました.
 
  
function Mat(__row, __col, __data, __buffer){
this.row = __row || 0;
this.col = __col || 0;
this.channel = 4;
this.buffer = __buffer || new ArrayBuffer(__row * __col * 4);
this.data = new Uint8ClampedArray(this.buffer);
__data && this.data.set(__data);
this.bytes = 1;
this.type = "CV_RGBA";
}

row-マトリクスを表す行数
col-マトリクスを表す列数
channel-getImageDataによって取得されたピクチャデータは、Red(赤)、Green(緑)、Blue(青)、Alpha(不透明度)の4つのチャネルで記述されるため、チャネル数を表します.
buffer-データに使用されるArrayBufferリファレンス.
data-ピクチャのUIT 8 ClampedArray配列データ.
bytes-uint 8データ型であるため、データ単位当たりのバイト数は1です.
type-データ型はCV_RGBA.
ピクチャデータをマトリクスに変換する方法
 
  
function imread(__image){
var width = __image.width,
height = __image.height;
iResize(width, height);
iCtx.drawImage(__image, 0, 0);
var imageData = iCtx.getImageData(0, 0, width, height),
tempMat = new Mat(height, width, imageData.data);
imageData = null;
iCtx.clearRect(0, 0, width, height);
return tempMat;
}

注意:ここの_イメージとはイメージオブジェクトを指し、文字列URLではありません.ブラウザでのImageの読み込みは非同期プロセスであり、対応するMatオブジェクトをすぐに返すことはできませんので、この関数は次のように使用します.
 
  
var img = new Image();
img.onload = function(){
var myMat = cv.imread(img);
};
img.src = "1.jpg";

iCtxメソッドとiResizeメソッドは、他の関数に共通化できるグローバル変数です.
 
  
var iCanvas = document.createElement("canvas"),
iCtx = iCanvas.getContext("2d");
function iResize(__width, __height){
iCanvas.width = __width;
iCanvas.height = __height;
}

drawImageの方法を見てみましょう.
用途
canvasに画像を描きます.
構文
context.drawImage(img,x,y);
context.drawImage(img,x,y,width,height);
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

getImageDataメソッドもあります.
用途
canvasの画像データを取得します.
データはRGBA色空間で返されます.
R-赤色チャネルサイズ
G-緑のチャネルサイズ
B-青チャンネルサイズ
A-不透明度の大きさ
構文
context.getImageData(x,y,width,height);
 
  
red = imgData.data[0];
green = imgData.data[1];
blue = imgData.data[2];
alpha = imgData.data[3];

マトリクスを画像データに変換する方法
処理されたマトリクスは、ImageDataになる方法が必要で、putImageData法でcanvas上に処理された画像を描くことができます.
 
  
function RGBA2ImageData(__imgMat){
var width = __imgMat.col,
height = __imgMat.row,
imageData = iCtx.createImageData(width, height);
imageData.data.set(__imgMat.data);
return imageData;
}

putImageDataメソッドを見てみましょう.
用途
画像データからcanvasに画像を描画します.
構文
context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
カラーマップをグレースケールマップに変換
最後に,RGBAからGRAYに画像を変換する簡単な色空間変換を行った.
 
  
function cvtColor(__src){
if(__src.type && __src.type === "CV_RGBA"){
var row = __src.row,
col = __src.col;
var dst = new Mat(row, col);
data = dst.data,
data2 = __src.data;
var pix1, pix2, pix = __src.row * __src.col * 4;
while (pix){
data[pix -= 4] = data[pix1 = pix + 1] = data[pix2 = pix + 2] = (data2[pix] * 299 + data2[pix1] * 587 + data2[pix2] * 114) / 1000;
data[pix + 3] = data2[pix + 3];
}
}else{
return src;
}
return dst;
}

OpenCVドキュメントの変換式を参照してください.
RGBA to Gray:Y Gray to RGBA:R RGBA to GRAY(4つのチャネルを持つことを指す)対応するマッピング関係は、次のようになります.
RGBA to RGBA(GRAY): R1 = G1 = B1