4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenCV.jsで関数を有効化したい時に確認するべき3つのポイント

4
Last updated at Posted at 2025-11-30

この記事はOpenCV Advent Calendar 2025の1日目の記事です。
他の記事は目次にまとめられています。

■ はじめに

OpenCV Advent Calendar 2025に興味を持って頂き、ありがとうございます!今年はカテゴリーが「ライブラリ・フレームワーク」から「AI・機械学習・データサイエンス」に移動となりました!(ただ、そんなことを気にせずに投稿しております!)

今回のアドカレでの内容を何か1つでも持ちかえっていただければ、あるいは、来年以降何かのタイミングで検索などでこの情報が参考になりましたら、幸甚に存じます。よろしくお願いいたします!

また、OpenCV Advent Calendar寄稿者の方も、お忙しい中、ご参加いただき誠にありがとうございます!何卒よろしくお願いいたします。

それでは、OpenCV Advent Calendar 2025開始となります!!25日間、最後までお楽しみくださいませ!

■ TL;DR:OpenCV.jsで関数を有効化したい時はここを見てほしい!

  1. 対象モジュールは、build対象に入っているか?
  2. 対象モジュールは、js wrapperに認識されているか?
  3. 対象関数は、gen_dict.jsに登録されているか?

■ はじめに

OpenCV.jsは、OpenCVが提供している機能をEmscriptenを使ってJavaScriptから使えるようにしたライブラリです。もう8年目になりますね。

ただし、外部ライブラリが必要などの理由でOpenCVが提供している機能のフルセットではなくサブセットになっております。そのため、本当はこの機能欲しいんだけど使えない、という悲しい場合も少なくないです。

或いは、元々のOpenCV.jsだとサイズが大きすぎるから、もうちょっと小さいサイズにシュリンクしたかったりもします。

こういう時は、自分でビルドしてあげると、欲しい機能だけ取り出せたりします!
そこで、OpenCV.jsで関数を有効化するときに確認するべき3つのポイントを紹介したい!!

■ OpenCV.jsをデフォルトでbuildしたい!

まずは、OpenCV.jsをbuildする準備をしましょう。以下は、ubuntu 24.04環境です。

〇 emscriptenの準備

まず、build環境の構築になります。このあたりはサクサクやりましょう


11/30現在、emsdk側に修正が入った影響で、最新版の組み合わせだとC++11では動かないかも!?下記2つの修正が別途必要です(両方やったら、最新のOpenCVとlatestのemsdkの組み合わせでもbuildできました)。

(1) emcmake する時に、 -DCMAKE_CXX_STANDARD=17 を指定する
(2) modules/js/CMakeLists.txt 内の-std=c++11-std=c++17に書き換える


See https://emscripten.org/docs/getting_started/downloads.html
See https://docs.opencv.org/4.x/d4/da1/tutorial_js_setup.html

cd && mkdir work && cd work
apt update -y
sudo apt install -y python3 git cmake
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
/home/kmtr/work
 ├ emsdk

〇OpenCVとOpenCV contribのダウンロード

次に、OpenCVとContribをcloneしましょう。

cd && cd work
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
/home/kmtr/work
 ├ emsdk
 ├ opencv
 ├ opencv_contrib

〇OpenCV.jsをbuildしてみる

それではさっそく、OpenCV.jsをbuildしてみましょう。
この時contribのコードを取り込みたい場合は、OPENCV_EXTRA_PATH_MODULESにフルパスで指定すると間違いないですね!(多分問題ないはずですが)。

cd && cd work
emcmake python ./opencv/platforms/js/build_js.py -DOPENCV_EXTRA_MODULES_PATH=/home/kmtr/work/opencv_contrib/modules build_js
/home/kmtr/work
 ├ emsdk
 ├ opencv
 ├ opencv_contrib
 ├ build_js

■ 実際に関数を追加してみる

それでは、実際に関数を追加してみましょう!

〇【確認ポイント1】対象モジュールは、build対象に入っているか?

emcmakeを実行したときに、各モジュールのbuild statusが表示される。ここを確認しましょう!

--   OpenCV modules:
--     To be built:                 aruco bgsegm bioinspired calib3d core dnn dnn_objdetect dnn_superres dpm face features2d flann fuzzy hfs img_hash imgproc intensity_transform js line_descriptor mcc objdetect phase_unwrapping photo plot rapid reg rgbd saliency signal stereo structured_light surface_matching tracking video wechat_qrcode xfeatures2d xphoto
--     Disabled:                    highgui imgcodecs ml shape stitching superres videoio videostab world
--     Disabled by dependency:      ccalib datasets optflow quality text ts ximgproc xobjdetect
--     Unavailable:                 alphamat cannops cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev cvv fastcv freetype gapi hdf java julia matlab ovis python2 python3 sfm viz
--     Applications:                examples
--     Documentation:               js
--     Non-free algorithms:         NO
  • To be builtに含まれるモジュールは、OpenCV.jsに含められるモジュール
  • DisabledはOpenCV.jsをbuildするときに明示的に無効化されたモジュール
  • Disabled by dependencyDisabledなどの依存関係で無効化されたモジュール

例えば、img_hashxphotoモジュール内の関数はOpenCV.jsに組み込めます。しかし、freetypesfmは組み込めない、という事になります。自分が使いたい関数のモジュールが有効化されているのかを確認しましょう!

〇【確認ポイント2】対象モジュールは、js wrapperに認識されているか?

自分が使いたい関数を含むモジュールが有効化されていても、まだ油断はなりません!

次は、js wrapperがその対象モジュールを認識しているかを確認しなければなりません。これは各モジュールのCMakeLists.txtを確認してください

ocv_define_module行のWRAP jsが重要です。これが書いてあるモジュールだけが、js wrapperはOpenCV.js対象モジュールとして認識されます。

OpenCV.js対象モジュールとして認識されたかどうかは、emcmake実行時のログにも出力されます!

-- Wrapped in JavaScript(js):
--     opencv_core
--     opencv_imgproc
--     opencv_photo
--     opencv_dnn
--     opencv_features2d
--     opencv_calib3d
--     opencv_objdetect
--     opencv_video
--     opencv_wechat_qrcode
--     opencv_aruco
-- Use autogenerated whitelist /home/kmtr/work/build_js/modules/js_bindings_generator/whitelist.json

上記の例だと、core imgproc photoなんかはOpenCV.jsに含まれますが、ximgprocxphotoなんかは含まれない、ということになりますね。

例えば、img_hashを対象に入れたいならば、WRAP jsを追加してあげる必要があります。

kmtr@kmtr-VMware-Virtual-Platform:~/work/opencv_contrib4$ git diff
diff --git a/modules/img_hash/CMakeLists.txt b/modules/img_hash/CMakeLists.txt
index fe75c22c..e78887ac 100644
--- a/modules/img_hash/CMakeLists.txt
+++ b/modules/img_hash/CMakeLists.txt
@@ -1,3 +1,3 @@
 set(the_description "Image hash algorithms")
 set(OPENCV_MODULE_IS_PART_OF_WORLD OFF)
-ocv_define_module(img_hash opencv_imgproc opencv_core WRAP python java objc)
+ocv_define_module(img_hash opencv_imgproc opencv_core WRAP python java objc js)

〇【確認ポイント3】対象関数は、gen_dict.jsに登録されているか?

次に、js wrapperがexportするために、misc/js/gen_dict.jsに対象関数を記述して下さい!

例えば、img_hashに含まれる関数だったら、こんな感じになります。

modules/img_hash/misc/js/gen_dict.json
{
    "whitelist":
    {
        "": [ "averageHash", "blockMeanHash", "colorMomentHash", "marrHildrethHash", "radialVarianceHash", "pHash" ]
    },
    "namespace_prefix_override":
    {
        "img_hash": ""
    }
}

下にある、namespace_prefix_overrideを書かないと、exportしたはずの関数が見つからない、なんてことがありますので、ご注意ください!。

〇 さあ、自分だけのOpenCV.jsをbuildしよう!

それでは、もう一度buildしてみましょう! これで自分だけの特別なOpenCV.jsの完成になります!!

cd && cd work
emcmake python ./opencv/platforms/js/build_js.py -DOPENCV_EXTRA_MODULES_PATH=/home/kmtr/work/opencv_contrib/modules build_js

■ きちんとできていることを確認する

例えばサンプルコードはこんな感じになります。
このindex.htmlを同じフォルダに作成したopencv.jsを置いてください。

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello OpenCV.js</title>
</head>
<body>
<h2>Hello OpenCV.js</h2>
<p id="status">OpenCV.js is loading...</p>
<div>
  <div class="inputoutput">
    <img id="imageSrc" alt="No Image" />
    <div class="caption">imageSrc <input type="file" id="fileInput" name="file" /></div>
  </div>
  <div class="inputoutput">
    <canvas id="canvasOutput" ></canvas>
    <div class="caption">canvasOutput</div>
  </div>
</div>
<script type="text/javascript">
let imgElement = document.getElementById('imageSrc');
let inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', (e) => {
  imgElement.src = URL.createObjectURL(e.target.files[0]);
}, false);

imgElement.onload = async function() {
  cv = (cv instanceof Promise) ? await cv : cv;
  let src = cv.imread(imgElement);
  let dst = new cv.Mat();
  cv.averageHash(src,dst);
  cv.resize(dst, dst, src.size(), 0, 0, cv.INTER_NEAREST );
  cv.imshow('canvasOutput', dst);
  dst.delete();
  src.delete();
};

var Module = {
  // https://emscripten.org/docs/api_reference/module.html#Module.onRuntimeInitialized
  onRuntimeInitialized() {
    document.getElementById('status').innerHTML = 'OpenCV.js is ready.';
  }
};
</script>
<script async src="opencv.js" type="text/javascript"></script>
</body>
</html>

なお、 cv = (cv instanceof Promise) ? await cv : cv; とある通り、cvは実際に関数を呼ばれるまでは読み込みません。つまり、いきなりこのHTMLファイルを読み込んだ時点で、Webブラウザのコンソール上でcv.averageHashと叩いてもundefinedとエラーになります。

なので、一度cvを実体化してから、確かめましょう!

cv = (cv instanceof Promise) ? await cv : cv;`
cv.averageHash

■ まとめ(再掲)

  1. 対象モジュールは、build対象に入っているか?
  2. 対象モジュールは、js wrapperに認識されているか?
  3. 対象関数は、gen_dict.jsに登録されているか?

以上となります。お忙しい中、お読みいただき、ありがとうございました!!

明日12/2は「Zintなら、OpenCVでもMicro QR CodeもrMQRを簡単にサポートできますよ!」になります。OpenCVだけでは対応できなかった、rMQRも実は簡単に作れますよ!!お楽しみに!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?