-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: Restore MATLAB Module Compilation for OpenCV 4.x #3898
base: 4.x
Are you sure you want to change the base?
Conversation
Fixes related to optflow and xphoto, whose namespace have changed since 4.0.0-rc, and therefore deprecated the 'matlab' module
@CodeHotel Thanks a lot for the contribution. Could you add your build steps to the PR description. I want to try the patch. |
@asmorkalov Thanks for the review. I’ll post the build steps as a comment to keep them separate, as there may be future adjustments. |
Additional clarification: This PR is to ensure that the MATLAB module compiles successfully. I forgot to mention I have not yet run tests specifically designed for the matlab module. I have added such clarification to the main PR description |
Added fix in order to address previously unresolved issue when building in environments with python 3.10+. Modified so that this fix does not effect 3.9 or less.
@asmorkalov Hardware DetailsThe following hardware was used for testing the OpenCV MATLAB module compilation:
These specifications were used for both Ubuntu 22.04 and RHEL 9.1 testing. Ubuntu 22.04I have fully reinstalled ubuntu 22.04 and tested build 2 times using the below scripts. Package setupI tried to seamlessly include as much modules, features, libraries as possible with testing in mind. [script] Click to expand#!/bin/bash
# This script installs all dependencies and clones repositories necessary for testing
# Run this script in minimal ubuntu installation (was made for and tested in actual installation, not docker)
# It also acts as a dependency package list (full package list of the environment that I used)
# Almost all modules and features, excluding js, julia, ovis(ogre3d), vtk, qt will build
# IMPORTANT : Before running the script, please set below
USE_CUDA=1 # Change to 0 to skip CUDA installation. Modification of below code according to your architecture version may be required
USE_VTK=0 # libtbb2 is known to conflict with libtbb in ubuntu 22.04, therefore non compatible with vtk
# Paths to install NVidia Video Codec SDK
NV_CUVID_ZIP_NAME="Video_Codec_SDK_12.1.14" # Exclude '.zip' + This MUST be manually downloaded to the script's directory
NV_CUVID_INC_PATH=/usr/local/cuda-12.4/include
NV_CUVID_LIB_PATH=/usr/local/cuda-12.4/lib64
set -xe
trap 'echo "Error on line $LINENO"; exit 0' ERR
SHDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# This keeps sudo active for the rest of installation. Remove if needed when root (e.g. Docker)
cat $SHDIR/.sudo_passwd | sudo -S -v
while true; do cat $SHDIR/.sudo_passwd | sudo -S -v; sleep 30; done &
sudo apt update
if [ "$USE_CUDA" -eq 1 ]; then
# If needed, modify this according to your own hardware
echo "Installing CUDA keyring..."
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update
CUDA_PACKAGES="cuda-drivers cuda-toolkit-12-4 libcudnn8 libcudnn8-dev libcudnn8-samples"
else
CUDA_PACKAGES=""
fi
if [ "$USE_VTK" -eq 1 ]; then
sudo apt remove -y libtbb2
TBB_PACKAGES="libtbb-dev libvtk9-dev"
else
sudo apt remove -y libtbb-dev
TBB_PACKAGES="libtbb2 libtbb2-dev"
fi
# I tried to minimze this list using dependency/suggested/recommended tree
sudo apt full-upgrade -y apt-rdepends btop cmake \
xfce4 $CUDA_PACKAGES \
flake8 git pylint \
openjdk-11-jdk python3-numpy python3.10-dev \
unzip vim \
libavformat-dev libavif-dev libceres-dev libdc1394-dev \
libgstreamer-plugins-base1.0-dev libgtk-3-dev libgtkglext1-dev \
libhdf5-dev liblapacke-dev libopenblas-dev libswscale-dev \
$TBB_PACKAGES libtesseract-dev libva-dev
# Install video codec sdk
if [ "$USE_CUDA" -eq 1 ]; then
unzip $NV_CUVID_ZIP_NAME.zip
sudo cp $NV_CUVID_ZIP_NAME/Interface/nvcuvid.h $NV_CUVID_INC_PATH
sudo cp $NV_CUVID_ZIP_NAME/Interface/nvEncodeAPI.h $NV_CUVID_INC_PATH
sudo cp $NV_CUVID_ZIP_NAME/Interface/cuviddec.h $NV_CUVID_INC_PATH
sudo cp $NV_CUVID_ZIP_NAME/Lib/linux/stubs/x86_64/libnvcuvid.so $NV_CUVID_LIB_PATH
sudo cp $NV_CUVID_ZIP_NAME/Lib/linux/stubs/x86_64/libnvidia-encode.so $NV_CUVID_LIB_PATH
sudo ldconfig
fi
if [ -d "$SHDIR/opencv" ]; then
echo "[ WARNING ] $SHDIR/opencv already exists. Skipping cloning."
else
echo "Cloning OpenCV repository into $SHDIR/opencv."
cd $SHDIR
git clone https://github.com/opencv/opencv.git
cd opencv
git fetch --tags
git checkout 4.11.0
cd ..
fi
if [ -d "$SHDIR/opencv_contrib" ]; then
echo "[ WARNING ] $SHDIR/opencv_contrib already exists. Skipping cloning."
else
echo "Cloning OpenCV contrib repository into $SHDIR/opencv_contrib."
cd "$SHDIR"
git clone https://github.com/CodeHotel/opencv_contrib.git
cd opencv_contrib
git checkout matlab-build-fix-4.11.0
cd $SHDIR
fi
# Restart to load correct nv firmware
if [ "$USE_CUDA" -eq 1 ]; then
sudo reboot now
fi Setup MATLABMatlab has a GUI installer, which is the reason why I included xfce in above script. sudo ./install In terminal within the xfce wm session. Configure CMake and buildResets configurations, configures, and builds. [script] Click to expand#!/bin/bash
set -x
# This Script sets the build configs for opencv compilation.
# Please set correct variables below :
BUILD_CUDA=1
CUDA_ARCH_NUMBER=8.9
export CXXFLAGS="-O0 -fno-lto -w"
export CFLAGS="-O0 -fno-lto -w"
SHDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
OUTDIR="$SHDIR/pr-build-out" # Build directory
# Resets build output directory
[ -d "$OUTDIR" ] && rm -rf $OUTDIR
mkdir $OUTDIR
cd $OUTDIR
# Set CUDA variables
if [ "$BUILD_CUDA" -eq 1 ]; then
CUDA_FLAGS="
-D WITH_CUDA=ON \
-D CUDA_ARCH_BIN=$CUDA_ARCH_NUMBER \
-D WITH_CUDNN=ON \
-D OPENCV_DNN_CUDA=ON \
-D CUDA_FAST_MATH=ON \
-D WITH_CUBLAS=ON \
-D WITH_CUFFT=ON"
else
CUDA_FLAGS=""
fi
# Quick fix for ubuntu 22.04 openblas and openblas-lapack header detection
OPENBLAS_INCLUDE=$(find /usr -type f -name "cblas.h" 2>/dev/null | grep "pthread" | head -n 1 | xargs dirname)
OPENBLAS_LIB=$(find /usr -type f -name "libopenblas*.so" 2>/dev/null | grep "pthread" | head -n 1)
BLAS_FLAGS=""
if [ -n "$OPENBLAS_INCLUDE" ]; then
BLAS_FLAGS+=" -DOpenBLAS_INCLUDE_DIR=$OPENBLAS_INCLUDE"
fi
if [ -n "$OPENBLAS_LIB" ]; then
BLAS_FLAGS+=" -DOpenBLAS_LIB=$OPENBLAS_LIB"
fi
LAPACKE_HEADERS=("lapacke.h" "lapacke_config.h" "lapacke_mangling.h" "lapacke_utils.h")
LAPACKE_DIR="/usr/include"
TARGET_DIR="$OPENBLAS_INCLUDE"
if [ -d "$TARGET_DIR" ]; then
for header in "${LAPACKE_HEADERS[@]}"; do
SOURCE_PATH="$LAPACKE_DIR/$header"
TARGET_PATH="$TARGET_DIR/$header"
if [ -f "$SOURCE_PATH" ]; then
if [ ! -L "$TARGET_PATH" ]; then
echo "Creating symlink for $header in $TARGET_DIR"
sudo ln -s "$SOURCE_PATH" "$TARGET_PATH"
fi
fi
done
else
echo "Warning: OpenBLAS include directory not found. Skipping LAPACKE symlink creation."
fi
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-DBUILD_opencv_world=OFF \
-D BUILD_TESTS=ON \
-D BUILD_PERF_TESTS=ON \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=ON \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D BUILD_JAVA=ON \
-D WITH_TBB=ON \
-D WITH_IPP=ON \
$BLAS_FLAGS \
$CUDA_FLAGS \
-D ENABLE_FAST_MATH=ON \
-D WITH_OPENGL=ON \
-D WITH_V4L=ON \
-D WITH_FFMPEG=ON \
-D BUILD_NEW_PYTHON_SUPPORT=ON \
-D WITH_QT=ON \
-D WITH_GTK=ON \
-D WITH_IMGCODEC_GIF=ON \
-D BUILD_WITH_DEBUG_INFO=OFF \
-D BUILD_opencv_python3=ON \
-D WITH_MATLAB=ON \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_ENABLE_NONFREE=ON \
-D OPENCV_EXTRA_MODULES_PATH=$SHDIR/opencv_contrib/modules \
$SHDIR/opencv \
2>&1 | tee config.log
echo "Configuration outputs logged to $OUTDIR/config.log"
read -p "Proceed to build? (y/n): " answer
if [[ "${answer,,}" == "y" ]]; then
make -j$(nproc) | tee build.log
else
cd $SHDIR
exit 0
fi
cd $SHDIR
exit 0 I will also post the config.log as a reference: [log] Click to expand
RHEL 9.1This script was for my own personal use, and therefore is not as organized and tailored as the ubuntu script, and is quite messy. Setup script 1[script] Click to expand#!/bin/bash
set -xe
trap 'echo "Error on line $LINENO"; exit 0' ERR
SHDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# This keeps sudo active for the rest of installation. Remove if needed when root (e.g. Docker)
cat $SHDIR/.sudo_passwd | sudo -S -v
while true; do cat $SHDIR/.sudo_passwd | sudo -S -v; sleep 30; done &
# Use sudo with stored password
sudo subscription-manager release --set=9.1
# Add repositories
sudo subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
sudo dnf -y install https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm
sudo dnf -y install https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-9.noarch.rpm
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo
# Install the latest available kernel
sudo dnf -y install kernel kernel-core kernel-devel kernel-headers
# Stop sudo keep-alive (cleanup)
exit 0 Setup Script 2[script] Click to expand#!/bin/bash
set -xe
trap 'echo "Error on line $LINENO"; exit 0' ERR
SHDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# This keeps sudo active for the rest of installation. Remove if needed when root (e.g. Docker)
cat $SHDIR/.sudo_passwd | sudo -S -v
while true; do cat $SHDIR/.sudo_passwd | sudo -S -v; sleep 30; done &
# Prepare docker install
sudo systemctl stop podman
sudo dnf remove -y podman
sudo rm -rf /var/lib/docker /var/lib/containerd /var/lib/podman
sudo systemctl daemon-reload
# Add Docker dependencies and clean DNF cache
sudo dnf -y install dnf-plugins-core
sudo dnf -y clean all
# Install NVIDIA driver
sudo dnf -y module install nvidia-driver:latest-dkms
# Install all required packages
sudo dnf install -y cmake \
gtk2-devel \
gtk3-devel \
gtkglext-devel \
ccache \
ceres-solver-devel \
suitesparse-devel \
xine-lib xine-lib-devel \
metis metis-devel \
mesa-libGL-devel mesa-libEGL-devel \
libcudnn8* \
cuda-toolkit-12-4 \
docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin \
gstreamer1-devel gstreamer1-plugins-base-devel \
eigen3-devel \
lapack-devel \
java-11-openjdk-devel ant \
nasm \
giflib-devel \
libva-devel \
hdf5-devel \
python3-devel \
python3-numpy \
libavif \
libavif-devel \
libjpeg-turbo-devel \
openblas-devel \
lapack-devel \
alsa-lib-devel SDL2-devel \
ffmpeg-devel ffmpeg \
qt5 qt5-devel \
rpm-build rpmdevtools rpmlint \
doxygen \
python3-pip \
tesseract-devel \
gflags gflags-devel \
glog glog-devel \
tbb tbb-devel \
pybind11-devel python3-pybind11 \
python3-jinja2 \
libedit-devel ncurses-devel swig python3-devel lua-devel perl-core ninja-build texlive-epstopdf texlive-epstopdf \
htop btop nmon
# Setup TensorRT
tar -xzvf TensorRT-8.6.1.6.Linux.x86_64-gnu.cuda-12.0.tar.gz
sudo mv TensorRT-8.6.1.6 /usr/local/TensorRT
echo '/usr/local/TensorRT/lib' | sudo tee /etc/ld.so.conf.d/tensorrt.conf
sudo ldconfig
sudo python3 -m pip install /usr/local/TensorRT/python/tensorrt-*-cp39-none-linux_x86_64.whl
# Setup llvm and bazel
sudo ./install-llvm
sudo ./install-bazel
# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
# Confirm Docker installation
sudo docker run hello-world
sudo docker pull tensorflow/build:2.17-python3.9
echo "Docker and TensorFlow GPU image setup completed successfully."
docker --version
sudo docker images
# Set CUDA vars
sudo tee /etc/profile.d/cuda-env.sh > /dev/null <<EOL
# CUDA
export PATH=/usr/local/cuda-12.4/bin:\$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:\$LD_LIBRARY_PATH
# cuDNN
export LD_LIBRARY_PATH=/usr/lib64:\$LD_LIBRARY_PATH
# TensorRT
export LD_LIBRARY_PATH=/usr/local/TensorRT/lib:\$LD_LIBRARY_PATH
export PYTHONPATH=/usr/local/TensorRT/python:\$PYTHONPATH
# Common NVIDIA Paths
export CUDA_HOME=/usr/local/cuda-12.4
export CUDNN_HOME=/usr/lib64
export TENSORRT_HOME=/usr/local/TensorRT
EOL
sudo chmod +x /etc/profile.d/cuda-env.sh
source /etc/profile.d/cuda-env.sh
echo "/usr/local/cuda-12.4/lib64" | sudo tee /etc/ld.so.conf.d/cuda.conf
echo "/usr/lib64" | sudo tee /etc/ld.so.conf.d/cudnn.conf
echo "/usr/local/TensorRT/lib" | sudo tee /etc/ld.so.conf.d/tensorrt.conf
sudo ldconfig
# Cuda vars for matlab
echo "NVIDIA_CUDNN=/usr" | sudo tee -a /etc/environment
echo "NVIDIA_TENSORRT=/usr/local/TensorRT" | sudo tee -a /etc/environment
# Test CUDA installation
nvcc -V
# Stop sudo keep-alive (cleanup)
exit 0 # Exiting script ensures the `sudo -v` loop stops Prepare opencv installation[script] Click to expand#!/bin/bash
set -xe
trap 'echo "Error on line $LINENO"; exit 0' ERR
SHDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# This keeps sudo active for the rest of installation. Remove if needed when root (e.g. Docker)
cat $SHDIR/.sudo_passwd | sudo -S -v
while true; do cat $SHDIR/.sudo_passwd | sudo -S -v; sleep 30; done &
# Remove existing mpg123 package
sudo dnf -y remove mpg123
# Extract the source tarball
tar -xvf mpg123-1.32.10.tar.bz2
cd mpg123-1.32.10/
# Configure with optimizations
CFLAGS="-march=native -O3" CXXFLAGS="-march=native -O3" ./configure --prefix=/usr --with-cpu=generic --enable-id3v2 --enable-feature-report --enable-newoldwritesample
# Compile and install
make
sudo make install
# Return to previous directory
cd ..
# Force qt5-qtwebkit deps in order to install vtk
sudo dnf -y remove qt5-qtwebkit
dnf download --nobest qt5-qtwebkit
sudo rpm -ivh --nodeps qt5-qtwebkit-*.rpm
sudo dnf -y install vtk vtk-devel
wget https://developer.nvidia.com/downloads/designworks/video-codec-sdk/secure/12.1/video_codec_sdk_12.1.14.zip
unzip Video_Codec_SDK_12.1.14.zip
VENC_PATH=/usr/local/cuda/include
sudo cp Video_Codec_SDK_12.1.14/Interface/nvcuvid.h /usr/local/cuda/include/
sudo cp Video_Codec_SDK_12.1.14/Interface/nvEncodeAPI.h /usr/local/cuda/include/
sudo cp Video_Codec_SDK_12.1.14/Interface/cuviddec.h /usr/local/cuda/include/
sudo cp Video_Codec_SDK_12.1.14/Lib/linux/stubs/x86_64/libnvcuvid.so /usr/local/cuda/lib64/
sudo cp Video_Codec_SDK_12.1.14/Lib/linux/stubs/x86_64/libnvidia-encode.so /usr/local/cuda/lib64/
sudo ldconfig
sudo pip3 install bs4 pylint flake8
# Define the directory
DIR="cv_cuda"
# Check if the directory exists
if [ -d "$DIR" ]; then
echo "$DIR already exists. Skipping cloning."
else
echo "Creating $DIR and cloning OpenCV repositories."
mkdir $DIR
cd $DIR
git clone https://github.com/opencv/opencv.git
git clone https://github.com/CodeHotel/opencv_contrib.git
# Checkout to rel4.11 in opencv
cd opencv
git fetch --tags
git checkout 4.11.0
cd ..
# Checkout to rel4.11 in opencv_contrib
cd opencv_contrib
git checkout matlab-build-fix-4.11.0
cd ../..
fi
exit 0 Configure CMake#!/bin/bash
set -x
cd cv_cuda
[ -d "release_general" ] && rm -rf release_general
mkdir release_general
cd release_general
export CXXFLAGS="-O3 -march=native -mtune=native -fno-lto -w"
export CFLAGS="-O3 -march=native -mtune=native -fno-lto -w"
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-DBUILD_opencv_world=OFF \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
-D BUILD_JAVA=ON \
-D WITH_LAPACK=ON \
-D WITH_TBB=ON \
-D WITH_IPP=ON \
-D WITH_CUDA=ON \
-D CUDA_ARCH_BIN="8.9" \
-D WITH_CUDNN=ON \
-D OPENCV_DNN_CUDA=ON \
-D CUDA_FAST_MATH=ON \
-D ENABLE_FAST_MATH=ON \
-D WITH_CUBLAS=ON \
-D WITH_CUFFT=ON \
-D WITH_OPENGL=ON \
-D WITH_V4L=ON \
-D WITH_FFMPEG=ON \
-D WITH_XINE=ON \
-D BUILD_DOCS=ON \
-D BUILD_EXAMPLES=ON \
-D BUILD_TESTS=ON \
-D BUILD_PERF_TESTS=ON \
-D BUILD_NEW_PYTHON_SUPPORT=ON \
-D INSTALL_C_EXAMPLES=ON \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_QT=ON \
-D WITH_GTK=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
-D WITH_IMGCODEC_GIF=ON \
-D BUILD_WITH_DEBUG_INFO=OFF \
-D BUILD_opencv_python3=ON \
-D WITH_MATLAB=ON \
../opencv
cd ../.. |
This PR resolves a VERY long-standing issue where the
MATLAB
module in opencv_contrib fails to compile due to namespace changes incv::optflow
andcv::xphoto
. The MATLAB module has been broken since OpenCV 4.0.0-rc due to these changes, and this fix restores compilation compatibility.Issue Details
Namespace Changes
opencv
toopencv_contrib/optflow
, breaking references in the MATLAB module. This was done during4.0.0-beta
and4.0.0-rc
, but never reflected incv::matlab
cv::xphoto
also underwent similar changes, but I am yet to find the exact version such change was made in.collections.Iterable
was changed intocollections.abc.Iterable
, which causesparse_tree.py
to break. I added fixes for build to work for both versions.Reported Issues
Fix Implementation
make
andgcc
Request to Maintainers
I acknowledge that the MATLAB module has not been actively maintained for nearly 7 years, which, I find, is quite unusual for an active project like opencv.
If the devs do not intend to support the MATLAB module anymore, I request the maintainers to officially mark it as deprecated, or disable its inclusion using CMake scripts rather than leaving it in a permanently broken state.
Even if the PR is to be rejected, I hope at least a deprecation notice of the module will be considered.