DEV Community

Junichi Kajiwara
Junichi Kajiwara

Posted on

require('./opencv.js') is not enough for using OpenCV.js

Begin

I noticed that I can use official OpenCV with JavaScript(WASM).

The problem

When I wrote code following:

const cv = require('./opencv.js');

let mat = new cv.Mat();
console.log(mat.size());
mat.delete();
Enter fullscreen mode Exit fullscreen mode

Unfortunately I've got only error messages like this:

TypeError: cv.Mat is not a constructor
    at Object.<anonymous> (/Volumes/EXTHDD3/local/opencv/build_wasm/bin/dame.js:3:11)
    at Module._compile (module.js:641:30)
    at Object.Module._extensions..js (module.js:652:10)
    at Module.load (module.js:560:32)
    at tryModuleLoad (module.js:503:12)
    at Function.Module._load (module.js:495:3)
    at Function.Module.runMain (module.js:682:10)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:613:3
Enter fullscreen mode Exit fullscreen mode

Solution 1

I think I need some wait, and I rewrite the code following:

const cv = require('./opencv.js');

setTimeout(()=>{
        (()=>{
                let mat = new cv.Mat();
                console.log(mat.size());
                mat.delete();
        })();
},10000);
Enter fullscreen mode Exit fullscreen mode

This time,there is no error message.

{ width: 0, height: 0 }
Enter fullscreen mode Exit fullscreen mode

Solution 2

Solution 1 is not goot at looking, and depends on CPU's speed.

I found that Emscipten will call onRuntimeInitialized when it's ready to call main function.

const cv = require("./opencv.js");
cv['onRuntimeInitialized']=()=>{
          let mat = new cv.Mat();
          console.log(mat.size());
          mat.delete();
};
Enter fullscreen mode Exit fullscreen mode
{ width: 0, height: 0 }
Enter fullscreen mode Exit fullscreen mode

Discussion (2)

Collapse
mjyc profile image
Michael Jae-Yoon Chung • Edited on

Thank you for sharing useful info!

I've also faced this problem and solved the problem by using --disable_wasm option, e.g., python ./platforms/js/build_js.py build_js --disable_wasm, which ends up building an asm.js version of opencv.js. Then const cv = require('./opencv.js'); will block until the opencv.js will is fully loaded.

Note that asm.js version of opencv.js is slower than that of wasm, but it was more important for me to make the import step easy for me for teaching purposes.

For details see npmjs.com/package/@mjyc/opencv.js.

Collapse
torbasow profile image
torbasow

Thank you! Official tutorial lies for a pity.