目录
背景
记录一下我前一阵子在Ubuntu18.04 64位上安装OpenCV3的过程,运气背的话挺繁琐的,仅供参考
安装依赖包
root@sundata:/etc/apt/sources.list.d# apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev libx264-dev libx265-dev
root@sundata:/etc/apt/sources.list.d# apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev ffmpeg libavformat-dev libavcodec-dev libswresample-dev libswscale-dev libavutil-dev libsdl1.2-dev yasm
安装ffmpeg
root@sundata:/data/szc# git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
root@sundata:/data/szc# cd ffmpeg/
root@sundata:/data/szc/ffmpeg# ./configure --enable-shared --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-libx265
root@sundata:/data/szc/ffmpeg# make && make install
如果编译时报错:V4L2_PIX_FMT_JPEG undeclared here,那么就修改libavdevice/v4l2-common.h文件,注释掉#include <linux/videodev2.h>周围的宏判断
// #if HAVE_SYS_VIDEOIO_H
// #include <sys/videoio.h>
// #else
// #if HAVE_ASM_TYPES_H
// #include <asm/types.h>
// #endif
#include <linux/videodev2.h>
// #endif
测试一下
root@sundata:/data/szc/ffmpeg# ldd ffmpeg
linux-vdso.so.1 (0x00007ffd3fbb1000)
libavdevice.so.58 => not found
libavfilter.so.7 => not found
libavformat.so.58 => not found
libavcodec.so.58 => not found
libpostproc.so.55 => not found
libswresample.so.3 => not found
libswscale.so.5 => not found
libavutil.so.56 => not found
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7bf1a84000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7bf1865000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7bf1474000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7bf2068000)
root@sundata:/data/szc/ffmpeg# ffmpeg -version
ffmpeg version 3.4.8-0ubuntu0.2 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
configuration: --prefix=/usr --extra-version=0ubuntu0.2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
编译安装opencv3
理想情况
(base) root@ubuntu:/home/szc/opencv/opencv-3.0.0/build# cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
如果一切正常,会成功并且当前目录下会有Makefile文件
(base) root@ubuntu:/home/szc/opencv/opencv-3.0.0/build# make -j6 && make install
以上过程在我的虚拟机上一切正常,完成后的截图如下所示
错误处理
复制头文件
root@sundata:/data/szc/opencv/opencv-3.0.0/build# apt-get install libpt-dev apcalc-dev linux-oracle-headers-4.15.0-1054
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp -r /usr/include/x86_64-linux-gnu/libavformat /usr/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/calc/cmath.h /usr/local/include/
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/c++/v1/* /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /snap/gnome-3-34-1804/36/usr/include/c++/6/cmath /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/src/linux-oracle-headers-4.15.0-1054/include/uapi/linux/videodev2.h /usr/local/include/linux/
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/ptlib/videoio.h /usr/local/include/sys/
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/ptbuildopts.h /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp -r /usr/include/ptlib /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/ptlib.h /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /snap/gnome-3-34-1804/36/usr/include/c++/6/bits/cpp_type_traits.h /usr/local/include/bits
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp -r /usr/src/linux-hwe-5.4-headers-5.4.0-48/include/linux/* /usr/local/include/linux/
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp -r /usr/src/linux-hwe-5.4-headers-5.4.0-48/include/uapi /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /snap/gnome-3-34-1804/36/usr/lib/gcc/x86_64-linux-gnu/6/include/stdbool.h /usr/local/include
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/local/include/c++/6/ext/atomicity.h /usr/local/include/ext/
注意libpjproject-dev似乎和libpt-dev是互斥的,因此要把后者的相关文件复制到/usr/local/include目录后,再安装后者
root@sundata:/data/szc/opencv/opencv-3.0.0/build# apt-get install libpjproject-dev
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/pjmedia/videodev.h /usr/local/include/linux/
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp -r /usr/include/pj* /usr/local/include
修改头文件
还得修改一些文件:
#pragma once
#ifdef __cplusplus
extern "C++" {
.....
} // extern "C++"
#endif
....
2)、/usr/local/include/wchar.h,开头某行加上wchar_t的宏定义
....
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#define int32 wchar_t
#include_next <wchar.h>
....
3)、/usr/local/include/ptlib/unix/ptlib/contain.h,加上头文件
#include <wchar.h>
- 未知类型extern "C++":修改type_traits、cmath,用#ifdef __cplusplus .... #endif包裹住extern "C++" {}
- 未知类型using namespace std:修改ptlib/unix/ptlib/contain.h,用#ifdef __cplusplus .... #endif包裹住using namespace std;
- 未知类型_LIBCPP_BEGIN_NAMESPACE_STD:修改atomic、cctype、cstring、cstddef、cstdio、cstdint、iosfwd、ios、iterator、cstdlib、cwctype、cwchar、memory、stdexcept、tuple、typeinfo、type_traits、utility、__tuple、__debug、__bsd_locale_fallbacks.h、cstdarg、__locale、ostream、iostream、iomanip、map文件,用#ifdef __cplusplus.... #endif包裹住_LIBCPP_BEGIN_NAMESPACE_STD ..... _LIBCPP_END_NAMESPACE_STD,其中atomic还要引入头文件#include <stdbool.h>,以及注释掉#error <atomic> is not implemented;stdexcept文件是从第一个_LIBCPP_BEGIN_NAMESPACE_STD,一直包裹到最后一个_LIBCPP_END_NAMESPACE_STD,基本就到了文件末尾了
- 未知类型 namespace std:修改__nullptr、exception、initializer_list、typeinfo文件,用#ifdef __cplusplus .... #endif包裹住所有的namespace std {}
- #include_next <stddef.h>找不到stddef.h文件,修改cstddef文件,把#include_next <stddef.h>改成#include <stddef.h>
- 未知类型_LIBCPP_PUSH_MACROS:修改__string、__bit_reference、__mutex_base、__threading_support、__split_buffer、__tree、string_view、string、streambuf、algorithm、memory、limits、locale、bitset、mutex、chrono、ratio、istream、sstream、vector、list文件:用#ifdef __cplusplus .... #endif包裹住_LIBCPP_PUSH_MACROS和_LIBCPP_BEGIN_NAMESPACE_STD ..... _LIBCPP_POP_MACROS
- new文件:
- 用#ifdef __cplusplus .... #endif包裹住#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME) ....#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME之间的内容
- 用#ifdef __cplusplus .... #endif包裹住_LIBCPP_BEGIN_NAMESPACE_STD ..... _LIBCPP_END_NAMESPACE_STD
- __functional_base文件:用#ifdef __cplusplus .... #endif包裹住_LIBCPP_BEGIN_NAMESPACE_STD ..... _LIBCPP_END_NAMESPACE_STD和constexpr
- ext/atomicity.h文件: 用#ifdef __cplusplus .... #endif包裹住namespace
- ptlib/目录:要改的文件很多,可以直接从我的网盘下载改好的:链接:https://pan.baidu.com/s/1guHSn6iVRGyrw8enXead5Q,提取码:hsw3
- sys/videoio.h文件: 用#ifdef __cplusplus .... #endif包裹住class PColourConverter; ...... class PVideoFont : public PObject两个类之间的内容
- class:修改__debug文件,用#ifdef __cplusplus .... #endif包裹住class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception;
修改OpenCV文件
下面这些文件都是在opencv3.0.0的目录下
#include <cuda_fp16.h>
2)、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)
3)、cmake/OpenCVDetectCUDA.cmake
if(CUDA_GENERATION STREQUAL "Fermi")
set(__cuda_arch_bin "2.0 2.1(2.0)")
elseif(CUDA_GENERATION STREQUAL "Kepler")
if(${CUDA_VERSION} VERSION_LESS "5.0")
set(__cuda_arch_bin "3.0")
else()
set(__cuda_arch_bin "3.0 3.5")
endif()
改为
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")
4)、cmake/OpenCVFindLibsVideo.cmake
CHECK_INCLUDE_FILE(ffmpeg/avformat.h HAVE_FFMPEG_FFMPEG)
CHECK_INCLUDE_FILE(libavformat/avformat.h HAVE_FFMPEG_FFMPEG)
if(EXISTS /usr/include/ffmpeg/libavformat/avformat.h OR HAVE_FFMPEG_SWSCALE)
if(EXISTS /usr/local/include/libavformat/avformat.h OR HAVE_FFMPEG_SWSCALE)
# ----------------------------------------------------------------------------
# Detect Microsoft compiler:
# ----------------------------------------------------------------------------
if(CMAKE_CL_64)
set(MSVC64 1)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_GNUCXX 1)
set(CMAKE_COMPILER_IS_CLANGCXX 1)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(CMAKE_COMPILER_IS_GNUCC 1)
set(CMAKE_COMPILER_IS_CLANGCC 1)
endif()
if("${CMAKE_CXX_COMPILER};${CMAKE_C_COMPILER}" MATCHES "ccache")
set(CMAKE_COMPILER_IS_CCACHE 1)
endif()
# ----------------------------------------------------------------------------
# Detect Intel ICC compiler -- for -fPIC in 3rdparty ( UNIX ONLY ):
# see include/opencv/cxtypes.h file for related ICC & CV_ICC defines.
# NOTE: The system needs to determine if the '-fPIC' option needs to be added
# for the 3rdparty static libs being compiled. The CMakeLists.txt files
# in 3rdparty use the CV_ICC definition being set here to determine if
# the -fPIC flag should be used.
# ----------------------------------------------------------------------------
if(UNIX)
if (__ICL)
set(CV_ICC __ICL)
elseif(__ICC)
set(CV_ICC __ICC)
elseif(__ECL)
set(CV_ICC __ECL)
elseif(__ECC)
set(CV_ICC __ECC)
elseif(__INTEL_COMPILER)
set(CV_ICC __INTEL_COMPILER)
elseif(CMAKE_C_COMPILER MATCHES "icc")
set(CV_ICC icc_matches_c_compiler)
endif()
endif()
if(MSVC AND CMAKE_C_COMPILER MATCHES "icc|icl")
set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS)
endif()
# ----------------------------------------------------------------------------
# Detect GNU version:
# ----------------------------------------------------------------------------
if(CMAKE_COMPILER_IS_CLANGCXX)
set(CMAKE_GCC_REGEX_VERSION "4.2.1")
set(CMAKE_OPENCV_GCC_VERSION_MAJOR 4)
set(CMAKE_OPENCV_GCC_VERSION_MINOR 2)
set(CMAKE_OPENCV_GCC_VERSION 42)
set(CMAKE_OPENCV_GCC_VERSION_NUM 402)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -v
ERROR_VARIABLE CMAKE_OPENCV_CLANG_VERSION_FULL
ERROR_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "version.*$" CMAKE_OPENCV_CLANG_VERSION_FULL "${CMAKE_OPENCV_CLANG_VERSION_FULL}")
string(REGEX MATCH "[0-9]+\\.[0-9]+" CMAKE_CLANG_REGEX_VERSION "${CMAKE_OPENCV_CLANG_VERSION_FULL}")
elseif(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
OUTPUT_VARIABLE CMAKE_OPENCV_GCC_VERSION_FULL
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -v
ERROR_VARIABLE CMAKE_OPENCV_GCC_INFO_FULL
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Typical output in CMAKE_OPENCV_GCC_VERSION_FULL: "c+//0 (whatever) 4.2.3 (...)"
# Look for the version number, major.minor.build
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CMAKE_GCC_REGEX_VERSION "${CMAKE_OPENCV_GCC_VERSION_FULL}")
if(NOT CMAKE_GCC_REGEX_VERSION)#major.minor
string(REGEX MATCH "[0-9]+\\.[0-9]+" CMAKE_GCC_REGEX_VERSION "${CMAKE_OPENCV_GCC_VERSION_FULL}")
endif()
if(CMAKE_GCC_REGEX_VERSION)
# Split the parts:
string(REGEX MATCHALL "[0-9]+" CMAKE_OPENCV_GCC_VERSIONS "${CMAKE_GCC_REGEX_VERSION}")
list(GET CMAKE_OPENCV_GCC_VERSIONS 0 CMAKE_OPENCV_GCC_VERSION_MAJOR)
list(GET CMAKE_OPENCV_GCC_VERSIONS 1 CMAKE_OPENCV_GCC_VERSION_MINOR)
else()#compiler returned just the major version number
string(REGEX MATCH "[0-9]+" CMAKE_GCC_REGEX_VERSION "${CMAKE_OPENCV_GCC_VERSION_FULL}")
if(NOT CMAKE_GCC_REGEX_VERSION)#compiler did not return anything reasonable
set(CMAKE_GCC_REGEX_VERSION "0")
message(WARNING "GCC version not detected!")
endif()
set(CMAKE_OPENCV_GCC_VERSION_MAJOR ${CMAKE_GCC_REGEX_VERSION})
set(CMAKE_OPENCV_GCC_VERSION_MINOR 0)
endif()
set(CMAKE_OPENCV_GCC_VERSION ${CMAKE_OPENCV_GCC_VERSION_MAJOR}${CMAKE_OPENCV_GCC_VERSION_MINOR})
math(EXPR CMAKE_OPENCV_GCC_VERSION_NUM "${CMAKE_OPENCV_GCC_VERSION_MAJOR}*100 + ${CMAKE_OPENCV_GCC_VERSION_MINOR}")
message(STATUS "Detected version of GNU GCC: ${CMAKE_OPENCV_GCC_VERSION} (${CMAKE_OPENCV_GCC_VERSION_NUM})")
if(WIN32)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine
OUTPUT_VARIABLE OPENCV_GCC_TARGET_MACHINE
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(OPENCV_GCC_TARGET_MACHINE MATCHES "amd64|x86_64|AMD64")
set(MINGW64 1)
endif()
endif()
endif()
if(MSVC64 OR MINGW64)
set(X86_64 1)
elseif(MINGW OR (MSVC AND NOT CMAKE_CROSSCOMPILING))
set(X86 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
set(X86_64 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|AMD64.*")
set(X86 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
set(ARM 1)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
set(AARCH64 1)
endif()
# Workaround for 32-bit operating systems on 64-bit x86_64 processor
if(X86_64 AND CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT FORCE_X86_64)
message(STATUS "sizeof(void) = 4 on x86 / x86_64 processor. Assume 32-bit compilation mode (X86=1)")
unset(X86_64)
set(X86 1)
endif()
# Similar code exists in OpenCVConfig.cmake
if(NOT DEFINED OpenCV_STATIC)
# look for global setting
if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)
set(OpenCV_STATIC OFF)
else()
set(OpenCV_STATIC ON)
endif()
endif()
if(MSVC)
if(CMAKE_CL_64)
set(OpenCV_ARCH x64)
elseif((CMAKE_GENERATOR MATCHES "ARM") OR ("${arch_hint}" STREQUAL "ARM") OR (CMAKE_VS_EFFECTIVE_PLATFORMS MATCHES "ARM|arm"))
# see Modules/CmakeGenericSystem.cmake
set(OpenCV_ARCH ARM)
else()
set(OpenCV_ARCH x86)
endif()
if(MSVC_VERSION EQUAL 1400)
set(OpenCV_RUNTIME vc8)
elseif(MSVC_VERSION EQUAL 1500)
set(OpenCV_RUNTIME vc9)
elseif(MSVC_VERSION EQUAL 1600)
set(OpenCV_RUNTIME vc10)
elseif(MSVC_VERSION EQUAL 1700)
set(OpenCV_RUNTIME vc11)
elseif(MSVC_VERSION EQUAL 1800)
set(OpenCV_RUNTIME vc12)
elseif(MSVC_VERSION EQUAL 1900)
set(OpenCV_RUNTIME vc14)
elseif(MSVC_VERSION EQUAL 1910)
set(OpenCV_RUNTIME vc15)
endif()
elseif(MINGW)
set(OpenCV_RUNTIME mingw)
if(MINGW64)
set(OpenCV_ARCH x64)
else()
set(OpenCV_ARCH x86)
endif()
endif()
6)、如果报错Requested modules not available: vtkRenderingOpenGL,就修改/cmake/OpenCVDetectVTK.cmake文件,把
find_package(VTK QUIET COMPONENTS vtkRenderingOpenGL vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
改成
find_package(VTK QUIET COMPONENTS vtkRenderingOpenGL2 vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
7)、如果报错unsupported gpu architecture compute_20,由于我的cuda为10.0,就要先修改cmake/OpenCVDetectCUDA.cmake文件,在设置_generations后面加上Pascal
set(_generations "Fermi" "Kepler" "Pascal")
然后在对CUDA_GENERATION的判断分支里假设Pascal对应的计算能力(6.0和6.1)
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")
elseif(CUDA_GENERATION STREQUAL "Pascal")
set(__cuda_arch_bin "6.0 6.1")
最后cmake编译时指定CUDA架构
-D CUDA_GENERATION=Pascal
修改文件方法
最后说一下这些问题的解决思路:
root@sundata:/home/sundata# locate bits/cpp_type_traits.h
/snap/gnome-3-34-1804/36/usr/include/c++/6/bits/cpp_type_traits.h
/usr/include/c++/3.4/bits/cpp_type_traits.h
/usr/include/c++/5/bits/cpp_type_traits.h
/usr/include/c++/7/bits/cpp_type_traits.h
/usr/local/include/c++/6/bits/cpp_type_traits.h
然后找一个复制到/usr/local/include目录下(这里找不到的是bits/cpp_type_traits.h,因此要复制到/usr/local/include/bits目录下)
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /snap/gnome-3-34-1804/36/usr/include/c++/6/bits/cpp_type_traits.h /usr/local/include/bits
如果在本地找不到,就说明我们得通过安装第三方库的方式添加此文件了(比如sys/videoio.h)。首先用apt-file(没有就用apt-get安装)查一下此头文件包含在哪个第三方库和安装后所在的路径
root@sundata:/home/sundata# apt-file search videoio.h
libopencv-videoio-dev: /usr/include/opencv2/videoio.hpp
libopencv-videoio-dev: /usr/include/opencv2/videoio/videoio.hpp
libpt-dev: /usr/include/ptlib/videoio.h
opencv-doc: /usr/share/doc/opencv-doc/html/dd/de7/group__videoio.html
opencv-doc: /usr/share/doc/opencv-doc/html/df/d2c/tutorial_table_of_content_videoio.html
我们选的肯定是头文件,那么只有libpt-dev能选。我们用apt-get安装后,把此文件从安装后所在的路径复制到/usr/local/include下即可(因为是找不到sys/videoio.h,所以得复制到usr/local/include/sys/目录下)
root@sundata:/data/szc/opencv/opencv-3.0.0/build# cp /usr/include/ptlib/videoio.h /usr/local/include/sys/
2)、某字段找不到、定义前已经使用
/* The fallback definitions, for when __WCHAR_MAX__ or __WCHAR_MIN__
are not defined, give the right value and type as long as both int
and wchar_t are 32-bit types. Adding L'\0' to a constant value
ensures that the type is correct; it is necessary to use (L'\0' +
0) rather than just L'\0' so that the type in C++ is the promoted
version of wchar_t rather than the distinct wchar_t type itself.
Because wchar_t in preprocessor #if expressions is treated as
intmax_t or uintmax_t, the expression (L'\0' - 1) would have the
wrong value for WCHAR_MAX in such expressions and so cannot be used
to define __WCHAR_MAX in the unsigned case. */
里面说,如果__WCHAR_MAX__或__WCHAR_MIN__没定义,只要wchar_t和int都是32位的类型,就会对__WCHAR_MAX__或__WCHAR_MIN__进行正确赋值,而且在升级后的C++版本中wchar_t没有被明确定义。那么我只好帮它定义wchar_t了,32位嘛,于是就有了修改头文件中的第二部分的修改
更好的解决方法——换OpenCV版本
3.4.1版本的OpenCV及OpenCV_contrib
下载xfeatures2d源文件
修改OpenCV文件
...
include_directories("modules")
# ----------------------------------------------------------------------------
# Path for build/platform -specific headers
# ----------------------------------------------------------------------------
....
2)、修改文件opencv-3.4.1/modules/stitching目录下的CMakeLists.txt,加上一句话:
include_directories("/home/rtlab/szc/opencv-3.4.1/modules/features2d/include/")
编译与安装
再使用命令行编译安装
root@rtlab-computer:/home/rtlab/szc/opencv-3.4.1/build# make -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D ENABLE_PRECOMPILED_HEADERS=OFF -D CUDA_GENERATION=Pascal -D OPENCV_EXTRA_MODULES_PATH=/home/rtlab/szc/opencv_contrib-3.4.1/modules -D WITH_CUDA=ON -D WITH_OPENCL=ON ..
root@rtlab-computer:/home/rtlab/szc/opencv-3.4.1/build# make -j10 && make install
此时编译就很顺利
配置
include /usr/local/lib
2)、修改/etc/profile
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
3)、使能
(base) root@ubuntu:/home/szc/opencv/opencv-3.0.0/build# ldconfig
(base) root@ubuntu:/home/szc/opencv/opencv-3.0.0/build# source /etc/profile
检验
root@ubuntu:/home/szc/opencv/opencv-3.0.0/build# pkg-config opencv --modversion
如果能正确输出版本号,就成功了
结语
在选择要编译安装的OpenCV版本时,最好查看github中cmake/OpenCVDetectCUDA.cmake文件里有没有包含自己的CUDA版本(比如计算能力为6.X的就是Pascal),这样可以少走很多弯路。另外OpenCV里面的一些测试用例由于没有数据,无法运行;另有一些因为种种原因也不能运行通过,但只要能正确输出版本号,应该就说明我们安装成功了。