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

React

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

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

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

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

スポンサー

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

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

Reactプロジェクトの「public/index.html」(パスを変えていない場合)に以下のコードを追加します。(「4.5.5」の部分は任意のバージョンを指定します)

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

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

const cv = window.cv

以降では、Appコンポーネントで画像ファイルの読み込み、表示、簡単な画像処理を実施する方法を紹介します。

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

Appコンポーネントに<input>タグと<canvas>タグを追加し、ファイル読み込み後にOpenCVのMatデータに変換後、<canvas>タグに画像を表示します。

const cv = window.cv

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

  return (
    <div className="App">
      <div>
        <input type="file" onChange={onChangeFile} />
      </div>
      <canvas id="output" />
    </div>
  )
}

extern default App

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

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

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

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

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

const cv = window.cv

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

  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()
  }

  return (
    <div className="App">
      <div>
        <input type="file" onChange={onChangeFile} />
        <button onClick={onClickGray}>グレイスケール化</button>
        <button onClick={onClickTh}>二値化</button>
      </div>
      <canvas id="output" />
    </div>
  )
}

extern default App

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

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

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

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

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

終わりに

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

今回の記事についてわからなかった点や誤っている点などありましたらコメントまでお願いいたします。

コメント

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