【AVD】Linux 编译支持 Cuda 的 OpenCV 4.6,解决报错 throw_no_cuda

这篇具有很好参考价值的文章主要介绍了【AVD】Linux 编译支持 Cuda 的 OpenCV 4.6,解决报错 throw_no_cuda。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近在做视频镜头切换检测功能,需要用 OpenCV 计算某一帧图像的直方图,于是尝试着在 Linux 上编译安装 OpenCV。然而仅用软解码和 CPU 计算着实慢了些,所以就想使用 Cuda 计算来加速,然而调用时却报错说 function/feature is not implement,the called functionality is disabled for current build or platform in function ‘throw_no_cuda’,经过一番努力,总算是解决了这个问题。

Linux Ubuntu 编译安装 OpenCV

源码下载

通过官网链接(https://opencv.org/releases/)即可选择自己希望使用的版本来编译安装,这里,我们选择了 4.6.0,使用 GitHub ssh 链接 clone 到本地。

编译脚本

进入源码目录,看得到有个 CMakeLists.txt,因此使用 CMake 命令进行编译配置。参考网上其他文章,大致命令如下:

cmake . -Bbuild \ # CMake 使用当前目录(.) 下的 CMakeLists.txt 进行编译配置并将配置临时及最终文件放到新建文件夹 build 目录下
-DCMAKE_BUILD_TYPE=RELEASE \ # 使用 release 版本,可能会有一些优化
-DCMAKE_INSTALL_PREFIX=/usr/local \ # 指定安装目录
-DWITH_TBB=ON -DWITH_V4L=ON -DWITH_QT=OFF -DWITH_OPENGL=ON -DWITH_CUDA=ON \ # TBB V4L 是干啥滴,我也不清楚
-DCUDA_GENERATION="Auto" \ # 让编译脚本自动查询 Cuda 架构
-DENABLE_FAST_MATH=1 -DCUDA_FAST_MATH=1 -DCUDA_NVCC_FLAGS="-D_FORCE_INLINES" \
-DOPENCV_GENERATE_PKGCONFIG=1 # 这一句我在使用的时候没加,是用于生成 pc 文件的,以便支持 pkg-config 功能

执行上述命令后,会进行一堆测试,然后出现一个报错

CMake Error at modules/core/CMakeLists.txt:53 (message):
  CUDA: OpenCV requires enabled 'cudev' module from 'opencv_contrib'
  repository: https://github.com/opencv/opencv_contrib

这意思是,这需要使用到 opencv_contrib 包,需要从上述 github 库中把代码库 opencv_contrib 也克隆到本地,并且通过特定的指令告诉编译脚本这个位置,例如,我们将 opencv_contrib 和 opencv 源码并列放在同一目录下,于是,CMake 命令就变成了如下:

cmake . -Bbuild \ # CMake 使用当前目录(.) 下的 CMakeLists.txt 进行编译配置并将配置临时及最终文件放到新建文件夹 build 目录下
-DCMAKE_BUILD_TYPE=RELEASE \ # 使用 release 版本,可能会有一些优化
-DCMAKE_INSTALL_PREFIX=/usr/local \ # 指定安装目录
-DWITH_TBB=ON -DWITH_V4L=ON -DWITH_QT=OFF -DWITH_OPENGL=ON -DWITH_CUDA=ON \ # TBB V4L 是干啥滴,我也不清楚
-DCUDA_GENERATION="Auto" \ # 让编译脚本自动查询 Cuda 架构
-DENABLE_FAST_MATH=1 -DCUDA_FAST_MATH=1 -DCUDA_NVCC_FLAGS="-D_FORCE_INLINES" \
-DOPENCV_GENERATE_PKGCONFIG=1 # 这一句我在使用的时候没加,是用于生成 pc 文件的,以便支持 pkg-config 功能
-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules

执行之后会有一个清单打印出来,告诉你哪些模块支持了哪些东西。并且在最后会有一个

Configuring done
Genrating done
Build file have been written to: ....

然后进入 build 目录执行 make,并在 make -jn 这里的 n 我用的 41,完成之后执行 sudo make install 即可。n 用其他值也行,取决于你的 cpu 能力,小一些的值编译过程会慢一些,但是会稳定一些。

测试 Demo

参考 Github 工程 https://github.com/sam09/shot-detector 写了个利用 OpenCV 的 Demo 来验证是否能正常使用。
但是最开始编译到最后链接时貌似弹出了找不到 OpenCV 依赖库的错误,理论上我把它 install 到了 /usr/local/ 这个默认搜索路径下,应该是没问题的,但是的确使用 ldconfig -p | grep opencv 的时候,找不到任何结果,通过调用把 /usr/local/lib 这个路径放到 /etc/ld.so.conf.d/usr_local.conf 中之后重新调用 ldconfig,貌似解决了这个问题。
Demo 中有一句 cv::Ptr<cv::cudacodec::VideoReader> reader = cv::cudacodec::createVideoReader(url_);,在执行时报错如下:

OpenCV(4.6.0) /home/liuyike/Codes/Refs/opencv/modules/core/include/opencv2/core/private.cuda.hpp:112: 
error: (-213:The function/feature is not implemented) The called functionality is disabled for current 
build or platform in function 'throw_no_cuda'

很奇怪啊,明明 /usr/local/lib 目录下有 libopencv_cudacodec.so 等一堆 cuda 的 OpenCV 库,而且整个 Demo 的编译过程中也需要链接到一些 libopencv_cudaxxx.so,也都没有问题,怎么会在执行报错呢?

按图索骥

通过查看上述报错中提到的 prvate.cuda.hpp:112 行发现

// ...
#ifndef HAVE_CUDA

static inline CV_NORETURN void throw_no_cuda() { CV_Error(cv::Error::GpuNotSupported, "The library is compiled without CUDA support"); }

#else // HAVE_CUDA

#define nppSafeSetStream(oldStream, newStream) { if(oldStream != newStream) { cudaStreamSynchronize(oldStream); nppSetStream(newStream); } }

static inline CV_NORETURN void throw_no_cuda() { CV_Error(cv::Error::StsNotImplemented, "The called functionality is disabled for current build or platform"); }
// ...

它抛出的是第二个错误,The called functionality ...,也就是说,HAVE_CUDA 是成立的,那为啥有 CUDA 了,还要报这个错呢?于是我又找到 Demo 源码那句 cv::Ptr<cv::cudacodec::VideoReader> reader = cv::cudacodec::createVideoReader(url_); 在 OpenCV 中的源码实现,但它的具体实现并不在 OpenCV 源码中,而是在与它同目录的 opencv_contrib 目录下:

// opencv_contrib/modules/cudacodec/src/video_reader.cpp
#include "precomp.hpp"

using namespace cv;
using namespace cv::cuda;
using namespace cv::cudacodec;

#ifndef HAVE_NVCUVID

Ptr<VideoReader> cv::cudacodec::createVideoReader(const String&, const std::vector<int>&, const VideoReaderInitParams) { throw_no_cuda(); return Ptr<VideoReader>(); }
Ptr<VideoReader> cv::cudacodec::createVideoReader(const Ptr<RawVideoSource>&, const VideoReaderInitParams) { throw_no_cuda(); return Ptr<VideoReader>(); }

#else // HAVE_NVCUVID

这就不难发现了,如果 HAVE_NVCUVID 是 0,或者未定义过,那么就会抛出 no cuda 那个异常了。
那么,HAVE_NVCUVID 为啥未定义呢?全局搜索 HAVE_NVCUVID 发现,在 opencv/CMakeLists.txt 第 266 行写着:

OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" OFF  # disabled, details: https://github.com/opencv/opencv/issues/14850
  VISIBLE_IF WITH_CUDA
  VERIFY HAVE_NVCUVID)
OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" (NOT CV_DISABLE_OPTIMIZATION AND NOT CMAKE_CROSSCOMPILING)

这意思是说,WITH_NVCUVID 这个选项,默认是 OFF 的,那是谁把它 disable 了的呢?参见后面那个 Github 上的问题链接,貌似是有人发现编译后会有个问题,于是就把这个 默认选项置为 OFF 了。我们发现其他几个选项,例如 WITH_CUFFT WITH_CUBLAS WITH_CUDNN 的默认选项都是 WITH_CUDA,也就是说,只要你设置了 -DWITH_CUDA=ON,那么这些 cuda 相关的选项都会默认为 ON,唯独这个 WITH_NVCUVID。当然也有网友在那个问题链接下面吐槽为啥会合并了这样一个 mr。不过,我们需要做的是,给最开始的 CMake 命令里加上 -DWITH_NVCUVID=ON 这个参数。
这样,CMake 命令就变成了:

cmake . -Bbuild \ # CMake 使用当前目录(.) 下的 CMakeLists.txt 进行编译配置并将配置临时及最终文件放到新建文件夹 build 目录下
-DCMAKE_BUILD_TYPE=RELEASE \ # 使用 release 版本,可能会有一些优化
-DCMAKE_INSTALL_PREFIX=/usr/local \ # 指定安装目录
-DWITH_TBB=ON -DWITH_V4L=ON -DWITH_QT=OFF -DWITH_OPENGL=ON -DWITH_CUDA=ON \ # TBB V4L 是干啥滴,我也不清楚
-DCUDA_GENERATION="Auto" \ # 让编译脚本自动查询 Cuda 架构
-DENABLE_FAST_MATH=1 -DCUDA_FAST_MATH=1 -DCUDA_NVCC_FLAGS="-D_FORCE_INLINES" \
-DOPENCV_GENERATE_PKGCONFIG=1 # 这一句我在使用的时候没加,是用于生成 pc 文件的,以便支持 pkg-config 功能
-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
-DWITH_NVCUVID=ON

然后重新 make,make install,然后重新编译 Demo 执行,发现,报错仍在。问题仍未解决。

继续深究发现,如果全局搜索 WITH_NVCUVID 会发现,在 opencv/cmake/OpenCVDetectCUDA.cmake 这个脚本里第 56 行写着:

  if(WITH_NVCUVID)
    macro(ocv_cuda_SEARCH_NVCUVID_HEADER _filename _result)
      # place header file under CUDA_TOOLKIT_TARGET_DIR or CUDA_TOOLKIT_ROOT_DIR
      find_path(_header_result
        ${_filename}
        PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
        ENV CUDA_PATH
        ENV CUDA_INC_PATH
        PATH_SUFFIXES include
        NO_DEFAULT_PATH
        )
      if("x${_header_result}" STREQUAL "x_header_result-NOTFOUND")
        set(${_result} 0)
      else()
        set(${_result} 1)
      endif()
      unset(_header_result CACHE)
    endmacro()
    ocv_cuda_SEARCH_NVCUVID_HEADER("nvcuvid.h" HAVE_NVCUVID_HEADER)
    ocv_cuda_SEARCH_NVCUVID_HEADER("dynlink_nvcuvid.h" HAVE_DYNLINK_NVCUVID_HEADER)
    find_cuda_helper_libs(nvcuvid)
    if(WIN32)
      find_cuda_helper_libs(nvcuvenc)
    endif()
    if(CUDA_nvcuvid_LIBRARY AND (${HAVE_NVCUVID_HEADER} OR ${HAVE_DYNLINK_NVCUVID_HEADER}))
      # make sure to have both header and library before enabling
      set(HAVE_NVCUVID 1)
    endif()
    if(CUDA_nvcuvenc_LIBRARY)
      set(HAVE_NVCUVENC 1)
    endif()
  endif()

也就是说,如果我们传入了 -DWITH_NVCUVID 参数之后,它就会通过这些脚本来搜索 nvcuvid.hdynlink_nvcuvid.h 这两个头文件是否存在,并通过 find_cuda_helper_libs(nvcuvid) 来搜索库 libnvcuvid.so 是否存在。我在搜索库目录这句之后打印了一下 log 发现,它并没有找到 nvcuvid.h,于是通过打印 ${CUDA_TOOLKIT_TARGET_DIR} 变量的值和 ${CUDA_TOOLKIT_ROOT_DIR} 变量的值,找到了它认为的 CUDA toolkit 的目录,然后把位于 Video_Codec_SDK_11.1.5/interface 目录下的 nvcuvid.h 文件拷贝到 CUDA Toolkit 目录下,并在 opencv/CMakeLists.txt 第 1628 行插入以下内容之后:

  if(HAVE_CUDA)
    status("    NVIDIA GPU arch:"      ${OPENCV_CUDA_ARCH_BIN})
    status("    NVIDIA PTX archs:"     ${OPENCV_CUDA_ARCH_PTX})
    if (HAVE_NVCUVID)  # 插入内容判断 HAVE_NVCUVID 是否被置为了 1
      status("    NVIDIA WITH NVCUVID")
    endif()
  endif()
 endif()

再次执行 OpenCV 的 CMake 命令,发现执行结果中出现了 NVIDIA WITH NVCUVID 字样,说明 HAVE_NVCUVID 被置为 1 了。
the called functionality is disabled for current build or platform in functi,AVD,opencv,linux,计算机视觉
然后,再去编译执行 Demo,就能正常运行了,问题解决!

此外,上述提到的 CUDA Toolkit 在 Nvidia 官网中有其具体的安装方法,大致如下:文章来源地址https://www.toymoban.com/news/detail-612821.html

sudo apt-get autoremove --purge nvidia-*
sudo apt-add-repository ppa:graphics-drivers/ppa
sudo apt-get update
sudo apt-get install nvidia-driver-515
sudo reboot
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.7.1/local_installers/cuda-repo-ubuntu1804-11-7-local_11.7.1-515.65.01-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1804-11-7-local_11.7.1-515.65.01-1_amd64.deb
sudo cp /var/cuda-repo-ubuntu1804-11-7-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda
以上命令执行完之后,执行命令
nvidia-smi
若命令能正常执行且不报错,正常显示 NVIDIA-SMI 版本号,则表示正常安装

到了这里,关于【AVD】Linux 编译支持 Cuda 的 OpenCV 4.6,解决报错 throw_no_cuda的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Jetson OpenCV 安装,支持cuda加速,已解决多个常见问题

    1 :本文主要介绍 Jetson Xavier NX (以下简称 NX ) 平台下 OpenCV 的卸载及编译安装带 CUDA 加速的OpenCV 2 :并提出解决依赖项无法安装的问题 为什么要卸载默认的 OpenCV ? 输入命令 按数字6查看INFO页面,可以看到 所以默认的 OpenCV 版本是不带 CUDA 加速的,无法充分利用 NX 的 GPU 性能

    2024年01月19日
    浏览(41)
  • Linux/Debian/Ubuntu-OpenCV(4.5.4/4.6.0)+CUDA(11.3)配置编译全流程

    本文用来记录在linux环境下docker中编译 OpenCV with cuda 的过程,同时编译了4.5.4和4.6.0两个版本均可编译通过。 本地是linux环境也可参考本文完成编译。 系统:debian 11 CPU:i7 内存:16G 显卡:Nvidia Quadro M2000 github直接下载连接: OpenCV 4.5.4 source code OpenCV 4.6.0 source code 如需下载其他

    2024年02月10日
    浏览(32)
  • VS CUDA OpenCV编程 遇到gpu端核函数 应输入表达式的报错解决办法

    最近在做开发时,用到了cuda和opencv结合的使用方法。其中,cuda能够提供的公式就那么多,所以打算自己写一个核函数来实现自己想要实现的算法。结果遇到了核函数调用的时候报错,提示应输入表达式。 经过在网上查找,大家的解决办法基本上都说在cu文件中出现没事,可

    2024年02月08日
    浏览(40)
  • Android Studio启动AVD报错:The emulator process for AVD Pixel_5_API_30 has terminated.解决方法

    Android Studio启动AVD报错:The emulator process for AVD Pixel_5_API_30 has terminated. 原因:安装时使用自定义安装后,修改了默认安装目录。 而avd文件默认在 C:Users用户名.android 目录下。所以导致打开AVD时报错。 解决方法: 第一步:找到avd所在 .android文件夹,将 .android文件夹复制到SDK目

    2024年02月15日
    浏览(39)
  • Android Studio启动AVD报错:The emulator process for AVD Pixel_5_API_30 has terminated.最有效的解决方法

    Android Studio启动AVD报错:The emulator process for AVD Pixel_5_API_30 has terminated. 原因:安装时使用自定义安装后,修改了默认安装目录。 而avd文件默认在 C:Users用户名.android 目录下。所以导致打开AVD时报错。 解决方法一: 第一步:找到avd所在 .android文件夹,将 .android文件夹复制到

    2024年02月08日
    浏览(42)
  • 解决 Android Studio 报错 The emulator process for AVD xxx has terminated

    本人参考了这两篇文章 https://www.jianshu.com/p/7213d2242c5d https://www.cnblogs.com/fly263/p/16181714.html 首先找到 emu-launch-params.txt 该文件,由于我修改了存放路径所以在该目录下 C:AndroidSdk.androidavdPixel_2_API_25.avd ,默认应该是在C盘 C:Users你的用户名.androidavdPixel_2_API_25.avd 目录下 将这

    2024年02月03日
    浏览(47)
  • 【OpenCV】 OpenCV 源码编译并实现 CUDA 加速 (Windows)

    目录 1. 环境准备 1.1 软件环境 1. 2 源码下载 2. CMake编译项目 2.1 创建cmake项目 2.2 设置编译配置 2.3 解决异常 2.3.1 文件下载异常 2.3.2 解决CUDA版本异常 2.4 编译项目 3. Visual Studio 编译项目 4. 项目测试 5. 总结   OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器

    2024年02月03日
    浏览(29)
  • Win10 OpenCV编译安装CUDA版本

    Win10 + Microsoft Visual Studio Community 2017 + CUDA11.3 + CUDNN8.2 + RTX GeForce 3090 + OpenCV4.5.3 前往官网下载Visual Studio Installer即可,做如下勾选,安装即可 完成后,查看环境变量,将MSVC编译器地址加入环境变量 前往官网下载CUDA和对应的CUDNN,切记一定要对应CUDNN和CUDA版本,根据提示一步一

    2024年02月06日
    浏览(39)
  • OpenCV_CUDA_VS编译安装

    我这里是下载的OpenCV4.5.4,但是不知道到在vs里面build时一直报错,后面换了4.7.0的版本测试,安装成功。 Release OpenCV 4.5.4 · opencv/opencv · GitHub 这个里面有官方预编译好的OpenCV库,可以直接食用。 扩展包: https://github.com/opencv/opencv_contrib/releases/tag/4.5.4 这里cmake版本要求应该不是

    2024年02月09日
    浏览(38)
  • CMake编译CUDA项目报错

    configure后显示如下错误 CMake Error at C:/Program Files/CMake/share/cmake-3.26/Modules/CMakeDetermineCompilerId.cmake:751 (message): Compiling the CUDA compiler identification source file “CMakeCUDACompilerId.cu” failed. 同时,注意到下面报错为 C:Program FilesMicrosoft Visual Studio2022CommunityMSBuildMicrosoftVCv170BuildCustomi

    2024年02月06日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包