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時需要指定特定配置防止出錯,同時修改庫檔案並注意標頭檔案的新增。