PacktPublishing/Mastering-OpenCV-4-Third-Edition

Errors building/using OpenCV.js

orgicus opened this issue · 3 comments

Hi,

I've tried to build OpenCV.js and ran into errors:

python ./platforms/js/build_js.py build_js_test --emscripten_dir ../emsdk/upstream/emscripten
Args: Namespace(build_dir='build_js_test', build_doc=False, build_flags=None, build_perf=False, build_test=False, build_wasm=False, build_wasm_intrin_test=False, clean_build_dir=False, cmake_option=None, config='/Users/George/Downloads/Grouped/cv/opencv/platforms/js/opencv_js.config.py', config_only=False, disable_wasm=False, emscripten_dir='../emsdk/upstream/emscripten', enable_exception=False, opencv_dir='/Users/George/Downloads/Grouped/cv/opencv', simd=False, skip_config=False, threads=False)
Check dir /Users/George/Downloads/Grouped/cv/opencv/build_js_test (create: True, clean: False)
Check dir /Users/George/Downloads/Grouped/cv/opencv (create: False, clean: False)
Check dir /Users/George/Downloads/Grouped/cv/emsdk/upstream/emscripten (create: False, clean: False)
=====
===== Config OpenCV.js build for default target
=====
Executing: ['cmake', '-DENABLE_PIC=FALSE', '-DCMAKE_BUILD_TYPE=Release', "-DCMAKE_TOOLCHAIN_FILE='/Users/George/Downloads/Grouped/cv/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake'", "-DCPU_BASELINE=''", "-DCPU_DISPATCH=''", '-DCV_TRACE=OFF', '-DBUILD_SHARED_LIBS=OFF', '-DWITH_1394=OFF', '-DWITH_ADE=OFF', '-DWITH_VTK=OFF', '-DWITH_EIGEN=OFF', '-DWITH_FFMPEG=OFF', '-DWITH_GSTREAMER=OFF', '-DWITH_GTK=OFF', '-DWITH_GTK_2_X=OFF', '-DWITH_IPP=OFF', '-DWITH_JASPER=OFF', '-DWITH_JPEG=OFF', '-DWITH_WEBP=OFF', '-DWITH_OPENEXR=OFF', '-DWITH_OPENGL=OFF', '-DWITH_OPENVX=OFF', '-DWITH_OPENNI=OFF', '-DWITH_OPENNI2=OFF', '-DWITH_PNG=OFF', '-DWITH_TBB=OFF', '-DWITH_TIFF=OFF', '-DWITH_V4L=OFF', '-DWITH_OPENCL=OFF', '-DWITH_OPENCL_SVM=OFF', '-DWITH_OPENCLAMDFFT=OFF', '-DWITH_OPENCLAMDBLAS=OFF', '-DWITH_GPHOTO2=OFF', '-DWITH_LAPACK=OFF', '-DWITH_ITT=OFF', '-DWITH_QUIRC=OFF', '-DBUILD_ZLIB=ON', '-DBUILD_opencv_apps=OFF', '-DBUILD_opencv_calib3d=ON', '-DBUILD_opencv_dnn=ON', '-DBUILD_opencv_features2d=ON', '-DBUILD_opencv_flann=ON', '-DBUILD_opencv_gapi=OFF', '-DBUILD_opencv_ml=OFF', '-DBUILD_opencv_photo=ON', '-DBUILD_opencv_imgcodecs=OFF', '-DBUILD_opencv_shape=OFF', '-DBUILD_opencv_videoio=OFF', '-DBUILD_opencv_videostab=OFF', '-DBUILD_opencv_highgui=OFF', '-DBUILD_opencv_superres=OFF', '-DBUILD_opencv_stitching=OFF', '-DBUILD_opencv_java=OFF', '-DBUILD_opencv_java_bindings_generator=OFF', '-DBUILD_opencv_js=ON', '-DBUILD_opencv_python2=OFF', '-DBUILD_opencv_python3=OFF', '-DBUILD_opencv_python_bindings_generator=OFF', '-DBUILD_EXAMPLES=OFF', '-DBUILD_PACKAGE=OFF', '-DBUILD_TESTS=OFF', '-DBUILD_PERF_TESTS=OFF', '-DBUILD_DOCS=OFF', '-DWITH_PTHREADS_PF=OFF', '-DCV_ENABLE_INTRINSICS=OFF', '-DBUILD_WASM_INTRIN_TESTS=OFF', "-DCMAKE_C_FLAGS='-s USE_PTHREADS=0 '", "-DCMAKE_CXX_FLAGS='-s USE_PTHREADS=0 '", '/Users/George/Downloads/Grouped/cv/opencv']
Re-run cmake no build system arguments
CMake Error at /Users/George/Downloads/Grouped/cv/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake:131 (message):
  Failed to fetch compiler version information with command
  "'/Users/George/Downloads/Grouped/cv/emsdk/upstream/emscripten/emcc' -v"!
  Process returned with error code SIGTRAP.
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.18.2/share/cmake/Modules/CMakeDetermineSystem.cmake:93 (include)
  CMakeLists.txt:106 (enable_language)


CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles".  CMAKE_MAKE_PROGRAM is not set.  You probably need to select a different build tool.
-- Configuring incomplete, errors occurred!
Traceback (most recent call last):
  File "./platforms/js/build_js.py", line 270, in <module>
    builder.config()
  File "./platforms/js/build_js.py", line 192, in config
    execute(cmd)
  File "./platforms/js/build_js.py", line 23, in execute
    raise Fail("Child returned: %s" % retcode)
__main__.Fail: Child returned: 1

I've tried running the same command separaterly:

cmake -DENABLE_PIC=FALSE -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE='/Users/George/Downloads/Grouped/cv/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake' -DCPU_BASELINE='' -DCPU_DISPATCH='' -DCV_TRACE=OFF -DBUILD_SHARED_LIBS=OFF -DWITH_1394=OFF -DWITH_ADE=OFF -DWITH_VTK=OFF -DWITH_EIGEN=OFF -DWITH_FFMPEG=OFF -DWITH_GSTREAMER=OFF -DWITH_GTK=OFF -DWITH_GTK_2_X=OFF -DWITH_IPP=OFF -DWITH_JASPER=OFF -DWITH_JPEG=OFF -DWITH_WEBP=OFF -DWITH_OPENEXR=OFF -DWITH_OPENGL=OFF -DWITH_OPENVX=OFF -DWITH_OPENNI=OFF -DWITH_OPENNI2=OFF -DWITH_PNG=OFF -DWITH_TBB=OFF -DWITH_TIFF=OFF -DWITH_V4L=OFF -DWITH_OPENCL=OFF -DWITH_OPENCL_SVM=OFF -DWITH_OPENCLAMDFFT=OFF -DWITH_OPENCLAMDBLAS=OFF -DWITH_GPHOTO2=OFF -DWITH_LAPACK=OFF -DWITH_ITT=OFF -DWITH_QUIRC=OFF -DBUILD_ZLIB=ON -DBUILD_opencv_apps=OFF -DBUILD_opencv_calib3d=ON -DBUILD_opencv_dnn=ON -DBUILD_opencv_features2d=ON -DBUILD_opencv_flann=ON -DBUILD_opencv_gapi=OFF -DBUILD_opencv_ml=OFF -DBUILD_opencv_photo=ON -DBUILD_opencv_imgcodecs=OFF -DBUILD_opencv_shape=OFF -DBUILD_opencv_videoio=OFF -DBUILD_opencv_videostab=OFF -DBUILD_opencv_highgui=OFF -DBUILD_opencv_superres=OFF -DBUILD_opencv_stitching=OFF -DBUILD_opencv_java=OFF -DBUILD_opencv_java_bindings_generator=OFF -DBUILD_opencv_js=ON -DBUILD_opencv_python2=OFF -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_EXAMPLES=OFF -DBUILD_PACKAGE=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_DOCS=OFF -DWITH_PTHREADS_PF=OFF -DCV_ENABLE_INTRINSICS=OFF -DBUILD_WASM_INTRIN_TESTS=OFF -DCMAKE_C_FLAGS='-s USE_PTHREADS=0 ' -DCMAKE_CXX_FLAGS='-s USE_PTHREADS=0 ' /Users/George/Downloads/Grouped/cv/opencv
CMake Error at CMakeLists.txt:11 (message):
  

  FATAL: In-source builds are not allowed.

         You should create a separate directory for build files.



-- Configuring incomplete, errors occurred!

Looking at the official OpenCV.js setup I've noticed there's a docker version which I've tried:

docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:latest" python ./platforms/js/build_js.py build_js_docker --enable_exception

It did generate opencv.js (and also opencv_js.js which is confusing), but when I tried to use it on a web page I got this error:

Uncaught (in promise) 
BindingError
message: "Cannot register public name 'IntVector' twice"
name: "BindingError"
stack: "BindingError: Cannot register public name 'IntVector' twice↵    at BindingError.<anonymous> (http://127.0.0.1:8696/libraries/opencv.js:31:8081873)↵    at new BindingError (eval at createNamedFunction (http://127.0.0.1:8696/libraries/opencv.js:31:8081582), <anonymous>:4:34)↵    at throwBindingError (http://127.0.0.1:8696/libraries/opencv.js:31:8087018)↵    at exposePublicSymbol (http://127.0.0.1:8696/libraries/opencv.js:31:8092550)↵    at __embind_register_class (http://127.0.0.1:8696/libraries/opencv.js:31:8102881)↵    at <anonymous>:wasm-function[103]:0xdbd2↵    at <anonymous>:wasm-function[102]:0xb853↵    at __wasm_call_ctors (<anonymous>:wasm-function[57]:0xa1a3)↵    at Module.___wasm_call_ctors (http://127.0.0.1:8696/libraries/opencv.js:31:8147790)↵    at func (http://127.0.0.1:8696/libraries/opencv.js:31:8005045)"
__proto__: Error

I'm not sure how to proceed from here.

How can I compile OpenCV.js to a usable script ?

Many thanks,
George

You can (and should) get a prebuilt version of OpenCV JS instead of building it yourself.
Here is a Stackoverflow discussion about it: https://stackoverflow.com/a/49809421/5339857
And here you can get the prebuilt JS file: https://docs.opencv.org/master/opencv.js

This will save you all this trouble.

Hi Roy,

Thank you for the advice.
I've managed to compile OpenCV.js now with both Docker and using Ubuntu (in a VM).
The part that threw me off is I tried to use cv straight away and that resulted in errors.
I managed to use cv after handling it as a Promise, something like:

cv.then( (lib) => {console.log("now I can use cv:",cv.Mat.eye(3,3,cv.CV_8UC1}) );

This may be a bit cheeky but I'm grateful for any bit of advice on thi:
How can I wrap functions that OpenCV.js hasn't wrapped yet ?
For context I've posted a question here:
https://stackoverflow.com/questions/63889719/how-to-add-accumulateweighted-support-to-opencv-js#

Essentially I tried adding this to core_bindings (in the right IMG_PROC sections of course):

// C++: void accumulateWeighted(InputArray src, InputOutputArray dst, double alpha, InputArray mask=noArray() )
void accumulateWeighted_wrapper(const cv::Mat& src, const cv::Mat& dst, double alpha, cv::Mat& mask) {
    return cv::accumulateWeighted(src, dst, alpha, mask);
}

void accumulateWeighted_wrapper_1(const cv::Mat& src, const cv::Mat& dst, double alpha) {
    return cv::accumulateWeighted(src, dst, alpha);
}
// ...
function("accumulateWeighted", select_overload<void(const cv::Mat&, const cv::Mat&, double , cv::Mat&)>(&Wrappers::accumulateWeighted_wrapper));

function("accumulateWeighted", select_overload<void(const cv::Mat&, const cv::Mat&, double)>(&Wrappers::accumulateWeighted_wrapper_1));

(and also added the string to the imgproc dictionary in opencv_js.config.py

but ran into some strange assembly errors I'm having a hard time debugging.

Any hints/tips ? :)

Many thanks,
George

As mentioned on stackoverflow, in this particular case I went for a manual approach:

cv.lerp = function(lerpFromMat, lerpToMat, lerpResult, amount){
    // TODO: args safety check (including constraining amount)
    if (lerpToMat.cols === 0) {
      lerpFromMat.copyTo(lerpResult);
    } else if (lerpFromMat.cols === 0) {
      lerpToMat.copyTo(lerpResult);
    } else {
      cv.addWeighted(lerpFromMat, amount, lerpToMat, 1.0 - amount, 0.0, lerpResult);
    }
  }

// super simplified alias, skipping mask for now
cv.accumulateWeighted = function(newMat, accumulatorMat, alpha){
   p5cv.lerp(accumulatorMat, newMat, accumulatorMat, alpha);
}

however it would be great to learn how to tweak and compile OpenCV.js to wrap missing functions such as accumulateWeighted.