目次
概要
OpenCV.js を使用して Javascript で画像処理を行う方法について解説します。
OpenCV.js
OpenCV.js とは、OpenCV をブラウザ上で利用可能にした JavaScript バインディングです。この OpenCV.js を使うことで、JavaScript で直接 OpenCV の機能を使用し、ブラウザでリアルタイムな画像処理やコンピュータビジョンのアプリケーションを作成することが可能になります。 OpenCV.js は Emscripten を用いて、OpenCV の C++ コードを WebAssembly に変換することでブラウザ上で動作します。これにより、ブラウザ環境での高速な実行と、ネイティブに近い性能を得ることができます。
OpenCV と OpenCV.js の違い
- imread() で読み込んだ画像は OpenCV では BGR の 3 チャンネルに対して、OpenCV.js では RGBA の 4 チャンネルになります。チャンネル順が異なるので注意してください。
- 作成した
cv.Mat
オブジェクトは、使用後にcv.Mat.delete()
を呼び出して明示的にリソースを解放する必要があります。
ブラウザから使用する方法
- Releases · opencv/opencv から最新版の
opencv-{バージョン}-docs.zip
をダウンロードし、解凍します (例:opencv-4.10.0-docs
) opencv-{バージョン}-docs/{バージョン}/opencv.js
にそのバージョンの OpenCV.js の本体が存在するので、ディレクトリを作成し、以下のような構造で配置します
Project
├── sample.html
└── opencv.js
sample.html
には、以下のコードを記載します
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>OpenCV.js Example</title>
</head>
<body>
<div>
<input type="file" id="fileInput" />
<div>
<img id="input_img" />
<canvas id="output_img"></canvas>
</div>
</div>
<script async src="opencv.js" type="text/javascript"></script>
<script type="text/javascript">
const imgElement = document.getElementById("input_img");
const inputElement = document.getElementById("fileInput");
inputElement.addEventListener(
"change",
(e) => {
imgElement.src = URL.createObjectURL(e.target.files[0]);
},
false
);
imgElement.onload = function () {
const src = cv.imread(imgElement);
// グレースケール画像に変更する。
const dst = new cv.Mat();
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
// キャンバスに描画する。
cv.imshow("output_img", dst);
src.delete();
dst.delete();
};
</script>
</body>
</html>
HTML ファイルをブラウザから開き、「ファイルを選択」から画像ファイルを選択すると、以下のような画面が表示されます。このサンプルでは、選択した画像を OpenCV.js で開き、グレースケールに変換して表示しています。
処理について解説します。
まず、入力ボタンをクリックして画像を選択したとき、ユーザーが選択した画像ファイルを URL に変換して <img>
要素の src 属性に設定するイベントハンドラを登録します。
const imgElement = document.getElementById("input_img");
const inputElement = document.getElementById("fileInput");
inputElement.addEventListener(
"change",
(e) => {
imgElement.src = URL.createObjectURL(e.target.files[0]);
},
false
);
画像が読み込まれたときの処理を記述します。
cv.imread()
を使用して<img>
要素から画像を読み込み、OpenCV.js の cv.Mat 型のオブジェクトを生成します。cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY)
を使用して画像をグレースケールに変換します。出力結果を格納する空の行列をconst dst = new cv.Mat()
により事前に作成しておく必要があります。cv.imshow("output_img", dst)
で出力結果を表示する<canvas>
要素の id を指定して、結果画像を表示します。
imgElement.onload = function () {
const src = cv.imread(imgElement);
// グレースケール画像に変更する。
const dst = new cv.Mat();
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
// キャンバスに描画する。
cv.imshow("output_img", dst);
src.delete();
dst.delete();
};
React で使用する方法
vite を使用して React の雛形を作成します。(Vite は Vue など他のフレームワークも対応しています)
npm create vite@latest
- Project name: react-opencvjs
- Select a framework: React
- Select a variant: TypeScript + SWC
プロジェクトのディレクトリに移動し、@techstark/opencv-js
をインストールします。
cd react-opencvjs
npm install @techstark/opencv-js
src/App.tsx
を以下のように編集します。
import React, { useRef } from "react";
import cv from "@techstark/opencv-js";
function App() {
const imgElementRef = useRef<HTMLImageElement>(null!);
const canvasElementRef = useRef<HTMLCanvasElement>(null!);
console.log(cv);
function fileSelected(event: React.ChangeEvent<HTMLInputElement>) {
const imgElement = imgElementRef.current;
const file = event.target.files?.[0];
if (!file) {
return;
}
const reader = new FileReader();
reader.onload = (event) => {
const dataUrl = event.target?.result as string;
imgElement.src = dataUrl;
};
reader.readAsDataURL(file);
}
function imgLoaded() {
const imgElement = imgElementRef.current;
const canvasElement = canvasElementRef.current;
if (!imgElement.complete) {
return; // 画像の読み込みに失敗した場合
}
const src = cv.imread(imgElement);
const dst = new cv.Mat();
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
cv.imshow(canvasElement, dst);
src.delete();
dst.delete();
}
return (
<div>
<input type="file" id="fileInput" onChange={fileSelected} />
<div>
<img id="input_img" ref={imgElementRef} onLoad={imgLoaded} />
<canvas id="output_img" ref={canvasElementRef} />
</div>
</div>
);
}
export default App;
コメント