HTML5 + JavaScriptで画像処理 (エッジ検出)

古籏一浩のJavaScriptラボ ― 第14回 HTML5のcanvasで作る画像フィルター
を読んで、Canvasで画像の輝度値を編集できることを知ったので、ためしに実装してみることに。
GUIや画像の端の処理などかなり手抜きだが、FirefoxGoogle ChromeOperaで動作することを確認した。
処理はかなり重く、私の非力なマシンは実行するたび悲痛なファンの音を上げるほどである。。。でもしょうがないよね(´・ ω・`)
ちなみに3種類のブラウザで最も実行速度が早かったブラウザはOperaであり、もっとも遅いブラウザはFireFoxだった。

HTML5 + JavaScriptによるエッジ検出
http://jstap.web.fc2.com/test/html5/filtering/filtering.html

実行結果

ソースコード
2011/04/24追記
以下は古いソースコードです。最新は https://github.com/kojo-sugita/Image-filtering をご覧ください。

HTML

<p><b>オリジナル画像</b></p>
<img src="./lena.png"></img>
<br>
<input type="button" name="edge" value="エッジ検出" onClick="EdgeDetector()">
<br>
<p><b>エッジ画像</b></p>
<img src="./lena.png" style="display: none">
<canvas id="myCanvas" width="256" height="256">canvasに対応したブラウザーで実行してください</canvas>

JavaScript

/**
 * エッジ検出
 */
function EdgeDetector() {
  var _canvasW = 256; // 横幅256ピクセル
  var _canvasH = 256; // 縦幅256ピクセル
  var canvas = document.getElementById("myCanvas");
  var context = canvas.getContext("2d");
  var imgObj = new Image(_canvasW, _canvasH);
  imgObj.src = "http://jstap.web.fc2.com/test/html5/edge/lena.png";
  context.drawImage(imgObj, 0, 0);

  var grayImage = new Array(_canvasW * _canvasH);

  for(var y = 0; y < _canvasH; y++){
    for(var x = 0; x < _canvasW; x++){
      var pixelData = getPixel(canvas, x, y, _canvasW, _canvasH); // ピクセル値を取得する
      var R = pixelData.R;
      var G = pixelData.G;
      var B = pixelData.B;

      // グレースケール化
      grayImage[y * _canvasW + x] = ToGrayscale(R, G, B);
    }
  }

  /* Sobelフィルタ */
  var filter = new Array();
  filter[0] = 1; filter[1] = 0; filter[2] = -1;
  filter[3] = 1; filter[4] = 0; filter[5] = -1;
  filter[6] = 1; filter[7] = 0; filter[8] = -1;

  /* 空間フィルタリング */
  var resultImage = SpatialFiltering(grayImage, _canvasH, _canvasW, filter, 3);

  /* セット */
  for (var y = 0; y < _canvasH; y++) {
    for (var x = 0; x < _canvasW; x++) {
      var I = resultImage[y * _canvasW + x];
      setPixel(canvas, x, y, I, I, I, 255, _canvasW, _canvasH);
    }
  }
}

/**
 * 空間フィルタリング
 */
function SpatialFiltering(grayImage, height, width, filter, size_f) {

  var init = Math.floor(size_f / 2);
  var from = - init;
  var to = init;
  
  var resultImage = new Array(height * width);

  for (var k = 0; k < resultImage.length; k++) {
    resultImage[k] = 0;
  }

  for  (var i = init; i < height - init; i++) {
    for (var j = init; j < width - init; j++) {
      var sum = 0.0;
      /* フィルタリング */
      for (var n = from; n <= to; n++) {
        for (var m = from; m <= to; m++) {
          sum += grayImage[(i + n) * width + j + m] * 
            filter[(n + init) * size_f + m + init];
        }
      }
      resultImage[i * width + j] = Math.floor(Math.abs(sum));
    }
  }
  return resultImage;
}

/**
 * RBGをグレースケールにして返する
 */
function ToGrayscale(R, G, B) {
  R = Math.floor(R * 0.299);
  G = Math.floor(G * 0.587);
  B = Math.floor(B * 0.114);
  return R + G + B;
}

// GetPixel
// 戻り値はオブジェクトのプロパティでR,G,B
function getPixel(srcCanvas, x, y, canvasW, canvasH){
  if (window.opera) {
    var gContext = srcCanvas.getContext("opera-2dgame");
    var rgbStr = gContext.getPixel(x, y); // ピクセル値を取得する
    var R = eval("0x"+rgbStr.substring(1,3));
    var G = eval("0x"+rgbStr.substring(3,5));
    var B = eval("0x"+rgbStr.substring(5,7));
    return {R:R, G:G, B:B};
  }

  var imagePixelData = srcCanvas.getContext("2d").getImageData(x, y, 1, 1).data;
  var R = imagePixelData[0];
  var G = imagePixelData[1];
  var B = imagePixelData[2];
  return {R:R, G:G, B:B};
}

// SetPixel
function setPixel(srcCanvas, x, y, R, G, B, A, canvasW, canvasH){
  if (window.opera) {
    var gContext = srcCanvas.getContext("opera-2dgame");
    var rgbaColor = "rgba("+R+","+G+","+B+","+A+")";
    gContext.setPixel(x,y, rgbaColor);
    return;
  }
  var context = srcCanvas.getContext("2d");
  var pixelImage = context.createImageData(1, 1);
  pixelImage.data[0] = R;
  pixelImage.data[1] = G;
  pixelImage.data[2] = B;
  pixelImage.data[3] = A;
  context.putImageData(pixelImage, x, y);
}

HPを移行しました

管理しているHPのURLを変更しました。
ブックマークをしてくださっていた方はお手数ですが、ブックマークの変更をお願いします。


LaTeXコマンド集 - LaTeXのコマンド集。卒論やレポート作成のお供にどうぞ
 新URL http://www.latex-cmd.com/

C tips & reference \n - C言語のTips集とリファレンス集
 新URL http://www.c-tipsref.com/

2月に読んだ本と見た映画

2月は新しい職が決まった月でした。

見た映画

2月の鑑賞メーター
観た本数:7本
観た時間:750分

イエスマン “YES”は人生のパスワード 特別版 [DVD]イエスマン “YES”は人生のパスワード 特別版 [DVD]
典型的なアメリカンコメディで展開も先読みできる。だけど面白い。すべてを肯定するその姿勢は見習うべきところがある。それにしてもズーイー・デシャネルがかわいい。
鑑賞日:02月27日 監督:ペイトン・リード
ストレンジャー・ザン・パラダイス [DVD]ストレンジャー・ザン・パラダイス [DVD]
多分合う合わないがはっきり分かれであろう大きな展開のない雰囲気映画。少なくとも徹夜明けに見る映画じゃなかった。眠い。
鑑賞日:02月26日 監督:ジム・ジャームッシュ
黒猫白猫 [DVD]黒猫白猫 [DVD]
至高のコメディ。文句のつけようがない。 にぎやかな東欧のノリが最初から最後まで続き一度も映画のテンションが下がらない。 先読み可能な一本筋のストーリーではあるものの、中弛みせず、始終見ている側を楽しい気分にさせてくれる。 登場人物全員が生き生きとしていて魅力的なところもすごい。
鑑賞日:02月23日 監督:エミール・クストリッツァ
デッドマン スペシャル・エディション [DVD]デッドマン スペシャル・エディション [DVD]
雰囲気とジョニデの演技を楽しむ叙事詩的な映画
鑑賞日:02月21日 監督:ジム・ジャームッシュ
ラン・ローラ・ラン [DVD]ラン・ローラ・ラン [DVD]
ローラがひたすら走る映画。スタートからゴールまで3パターンのストーリーが用意されている。ローラ役のフランカ・ポテンテがまったく可愛くない。また、ハイペースで走る描写が多用されるわりにローラの息が全く切れていないなど引っかかる部分も多かったが、映像手法や細かい演出はよい。
鑑賞日:02月21日 監督:トム・ティクバ
いまを生きる [DVD]いまを生きる [DVD]
鑑賞日:02月13日 監督:ピーター・ウィアー
コーヒー&シガレッツ [DVD]コーヒー&シガレッツ [DVD]
鑑賞日:02月11日 監督:ジム・ジャームッシュ

1月に読んだ本と見た映画

読んだ本

1月の読書メーター
読んだ本の数:9冊
読んだページ数:2016ページ

親指の恋人〔文庫〕親指の恋人〔文庫〕
20歳の男女が心中したという既成事実が冒頭に示され、そこに至るまでの詳細なプロセスが全体にわたって書かれている。 作者としては「現代格差社会」と「若者の自殺」をテーマに本作を書いたのだろうが、あまりにも通俗的であり展開も使い古されている。 特に、主人公らの心情変化の表現が乏しいため、どうしても薄っぺらな印象を受けてしまう。石田が片手間に書いた小説に思えてしょうがない。
読了日:01月22日 著者:石田 衣良
当て屋の椿 3 (ジェッツコミックス)当て屋の椿 3 (ジェッツコミックス)
読了日:01月17日 著者:川下 寛次
飛ぶ男飛ぶ男
阿部公房の未完の遺作。未完なため結末を迎えることなく物語が幕を閉じるが、それでも十分楽しめる。
読了日:01月16日 著者:安部 公房
カルプス・アルピスカルプス・アルピス
ご都合主義というかストーリーが少し出来すぎている気がするけど、胸に響く文章がいくつもある。何より作品がまとっている雰囲気が美しい。嶽本野ばらは独特の文体から敬遠する人も多いが、本作はクセも少なく読みやすいので、野ばら嫌いな人にもオススメ。
読了日:01月12日 著者:嶽本 野ばら
灰色のピーターパン―池袋ウエストゲートパーク6 (文春文庫 い 47-10)灰色のピーターパン―池袋ウエストゲートパーク6 (文春文庫 い 47-10)
IWGPシリーズの第6作目。風営法や在留外国人に対しての思想はともかくとして、読みやすく集中して一気に読める一冊。疾走感がよい。それにしてもタカシはいつまでGボーイズのキングをやるつもりなんだろう?
読了日:01月11日 著者:石田 衣良
HUNTER×HUNTER NO.27 (ジャンプコミックス)HUNTER×HUNTER NO.27 (ジャンプコミックス)
読了日:01月11日 著者:冨樫 義博
屍蝋の街屍蝋の街
腐蝕の街の続編である。が、そのことを知らずに本作から読んでしまった・・・近未来クライムアクションとしてよく出来ていると思う。
読了日:01月06日 著者:我孫子 武丸
転職面接必勝法転職面接必勝法
読了日:01月03日 著者:細井 智彦
きつねのはなし (新潮文庫 も 29-2)きつねのはなし (新潮文庫 も 29-2)
京都奇譚集。一話目の表題作は秀逸、二話目もオモチロいのだが三話目以降がいまひとつだった。三話目は物語前中盤の伏線らしき部分を回収しきれておらず、読み終わった後に残尿感を感じた。四話目は構成がぶつ切りで読み難い。太陽の塔や、夜は短し歩けよ乙女も構成面で荒さが目立ったがそれを補うユニークな文章とストーリーの面白さがあった。しかし、本作四話目はそれがない。総評としてはイマイチ。個人的に大好きな作家のため次回作に期待したい。
読了日:01月03日 著者:森見 登美彦

読書メーター


見た映画

1月の鑑賞メーター
観た本数:8本
観た時間:1205分

ほしのこえ [DVD]ほしのこえ [DVD]
私がNHKデジタル・スタジアムで「彼女と彼女の猫」を見たのは10年ほど前のことである。 ガイナックスに影響を受けたであろう映像構成とクォリティの高さに衝撃を受けたことを覚えている。 TUTAYAで何気なく手に取った本作が「彼女と彼女の猫」の新海誠の作品ということを知り、 問答無用でレンタルした。 個人制作のため、仕方ないといってしまえばそれまでだが、キャラデザや声優が同人臭いのが少し気になった。 一方で背景美術が美しく、細部まで手抜きのない映像は一人で製作したとは思えないレベルである。
鑑賞日:01月31日 監督:
ターミネーター:サラ・コナー クロニクルズ 〈セカンド・シーズン〉 コレクターズ・ボックス1 [DVD]ターミネーター:サラ・コナー クロニクルズ 〈セカンド・シーズン〉 コレクターズ・ボックス1 [DVD]
鑑賞日:01月17日 監督:
パリ、テキサス デジタルニューマスター版 [DVD]パリ、テキサス デジタルニューマスター版 [DVD]
子供が可愛すぎて、妻が美人過ぎる。まあ、それはいいとして主人公に共感できない。特に面の皮の厚さと計画性の無さには脱帽させられる。が、見た後の余韻が楽しめるという点では素晴らしい。
鑑賞日:01月11日 監督:
ユージュアル・サスペクツ [DVD]ユージュアル・サスペクツ [DVD]
カイザー・ソゼというunknownな存在が非常にいい味を出しており、途中まではすごくワクワクしながら見ることができた。ただし、ミスリードが露骨すぎて根拠無しにカイザー・ソゼの正体が予想可能だったため、ひっくり返された感がなかったのが残念。面白かったが、自分にとって突出した映画ではない。
鑑賞日:01月10日 監督:ブライアン・シンガー
コーチ・カーター スペシャル・コレクターズ・エディション [DVD]コーチ・カーター スペシャル・コレクターズ・エディション [DVD]
鑑賞日:01月05日 監督:トーマス・カーター
テルマ&ルイーズテルマ&ルイーズ
男根主義へのアンチテーゼ
鑑賞日:01月03日 監督:
ソウ5 DTS【アンレイテッド】エディション [DVD]ソウ5 DTS【アンレイテッド】エディション [DVD]
犯人が既知だったためか特にスリルも無く、前作までを刈り取って、次回作へ向けて種まいて終わった感じ。
鑑賞日:01月02日 監督:ディヴィッド・ハックル
ナイト・オン・ザ・プラネット [DVD]ナイト・オン・ザ・プラネット [DVD]
タクシードライバーにまつわる群像劇。ローマの話が特に面白かった。
鑑賞日:01月01日 監督:

Javaを使う理由

 人気プログラミング言語ランキングJavaが1位を獲得した。
これは私にとっては意外な結果であった。(個人的にはCだと思っていた)

 さて、最近あるソフトウエアハウスの営業役員の方(仮にAさんとしよう)とお話をさせていただく機会があり、
そこでJavaの話題が出た。東海三県ではJavaの案件が多いそうだ。
なぜJavaが多いのか。Aさん曰く3つの理由があるそうだ。

理由

1. 既存の資産活用が可能
 一時期オブジェクト指向言語の代表例としてJavaがもてはやされたため、多くの企業がそれに乗っかった結果、資産が多く残ったため

2. マシンパワーが必要
 Javaを快適に動作させるにはそれなりにマシンパワーが必要となるため、ハードウエアの買い替え需要が発生する(SIerとしては美味しい)

3. オフショア開発
 中国にはJavaプログラマが多く存在しており、オフショアに出しやすいため


Aさんの話を聞く限り、何かしらのソリューションとしての言語選択ではなく、
環境がJavaを使う理由となっているようだ。
特に2については「なんじゃそりゃ」と言わざるをえない。
是非Javaプログラマの方にJavaの優位性を示してもらいたいものだ。

Twitterを始めてみた


なにやら流行っているようなので、Twitterを始めてみることにしました。
http://twitter.com/kojo_sugita
が、いまいちメリットというか、何を何のためにやるものなのかが分からん・・・

とりあえず、つぶやきまくればいいのかなあ?