1. 程式人生 > >Ubuntu16.04+CUDA9.0+Python2.7環境下安裝OpenCV3.4

Ubuntu16.04+CUDA9.0+Python2.7環境下安裝OpenCV3.4

花了兩天時間終於安裝好了opencv,遇到好幾個bug發現能找到的解決方案比較少,同時需要翻牆,所以寫下這個筆記記錄一下。我是根據這個教程來安裝OpenCV的,進行到第四步OpenCV的配置和編譯開始報錯:

報錯1.Cmake編譯opencv原始碼時出現以下報錯:

CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake
files: CUDA_nppi_LIBRARY (ADVANCED) linked by target "opencv_cudev" in directory D:/Cproject/opencv/opencv/sources/modules/cudev linked by target "opencv_cudev" in directory D:/Cproject/opencv/opencv/sources/modules/cudev linked by target "opencv_test_cudev" in directory D:/Cproject/opencv/opencv/sources/modules/cudev/test
linked by target "opencv_core" in directory D:/Cproject/opencv/opencv/sources/modules/core .......................................... linked by target "opencv_createsamples" in directory D:/Cproject/opencv/opencv/sources/apps/createsamples linked by target "opencv_annotation" in directory D:/Cproject/opencv/opencv/sources/apps/annotation
linked by target "opencv_visualisation" in directory D:/Cproject/opencv/opencv/sources/apps/visualisation linked by target "opencv_version" in directory D:/Cproject/opencv/opencv/sources/apps/version

報錯原因:cuda9不再支援2.0架構,比如nppi庫在9.0中被分成了很多小的庫,因此這裡需要將nppi庫改動一下。 解決方案:

1). 在Cmake資料夾下找到FindCUDA.cmake檔案並修改

  #找到如下這一行
  find_cuda_helper_libs(nppi)
  #將這一行更改為:
  find_cuda_helper_libs(nppial)
  find_cuda_helper_libs(nppicc)
  find_cuda_helper_libs(nppicom)
  find_cuda_helper_libs(nppidei)
  find_cuda_helper_libs(nppif)
  find_cuda_helper_libs(nppig)
  find_cuda_helper_libs(nppim)
  find_cuda_helper_libs(nppist)
  find_cuda_helper_libs(nppisu)
  find_cuda_helper_libs(nppitc)

#找到如下這一行
set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppi_LIBRARY};${CUDA_npps_LIBRARY}")
#將其更改為:
set(CUDA_npp_LIBRARY "${CUDA_nppc_LIBRARY};${CUDA_nppial_LIBRARY};${CUDA_nppicc_LIBRARY};${CUDA_nppicom_LIBRARY};${CUDA_nppidei_LIBRARY};${CUDA_nppif_LIBRARY};${CUDA_nppig_LIBRARY};${CUDA_nppim_LIBRARY};${CUDA_nppist_LIBRARY};${CUDA_nppisu_LIBRARY};${CUDA_nppitc_LIBRARY};${CUDA_npps_LIBRARY}")

#找到如下這一行
unset(CUDA_nppi_LIBRARY CACHE)
#將其更改為:
unset(CUDA_nppial_LIBRARY CACHE)
unset(CUDA_nppicc_LIBRARY CACHE)
unset(CUDA_nppicom_LIBRARY CACHE)
unset(CUDA_nppidei_LIBRARY CACHE)
unset(CUDA_nppif_LIBRARY CACHE)
unset(CUDA_nppig_LIBRARY CACHE)
unset(CUDA_nppim_LIBRARY CACHE)
unset(CUDA_nppist_LIBRARY CACHE)
unset(CUDA_nppisu_LIBRARY CACHE)
unset(CUDA_nppitc_LIBRARY CACHE)

2).同一個資料夾中找到OpenCVDetectCUDA.cmake檔案並修改,這裡做修改是因為cuda9.0架構已經不支援“Fermi”2.0版本

#將如下幾行
 ...
  set(__cuda_arch_ptx "")
  if(CUDA_GENERATION STREQUAL "Fermi")
    set(__cuda_arch_bin "2.0")
  elseif(CUDA_GENERATION STREQUAL "Kepler")
    set(__cuda_arch_bin "3.0 3.5 3.7")
  ...
  #修改為:
    ...
  set(__cuda_arch_ptx "")
  if(CUDA_GENERATION STREQUAL "Kepler")
    set(__cuda_arch_bin "3.0 3.5 3.7")
  elseif(CUDA_GENERATION STREQUAL "Maxwell")
    set(__cuda_arch_bin "5.0 5.2")
  ...

  #將如下一行
  set(__cuda_arch_bin "2.0 3.0 3.5 3.7 5.0 5.2 6.0 6.1") 
  修改為:
  set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1") 

3).cuda9中有一個單獨的halffloat(cuda_fp16.h)標頭檔案,也應該被包括在opencv的目錄裡,即將標頭檔案cuda_fp16.h新增至opencv\modules\cudev\include\opencv2\cudev\common.hpp,即在common.hpp中新增:

  #include <cuda_fp16.h>

然後重新生成即可。

報錯2.Cmake編譯opencv原始碼依然報錯:

See also "/root/opencv/build/CMakeFiles/CMakeOutput.log".
See also "/root/opencv/build/CMakeFiles/CMakeError.log".
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
CUDA_CUDA_LIBRARY (ADVANCED)
    linked by target "example_gpu_alpha_comp" in directory /root/opencv/samples/gpu
    linked by target "example_gpu_bgfg_segm" in directory /root/opencv/samples/gpu
    linked by target "example_gpu_cascadeclassifier" in directory /root/opencv/samples/gpu
    linked by target "example_gpu_cascadeclassifier_nvidia_api" in directory /root/opencv/samples/gpu
    linked by target "example_gpu_driver_api_multi" in directory /root/opencv/samples/gpu
    ........................ 
    linked by target "example_gpu_surf_keypoint_matcher" in directory /root/opencv/samples/gpu
    linked by target "example_gpu_video_reader" in directory /root/opencv/samples/gpu
    linked by target "example_gpu_video_writer" in directory /root/opencv/samples/gpu

報錯原因:CUDA_CUDA_LIBRARY沒找到,因此需要在cmake的時候加入路徑,參考

#即在原始指令中加入最後一行的引數
cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D INSTALL_C_EXAMPLES=OFF \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.1.0/modules \
    -D PYTHON_EXECUTABLE=~/.virtualenvs/cv/bin/python \
    -D BUILD_EXAMPLES=ON
    -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs .. #新增項

以上完成之後make時繼續報錯:

報錯1.

Building NVCC (Device) object src/gromacs/CMakeFiles/libgromacs.dir/gmxlib/cuda_tools/./libgromacs_generated_copyrite_gpu.cu.o    
nvcc fatal   : Unsupported gpu architecture 'compute_20'    
CMake Error at libgromacs_generated_copyrite_gpu.cu.o.cmake:208 (message):
Error generating      
/opt/gromacs/build-gromacs/src/gromacs/CMakeFiles/libgromacs.dir/gmxlib/cuda_tools/./libgromacs_generated_copyrite_gpu.cu.o

src/gromacs/CMakeFiles/libgromacs.dir/build.make:55: recipe for target 'src/gromacs/CMakeFiles/libgromacs.dir/gmxlib/cuda_tools/./libgromacs_generated_copyrite_gpu.cu.o' failed    
make[2]: *** [src/gromacs/CMakeFiles/libgromacs.dir/gmxlib/cuda_tools/./libgromacs_generated_copyrite_gpu.cu.o] Error 1
CMakeFiles/Makefile2:1938: recipe for target 'src/gromacs/CMakeFiles/libgromacs.dir/all' failed    
make[1]: *** [src/gromacs/CMakeFiles/libgromacs.dir/all] Error 2    
Makefile:143: recipe for target 'all' failed
make: *** [all] Error 2

這裡是make到百分之33左右的時候報錯,這個錯誤解決了好久才大概明白原因,同時也對之前的報錯的原因有了更深的瞭解,報錯的原因是compute_20已經不被CUDA9.0支援了,因此其實是第一步教程中CMAKE的時候一個引數沒有被指定導致的。

#因此在最後一行加入
cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D INSTALL_C_EXAMPLES=OFF \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.1.0/modules \
    -D PYTHON_EXECUTABLE=~/.virtualenvs/cv/bin/python \
    -D BUILD_EXAMPLES=ON
    -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs
    -D CUDA_ARCH_BIN="6.1".. #新增項,此處具體的數字需在官網檢視對應GPU所支援的數字

附檢視網址

報錯2.

modules/cudalegacy/CMakeFiles/opencv_cudalegacy.dir/build.make:290: recipe for target ‘modules/cudalegacy/CMakeFiles/opencv_cudalegacy.dir/src/graphcuts.cpp.o’ failed 
make[2]: *** [modules/cudalegacy/CMakeFiles/opencv_cudalegacy.dir/src/graphcuts.cpp.o] Error

報錯原因:CUDA配置出錯,GraphCut在cuda7.5中棄用,在cuda8.0以上的版本中中被移除, 修改~/opencv-3.1.0/modules/cudalegacy/src/graphcuts.cpp檔案。 把第45行修改成:

#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) || (CUDART_VERSION >= 8000)

即在 #if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) 加上 || (CUDART_VERSION >= 8000),然後重新執行 make -j8 即可。

總結:以上報錯的主要原因是CUDA升級導致庫發生變化無法找到,以及版本升級後一部分配置不再支援導致報錯,CMAKE時需要指定特定配置防止出錯,同時修改庫檔案並注意標頭檔案的新增。