JavaScriptでOpenCV.jsを使用して画像処理

Javascript

画像処理というとOpenCVが有名で、C++やPythonで使用されるのが一般的です。

OpenCVにはJavaScript版のOpenCV.jsがあり、Nodeだけでなくブラウザ上でも画像処理を行うことができます。

ブラウザ上で画像処理を行う場合には処理速度の問題がありますが、最近のパソコンやブラウザの性能向上によりだいぶ高速に処理できるようになってきました。

この記事では、JavaScriptでOpenCV.jsを使用して画像処理を行う方法について解説します。

OpenCV.jsを使用するための準備

OpenCV.jsはnpmパッケージが存在しないため、CDNからロードして使用します。

OpenCV.jsを使用するhtmlファイルのに以下のコードを追加します。(「4.5.5」の部分は任意のバージョンを指定します)

<script src="https://docs.opencv.org/4.5.5/opencv.js"></script>

OpenCV.jsをロードするとグローバルオブジェクト(window)に「cvオブジェクト」が追加されるので、使用する箇所で「cv」にアクセスすることでOpenCV.jsの機能を使うことができるようになります。

OpenCV.jsを使用して画像読み込み、表示

HTMLの用意

始めに画像を選択して表示するための領域をHTMLに準備します。(以降は説明がない限り<script>タグ内に記載します)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>OpenCV.jsテスト</title>
  <!-- OpenCV.jsのロード -->
  <script src="https://docs.opencv.org/4.5.5/opencv.js"></script>
</head>
<body>
  <!-- 入力領域 -->
  <div class="inputArea">
    <!-- 入力ボタン -->
    <input type="file" onchange="onChange(this)">
  </div>
  <!-- 出力領域 -->
  <div class="outputArea">
    <!-- 出力用キャンバス -->
    <canvas id="output" />
  </div>
  <script>
    // ここにコード記載
  </script>
</body>
</html>

出力は<img>タグではなく<canvas>タグであることに注意してください。(OpenCV.jsの出力処理に合わせて)

画像読み込み、表示

画像を読み込むためのonChange関数を作成し、その中で読み込み・表示処理を記述します。

const onChange = (e) => {
  if (e.files && e.files[0]) {
    const img = new Image();
    img.onload = () => {
      const mat = cv.imread(img);
      cv.imshow('output', mat);
      mat.delete();
    }
    img.src = URL.createObjectURL(e.files[0]);
  }
}

OpenCV.jsで画像の読み込みを行う場合には「cv.imread」関数にImage(HTMLのimg要素)か<canvas>タグのidを指定します。(ここではImageを指定しています)

出力先の<canvas>のidと取得したMatデータを「cv.imshow」に渡すことで、読み込んだ画像を出力することができます。

OpenCV.jsを使用してグレイスケール化、二値化

画像の読み込み・表示だけだと物足りないので、簡単な画像処理である「グレイスケール化」「二値化」をしてみます。

処理の起点となる<button>を2つ追加し、それぞれ処理を行うための関数を追加します。

<!-- 入力領域 -->
<div class="inputArea">
  <!-- 入力ボタン -->
  <input type="file" onchange="onChange(this)">
  <!-- グレイスケール化ボタン -->
  <button onclick="onClickGray()">グレイスケール化</button>
  <!-- 二値化ボタン -->
  <button onclick="onClickTh()">二値化</button>
</div>
const onClickGray = () => {
  const mat = cv.imread('output');
  cv.cvtColor(mat, mat, cv.COLOR_RGBA2GRAY, 0);
  cv.imshow('output', mat);
  mat.delete();
}
const onClickTh = () => {
  const mat = cv.imread('output');
  if (mat.channels() !== 1) cv.cvtColor(mat, mat, cv.COLOR_RGBA2GRAY, 0);
  cv.threshold(mat, mat, 0, 255, cv.THRESH_OTSU);
  cv.imshow('output', mat);
  mat.delete();
}

グレイスケール化は「cv.cvtColor」関数を、二値化は「cv.threshold」関数を使用して変換を行います。(詳細はコチラコチラを参照してください)

OpenCV.jsを使った画像処理の方法の調べ方

OpenCV.jsについてはネット上で検索をしてもあまり出てこないためどうやって調べたら良いかわからない方がいるかもしれません。

基本的にOpenCV.jsで使用できる関数はC++やPythonのOpenCVと同じ関数名となっているため、C++やPythonのOpenCVを使用した画像処理の方法を調べることでOpenCV.jsでも同様の処理を行うことが可能となります。

C++やPythonのOpenCVの処理をそのまま流用すると引数でエラーとなる場合があるので、そういった場合にはOpenCV.jsのチュートリアル(という名のリファレンス)を参照すると使い方が出てくるので参考になります。

終わりに

JavaScriptでOpenCV.jsを使用して画像処理を行う方法について解説しました。

フロント側だけで画像処理を完結させることができるので簡単なツールの作成なんかには良いかと思いますが、大きい画像に対して複雑な処理を行う場合なんかにはC++などと比較して遅くなるので注意が必要です。

この記事について誤っている点・不明な点などありましたらコメントまでお願いします。

コメント

タイトルとURLをコピーしました