以下のツイートで掲載していたように、以前、p5.js Web Editor で opencv.js を利用する、ということをやったのですが、その時に行った内容の記事化です(大晦日ハッカソン2022 絡みで、この内容を活用いただけそうだったため、記事化し忘れていたのを書いて公開)。
前に試した時からライブラリのバージョンがあがっていました。そのため、今回は以下の最新版にしてから動作を確認しています。
- p5.js 1.5.0
- opencv.js 4.7.0
ソースコードの内容など
p5.js Web Editor で opencv.js を使うために過去に試行錯誤して、sketch.js のみに手を加えるやり方で動作をさせることができていました。
その時に作ったプログラムを、以下に掲載します。
ちなみに、index.html と style.css は、p5.js Web Editor が生成するデフォルトの内容そのままで OK です。
なお、画像処理部分は冒頭のツイートのものよりシンプルな内容にしていて、グレースケール変換のみ行っています。
let canvas, pg, capture;
let cvFlag = false;
function setup() {
canvas = createCanvas(560, 420);
pg = createGraphics(width, height);
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
}
function draw() {
background(120);
pg.image(capture, 0, 0, width, height);
if (cvFlag) {
let src = cv.imread(pg.elt);
let dst = new cv.Mat();
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0);
cv.imshow(canvas.elt, dst);
src.delete();
dst.delete();
}
}
window.addEventListener("load", (event) => {
console.log("The page has fully loaded");
let script = document.createElement("script");
script.addEventListener("load", (event) => {
console.log("opencv.js file has been loaded");
cv["onRuntimeInitialized"] = () => {
console.log("onRuntimeInitialized");
cvFlag = true;
};
});
script.src = "https://docs.opencv.org/4.7.0/opencv.js";
document.body.appendChild(script);
});
上記を実行して、opencv.js を使ってグレースケール化された画像が、p5.js Web Editor上のキャンバスに描画されたのを確認できました。
p5.js と opencv.js を当時使っていたバージョンから、最新に変更しただけで、当時作成していたソースコードはいじることなく無事に動いた#p5js #OpenCV #大晦日ハッカソン pic.twitter.com/ErUbnVWThm
— you (@youtoy) December 31, 2022
プログラムに関する補足
上で掲載していたプログラムについて、少し補足をします。
cv["onRuntimeInitialized"] を利用する部分
過去に、 cv["onRuntimeInitialized"]
を使った処理と、p5.js の処理を組み合わせてうまく動かすのに、試行錯誤していたのがあります(かなり、記憶が曖昧になってる...)。
ソースコード内に以下の記事のリンクをメモしていたので、こちらが、当時の試行錯誤で参照した記事の一つとなるようでした。
●OpenCV.jsとWebカメラ画像表示 - Qiita
https://qiita.com/mktshhr/items/ac6351dd056e571715e0
cv["onRuntimeInitialized"]
を利用する部分は、上記の記事内では、以下の WASM を使う分岐の処理で掲載されていたものです。
カメラ画像の利用と画像の入出力
カメラ画像は、p5.js の createCapture() で取得したものを使っています。
そのカメラ画像を、 createGraphics()
で作った pg
に貼り付けてから、opencv.js に渡すようにしていて、メインのキャンバスとは分離して処理しています。その部分について、 cv.imread()
には、HTML の要素を渡す形になるようだったので、p5.Element の elt を渡す形にしています。
その処理の後、ページ上へ opencv.js での処理結果を描画する際にも、描画先は HTML要素を指定する形になるようでした。それで、メインのキャンバスの elt を指定した cv.imshow(canvas.elt, dst);
という形にしています。
opencv.js の読み込み待ち
opencv.js の読み込みは、少し時間がかかるので、 cvFlag
というフラグの変数を使い、読み込みが完了したかどうかを判定しています。
具体的には以下の部分です。p5.js の draw() が、opencv.js の読み込みを待たず動いていますが、draw() の中の opencv.js を使った処理は、以下のように opencv.js の読み込み完了後に行われるようにしています。
if (cvFlag) {
let src = cv.imread(pg.elt);
let dst = new cv.Mat();
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0);
cv.imshow(canvas.elt, dst);
src.delete();
dst.delete();
}