OpenCV

如何引用

set(OpenCV_DIR /home/faceunity/Library/opencv-4.9.0/build/install/sdk/native/jni)
find_package(OpenCV REQUIRED)
target_link_libraries(main ${OpenCV_LIBS} ${log-lib})

C++

编译

Android native库

开启opencl支持 一般android手机中,libOpenCL.so是在/vendor/lib64文件夹中,所以不需要从别的地方下载。

# 这里的编译脚本都可以用来编译android native库。
export ANDROID_SDK=/home/faceunity/Programs/Android/SDK
export ANDROID_OPENCL_SDK=/home/faceunity/Library/opencl-android-sdk
export ANDROID_HOME=$ANDROID_SDK
export ANDROID_NDK_ROOT=/home/faceunity/Programs/Android/NDK/android-ndk-r26b
export ANDROID_ABI=arm64-v8a
export ANDROID_API=21
mkdir -p build
cd build

cmake ..  \
        -G "Unix Makefiles" \
        -DANDROID_STL=c++_static \
        -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
        -DANDROID_SDK=$ANDROID_SDK \
        -DANDROID_NDK=$ANDROID_NDK_ROOT \
        -DANDROID_HOME=$ANDROID_SDK \
        -DANDROID_TOOLCHAIN=clang \
        -DANDROID_ABI=$ANDROID_ABI \
        -DANDROID_NATIVE_API_LEVEL=$ANDROID_API \
        -DWITH_OPENCL=ON \
        -DANDROID_OPENCL_SDK=$ANDROID_OPENCL_SDK

Linux 库编译

常规编译

# install the dependencies. 为了使用videoio
# pkg-config用来找下面安装的库的,必须安装,否则相当于没有videoio依赖库
sudo apt install pkg-config
sudo apt install ffmpeg libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
# For GStreamer
sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
# build.sh
BUILD_DIR=build_linux
cmake -S . -B build_linux  \
        -G "Unix Makefiles" \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_CXX_FLAGS="-O3" \
        -DBUILD_SHARED_LIBS=OFF \
        -DENABLE_PRECOMPILED_HEADERS=OFF \
        -DWITH_FFMPEG=ON \
        -DWITH_PNG=ON \
        -DWITH_JPEG=ON \
        -DCMAKE_INSTALL_PREFIX=./${BUILD_DIR}/install
# 在编译之前,可以看一下generate summary,看功能是否完整开启。
cmake --build build_linux -j16

cuda支持

# DOPENCV_EXTRA_MODULES_PATH需要从网上下载。
cmake -S . -B build_linux  \
        -G "Unix Makefiles" \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_CXX_FLAGS="-O3" \
        -DOPENCV_EXTRA_MODULES_PATH=$(realpath ./opencv_contrib-4.5.1/modules) \
        -DBUILD_SHARED_LIBS=ON \
        -DENABLE_PRECOMPILED_HEADERS=ON \
        -DWITH_FFMPEG=ON \
	    -DWITH_TBB=ON \
        -DWITH_PNG=ON \
        -DWITH_JPEG=ON \
        -DWITH_CUDA=ON \
        -DWITH_CUDNN=ON \
        -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda \
        -DFFMPEG_INCLUDE_DIR=/usr/include \
        -DFFMPEG_LIB_DIR=/usr/lib/x86_64-linux-gnu \
        -DCMAKE_INSTALL_PREFIX=./${BUILD_DIR}/install

Dockerfile编译安装

# 如果开启了ffmpeg,需要结合ffmpeg的编译安装或者cmake的编译安装
RUN apt update 
ENV TZ=Asia/Shanghai
RUN ln -fs /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt install --no-install-recommends -y build-essential cmake

RUN wget -P /tmp https://github.com/opencv/opencv/archive/refs/tags/4.5.1.tar.gz && \
    mv /tmp/4.5.1.tar.gz /tmp/opencv.tar.gz && \
    wget -P /tmp https://github.com/opencv/opencv_contrib/archive/refs/tags/4.5.1.tar.gz && \
    mv /tmp/4.5.1.tar.gz /tmp/opencv_contrib.tar.gz && \
    cd /tmp && mkdir /tmp/opencv_contrib && tar -xf opencv_contrib.tar.gz -C /tmp/opencv_contrib --strip-components=1 && \
    mkdir /tmp/opencv && tar -xf /tmp/opencv.tar.gz -C /tmp/opencv --strip-components=1 && \
    cd /tmp/opencv && \
    cmake -S . -B build_linux -G "Unix Makefiles" \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_CXX_FLAGS="-O3" \
    -DOPENCV_EXTRA_MODULES_PATH=/tmp/opencv_contrib/modules \
    -DBUILD_SHARED_LIBS=ON \
    -DENABLE_PRECOMPILED_HEADERS=ON \
    -DWITH_FFMPEG=ON \
    -DWITH_TBB=ON \
    -DWITH_V4L=ON \
    -DBUILD_TIFF=ON \
    -DWITH_EIGEN=OFF \
    -DWITH_PNG=ON \
    -DWITH_JPEG=ON \
    -DCMAKE_INSTALL_PREFIX=/usr/local && \
    cmake --build build_linux -j16 && cmake --build build_linux --target install && rm -rf /tmp/*

Windows

下载完opencv4.5.1之后,设置环境变量OPENCV_DIR=<opencv_dir>\build\x64\vc15\lib,随后CMake在编译的时候就能找到了

实现和特性

cv::Mat初始化

...
// 这样初始化的时候,opencv并不会进行拷贝,而是直接使用这块儿内存创建cv::Mat
cv::Mat mat(cv::Size(width, height), CV_8UC3, data_ptr);

常用代码片段

查看编译信息

cv::getBuildInformation()

获取仿射变换矩阵

// 通过旋转中心和旋转角度获取
double angle = 45.0;
cv::Point2f center(src.cols / 2, src.rows / 2);
cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, 1.0);
// 需要注意的是,这种方式获取的matrix是double的。

// 通过点获取
cv::Point2f srcQuad[4], dstQuad[4];
// 填充源和目标四边形的点
srcQuad[0] = cv::Point2f(0, 0);
srcQuad[1] = cv::Point2f(src.cols - 1, 0);
srcQuad[2] = cv::Point2f(src.cols - 1, src.rows - 1);
srcQuad[3] = cv::Point2f(0, src.rows - 1);

dstQuad[0] = cv::Point2f(src.cols * 0.05, src.rows * 0.33);
dstQuad[1] = cv::Point2f(src.cols * 0.9, src.rows * 0.25);
dstQuad[2] = cv::Point2f(src.cols * 0.8, src.rows * 0.9);
dstQuad[3] = cv::Point2f(src.cols * 0.2, src.rows * 0.7);
// 获取透视变换矩阵
cv::Mat warpMat = cv::getPerspectiveTransform(srcQuad, dstQuad);

Python

安装

pip install opencv-python

常见问题

VSCode提示无法正常运行

描述

比如这种情况,通常可能是安装了有冲突的库,导致pylance没法正常工作:

$ pip list | grep opencv
opencv-python           4.7.0.72
opencv-python-headless  4.7.0.72

这两个库是互斥的,它们都提供了名为 cv2 的 Python 模块,但是依赖和功能略有不同:

  • opencv-python:包含了完整的 OpenCV 库,并且包含了用于显示图像和视频的 GUI 功能(例如 cv2.imshow())。
  • opencv-python-headless:同样包含了完整的 OpenCV 库,但是不包含 GUI 功能。它主要用于服务器、Docker 容器等没有图形界面的环境。

解决办法

# 卸载所有库,然后重新安装
pip uninstall opencv-python opencv-python-headless
pip install opencv-python