0

I have following C++ code with opencv. It is basic code for display image. I'm trying to compile it using emscripten but it seems that emscripten can't load some function of opencv. For example the cv::Mat is ok.

Test for build_js went all right. Do you know what I'm doing wrong?

Code:

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <emscripten/emscripten.h>

int main(int argc, char** argv )
{
    if ( argc != 2 )
    {
        printf("usage: DisplayImage.out <Image_Path>\n");
        return -1;
    }
    cv::Mat image;
    image = cv::imread( argv[1], 1 );
    if ( !image.data )
    {
            printf("No image data \n");
            return -1;
    }
    cv::namedWindow("Display Image");
    cv::imshow("Display Image", image);
    cv::waitKey(0);
    return 0;
}

Error message:

/home/vasek/project_test/opencv/opencvgcccmake_emscript/DisplayImage.cpp:15:13: error: use of undeclared identifier 'imread'
    image = cv::imread( argv[1], 1 );
            ^
/home/vasek/project_test/opencv/opencvgcccmake_emscript/DisplayImage.cpp:21:9: error: no member named 'namedWindow' in namespace 'cv'
    cv::namedWindow("Display Image");
    ~~~~^
/home/vasek/project_test/opencv/opencvgcccmake_emscript/DisplayImage.cpp:22:9: error: no member named 'imshow' in namespace 'cv'
    cv::imshow("Display Image", image);
    ~~~~^
/home/vasek/project_test/opencv/opencvgcccmake_emscript/DisplayImage.cpp:23:9: error: no member named 'waitKey' in namespace 'cv'
    cv::waitKey(0);
    ~~~~^
4 errors generated.

cmake command:

emcmake cmake -DOpenCV_DIR=/home/vasek/tools/opencv/build_js ..

Edit: None of the function work exept cv::Mat.

Dan Mašek
  • 17,852
  • 6
  • 57
  • 85
  • Is this a case of namespaces ? `cv::imread(...` – Jeffrey Mar 29 '21 at 12:15
  • @Jeffrey Hello thanks for answer. Unfortunately forgotten **cv::** prefix was only typo from previous experiments. – Václav Hrbek Mar 29 '21 at 12:22
  • I'd suggest closing this, taking it slow and coming with a clean precisely written question. Quite often going through the motion of stating it cleanly will expose the bug. – Jeffrey Mar 29 '21 at 12:24
  • @Tsyvarev Well, all four of those functions are from the highgui module, however [`opencv2/opencv.hpp`](https://github.com/opencv/opencv/blob/master/include/opencv2/opencv.hpp#L67) automagically includes its header if the module is available... – Dan Mašek Mar 29 '21 at 12:59
  • "Not all of OpenCV’s offerings are suitable for the Web. For instance, the high-level GUI and I/O module (highgui)―which provides functions to access media devices such as cameras and graphical user interfaces―is platform-dependent and can’t be compiled to the Web. Those functions, however, have alternatives using HTML5 primitives, which are provided by a JavaScript module (utils.js). This works, for instance, to access files hosted on the Web and media devices through getUserMedia and to display graphics using HTML Canvas*." – Dan Mašek Mar 29 '21 at 13:04
  • @VáclavHrbek: Please, make the error log **consistent** with your (edited) code. That is, run compilation again, and copy paste the resulted log. – Tsyvarev Mar 29 '21 at 13:07
  • Correction, `imread` isn't from `highgui`, but from `imgcodecs`, but I suspect that since it interacts with the file system, it's missing for similar reason. – Dan Mašek Mar 29 '21 at 13:10
  • 1
    @DanMašek: Ok, so the problem is actually specific to emscripten. I have reopened the question. Feel free to provide the answer. – Tsyvarev Mar 29 '21 at 13:11

1 Answers1

0

This is not a problem with includes, since opencv2/opencv.hpp automagically pulls in all the module top-level headers if the modules are available. The obvious conclusion is that those modules are not available in your build of OpenCV, and now the question is why is that the case?

As it turns out, some of the OpenCV functionality is not suitable for Web, and opencv.js is built without it.

The functions cv::namedWindow, cv::imshow and cv::waitKey belong to the highgui module. The implementation of this module is platform-dependent (at build time you have to select the backend that will be used, be it WinAPI, WinRT, Gtk, Qt, cocoa, etc.). Furthermore, since (AFAIK) the JavaScript code in the browser runs in a sandbox, it would be impossible to access to APIs anyway.

The function cv::imread belongs to the imgcodecs module, yet another one that is not built in this case. I don't know the exact reason for this (perhaps due to some of it directly accessing filesystem), and the issue https://github.com/opencv/opencv/issues/17535 indicates that the third party codecs haven't been integrated into opencv.js and some mechanisms are missing from the binding generator.

Dan Mašek
  • 17,852
  • 6
  • 57
  • 85