Skip to content

Compile evision from source

Cocoa edited this page Feb 14, 2024 · 1 revision

Dependencies

  • Python3 (Only during the compilation, to generate binding files)

    • 3.8.12
    • 3.9.9
    • 3.10.1
  • CMake >= 3.3 (for this project)

    The minimal version required by OpenCV can vary between versions.

    OpenCV 4.5.5 requires at least CMake 3.5.1.

  • Erlang development library/headers. Tested on OTP/25 and OTP/26.

Build from source

To obtain and compile OpenCV's source code from official releases, the following environment variables can affect the build

# optional
## set OpenCV version
##   the corresponding license file should be available at https://github.com/opencv/opencv/blob/${OPENCV_VER}/LICENSE
export OPENCV_VER="4.9.0"

# optional
## Use Debug build
export CMAKE_BUILD_TYPE=Debug

# optional
## enable FFmpeg
##   this will allow cmake to auto-detect FFmpeg libraries installed on the host
##   on Windows, OpenCV will download prebuilt FFmpeg libraries
##   for more information, please visit https://github.com/opencv/opencv/tree/4.x/3rdparty/ffmpeg
export CMAKE_OPENCV_OPTIONS="-D WITH_FFMPEG=ON"
## or disable FFmpeg
export CMAKE_OPENCV_OPTIONS="-D WITH_FFMPEG=OFF"

Note 1: OpenCV can encode and decode some video formats (varies depending on your system). FFmpeg can be used to encode/decode more video formats.

However, you should be aware of the license of the FFmpeg components you selected as they could be licensed by LGPL/GPL or other licenses.

Note 2: Installing FFmpeg

On DEBIAN/Ubuntu

sudo apt install -y libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev ffmpeg

on macOS

# FFmpeg 4
brew install ffmpeg@4
brew link ffmpeg@4

# FFmpeg 5
brew install ffmpeg
brew link ffmpeg
Extra notes for building from source on Windows

Evision on Windows uses nmake to handle the Makefile.win at the moment. And we also need powershell for now. nmake should be included in Microsoft Visual Studio, and powershell should be included in almost all recent versions (it was first released in 2007) of Windows.

If ninja can be found in %PATH%, then we will prefer using ninja to build everything as it allows parallel building.

Evision is NOT tested in MSYS2, Cygwin, or WSL/WSL2.

Using source from a git repo (Optional)

It's also possible to obtain and compile OpenCV's source code from a custom git repo by setting the following environment variables (in addition to the ones above)

# required if and only if you prefer to compile OpenCV from a git repo
# set OPENCV_USE_GIT_HEAD to true to compile OpenCV from a git repo
# default value is false
export OPENCV_USE_GIT_HEAD=true

# required if and only if you prefer to compile OpenCV from a git repo
# this env var indicates which branch you prefer to use
# no default value
export OPENCV_USE_GIT_BRANCH=4.x

# optional.
# set this env var to specify which git repo to use
# default value is https://github.com/opencv/opencv.git, which is the official git repo of OpenCV
export OPENCV_GIT_REPO="https://github.com/opencv/opencv.git"

When OPENCV_USE_GIT_HEAD is set to true, the following command will be used to fetch OpenCV's source code in Makefile:

git clone --branch=${OPENCV_USE_GIT_BRANCH} --depth=1 ${OPENCV_GIT_REPO} "${OPENCV_DIR}"

More Configuration (Optional)

evision will compile a subset of OpenCV functionality. You can configure the enabled modules in your config files:

config :evision, enabled_modules: [
  :calib3d,
  :core,
  :features2d,
  :flann,
  :highgui,
  :imgcodecs,
  :imgproc,
  :ml,
  :photo,
  :stitching,
  :ts,
  :video,
  :videoio,
  :dnn
]

If a module is not specified in :enabled_modules, it may still be compiled if all requirements are present in your machine. You can enforce only the :enabled_modules to be compiled by changing the compilation mode:

config :evision, :compile_mode, :only_enabled_modules

You can also configure the list of image codecs used:

config :evision, enabled_img_codecs: [
  :png,
  :jpeg,
  :tiff,
  :webp,
  :openjpeg,
  :jasper,
  :openexr
]

Notes

  • How do I use my own OpenCV source code on my local disk?

    # To skip the download process, you can put the source zip file at `3rd_party/cache/opencv-${OPENCV_VER}.zip`.
    # Or you could supply OpenCV source code at `3rd_party/opencv/opencv-${OPENCV_VER}`.
    #
    # `3rd_party/opencv/opencv-${OPENCV_VER}` is the default value for `OPENCV_DIR`
    export OPENCV_DIR=/path/to/your/opencv/source/root
  • How do I use my own OpenCV source code on my git repo?

    # use branch
    export OPENCV_USE_GIT_BRANCH="branch_name"
    export OPENCV_GIT_REPO="https://github.com/username/opencv.git"
    
    # use HEAD
    export OPENCV_USE_GIT_HEAD=true
    export OPENCV_GIT_REPO="https://github.com/username/opencv.git"
  • How do I test for a new pre-release of OpenCV?

    Suppose that OpenCV has a new pre-release (usually a new tagged version), 4.9.0, then you need to do the following to test and maybe also add/change some lines so that the new version is usable.

    First of all, disable using precompiled binaries.

    export EVISION_PREFER_PRECOMPILED=false

    Then set to use source code from GitHub.

    export OPENCV_USE_GIT_HEAD=true
    export OPENCV_USE_GIT_BRANCH=4.9.0
    
    export OPENCV_CONTRIB_USE_GIT_HEAD=true
    export OPENCV_CONTRIB_USE_GIT_BRANCH=4.9.0

    After that, we can try to build it. Usually, this is likely to fail without any changes to the source code in the evision library. I'll mention possible fixes for that in a minute.

    rm -rf _build/test/lib/evision
    export MIX_ENV=test
    iex -S mix
  • Troubleshooting pre-release versions of OpenCV

    1. unknown type name 'XXXXXXXX_Params'

      When you see error messages like:

      In file included from /home/runner/evision/c_src/evision.cpp:2373:
      /home/runner/evision/c_src/evision_generated_funcs.h:3685:5: error: unknown type name 'TrackerVit_Params'
          TrackerVit_Params parameters=TrackerVit::Params();
      

      That usually means we need to copy some headers from OpenCV's source code for compatibilties. You can find them in

      3rd_party/opencv/opencv-${OPENCV_VER}/modules/${MODULE_NAME}/misc/python/
      

      where ${OPENCV_VER} is the version name and ${MODULE_NAME} is the corresponding module of that XXXXX_Params. To find the corresponding module of XXXXX_Params, one good way is to search the OpenCV source code. In this example, TrackerVit is in the video module:

      $ cd 3rd_party/opencv/opencv-4.9.0/modules/
      $ rg --no-ignore 'TrackerVit::Params'
      video/src/tracking/tracker_vit.cpp
      24:TrackerVit::Params::Params()
      43:    TrackerVitImpl(const TrackerVit::Params& parameters)
      60:    TrackerVit::Params params;
      210:Ptr<TrackerVit> TrackerVit::create(const TrackerVit::Params& parameters)
      216:Ptr<TrackerVit> TrackerVit::create(const TrackerVit::Params& parameters)
      
      video/include/opencv2/video/tracking.hpp
      914:    @param parameters vit tracker parameters TrackerVit::Params
      917:    Ptr<TrackerVit> create(const TrackerVit::Params& parameters = TrackerVit::Params());
      
      video/test/test_trackers.cpp
      166:    cv::TrackerVit::Params params;

      However, as the time of writing, OpenCV's official source didn't add TrackerVit::Params to

      3rd_party/opencv/opencv-4.9.0/modules/video/misc/python/pyopencv_video.hpp

      So we can either say this pre-release version is not ready for evision, or we can simply add some lines in evision's codebase to fix it. For this particular issue, we can edit this file:

      c_src/evision_custom_headers/evision_video.hpp
      

      and add the following lines to it.

      #if (CV_VERSION_MAJOR >= 4 && CV_VERSION_MINOR >= 9)
      typedef TrackerVit::Params TrackerVit_Params;
      #endif
  • How do I set the number of jobs for compiling?

    # use all logical cores, by default
    # `"-j#{System.schedulers_online()}"`. In `mix.exs`.
    export MAKE_BUILD_FLAGS="-j$(nproc)"
    
    # use 2 cores
    export MAKE_BUILD_FLAGS="-j2"
  • How do I set up for cross-compile or specify the toolchain?

    export CMAKE_TOOLCHAIN_FILE="/path/to/toolchain.cmake"
  • How do I make my own adjustments to the OpenCV CMake options?

    export CMAKE_OPENCV_OPTIONS="YOUR CMAKE OPTIONS FOR OPENCV"
  • How do I generate binding code for erlang and Elixir at the same time? Yes, but currently it's only possible to do so when compiling evision using mix.

    # default value is `elixir` when compiling evision using `mix`
    # default value is `erlang` when compiling evision using `rebar`
    #
    # expected format is a comma-separated string
    export EVISION_GENERATE_LANG="erlang,elixir"
  • Which ones of OpenCV options are supposed to be specified in config/config.exs?

    1. Enabled and disabled OpenCV modules
    2. Image codecs (if you enabled related OpenCV modules).

Debug related

Say you have the following MIX environment variables:

# set by MIX
MIX_ENV=dev
# set by evision or you
OPENCV_VER=4.9.0
# set by yourself if you're compiling evision to a nerves firmware
MIX_TARGET=rpi4
  • How do I delete OpenCV related CMake build caches?

    # delete OpenCV related CMake build caches.
    rm -rf "_build/${MIX_ENV}/lib/evision/cmake_opencv_${OPENCV_VER}"
    ## for nerves
    rm -rf "_build/${MIX_TARGET}_${MIX_ENV}/lib/evision/cmake_opencv_${OPENCV_VER}"
  • How do I remove downloaded OpenCV source zip file.

    rm -f "3rd_party/cache/opencv-${OPENCV_VER}"
  • Can I manually edit the generated files and compile them?

    1. First, delete evision.so (so that cmake can rebuild it)

      # 
      rm -f "_build/${MIX_ENV}/lib/evision/priv/evision.so"
      ## if you're building with nerves,
      ## use this path instead
      rm -rf "_build/${MIX_TARGET}_${MIX_ENV}/lib/evision/priv/evision.so"
    2. Secondly, comment out the following lines in the CMakeLists.txt

    otherwise, your editing will be overwritten by the py_src/gen2.py (executing from the CMakeLists.txt)

    if(WIN32)
        execute_process(COMMAND "rmdir ${GENERATED_ELIXIR_SRC_DIR} /s /q && rmdir ${GENERATED_ERLANG_SRC_DIR} /s /q  && mkdir ${GENERATED_ELIXIR_SRC_DIR} && mkdir ${GENERATED_ERLANG_SRC_DIR}")
        message("enabled modules: ${ENABLED_CV_MODULES}")
        execute_process(COMMAND python3.exe "${PY_SRC}\\gen2.py" "${C_SRC}" "${GENERATED_ELIXIR_SRC_DIR}" "${GENERATED_ERLANG_SRC_DIR}" "${C_SRC}\\headers.txt" "${EVISION_GENERATE_LANG}" "${ENABLED_CV_MODULES}" RESULT_VARIABLE STATUS)
    else()
        execute_process(COMMAND bash -c "rm -rf ${GENERATED_ELIXIR_SRC_DIR} && rm -rf ${GENERATED_ERLANG_SRC_DIR} && mkdir -p ${GENERATED_ELIXIR_SRC_DIR} && mkdir -p ${GENERATED_ERLANG_SRC_DIR}")
        message("enabled modules: ${ENABLED_CV_MODULES}")
        execute_process(COMMAND bash -c "python3 ${PY_SRC}/gen2.py ${C_SRC} ${GENERATED_ELIXIR_SRC_DIR} ${GENERATED_ERLANG_SRC_DIR} ${C_SRC}/headers.txt ${EVISION_GENERATE_LANG} ${ENABLED_CV_MODULES}" RESULT_VARIABLE STATUS)
    endif()
    if(STATUS STREQUAL "0")
        message(STATUS "Successfully generated binding code for: ${EVISION_GENERATE_LANG}")
    else()
        message(FATAL_ERROR "Failed to generate binding code for: ${EVISION_GENERATE_LANG}")
    endif()
    1. Then you can edit the source files and recompile evision.so.
    mix compile

Runtime related

  • How do I enable debug logging for OpenCV (prints to stderr).

    export OPENCV_EVISION_DEBUG=1