Nvidia jetson nano opencv 3.4.3 GPU版 编译 配置

步骤

  1.刷完系统后,卸载Jetpack L4T 32中自带的opencv

  2.下载opencv源码

  3.cmake下载编译

  4.编译安装opencv

  5.测试

 

一、卸载自带opencv

关于jetson平台可以通过apt-get命令来卸载opencv

#通过dpkg -l查看所安装的opencv库

dpkg -l | grep -i opencv

#看到相关的opencv就可以用apt-get来卸载了
#移除相关libopencv库

sudo apt-get remove libopencv*

 

如果是其他平台,由于没有构建目录,自然无法使用make uninstall命令来卸载。那我们就删除文件。

执行命令

sudo rm -rf /usr/local/include/opencv2 /usr/local/include/opencv /usr/include/opencv /usr/include/opencv2 /usr/local/share/opencv /usr/local/share/OpenCV /usr/share/opencv /usr/share/OpenCV /usr/local/bin/opencv* /usr/local/lib/libopencv*

    找到所有带opencv字符的文件 删除

cd /usr
find . -name "*opencv*" | xargs sudo rm -rf

二、下载opencv源码

    到github下载opencv3.4.3版本和下载contrib 3.4.3版本。

    opencv下载地址

    https://github.com/opencv/opencv/tree/3.4.3

    opencv contrib下载地址

    https://github.com/opencv/opencv_contrib/tree/3.4.3

 

    如果用我的命令来编译也可以下载我这边上传的文件,cmake时有些文件下载不下来,我这里面已经下载好了。

    已整合opencv+opencv_contrib

    https://download.csdn.net/download/ourkix/12023350

三、下载cmake源码,编译

    cmake下载地址

    官方地址:https://cmake.org/download/

    或者下载我上传的

    https://download.csdn.net/download/ourkix/12023373

编译安装

tar -xzvf cmake-3.15.4
cd cmake-3.15.4
sudo ./bootstrap
sudo make -j4
sudo make install

查看cmake安装成功与否

cmake --version 

就会出来版本号,若提示找不到cmake则做如下处理:

whereis cmake
result :
cmake: /usr/lib/aarch64-linux-gnu/cmake /usr/lib/cmake /usr/local/bin/cmake /usr/share/cmake
 
vim ~/.bashrc
添加:
export PATH=:/usr/local/bin/cmake:$PATH
source  ~/.bashrc

四、opencv编译安装

    我opencv解压后是放在home里面的,也就是当前用户的home ,路径 ~

    如果在github下载的话,opencv解压到home后,把opencv-contrib解压到opencv目录里面。如果用的是我上传的文件则直接解压到home目录即可。

    切换到home目录  切换到opecv目录

cd ~
cd opencv***

    切换到release目录

    如果github下载的没有此目录自己创建即可,有就直接切换

//创建目录release
mkdir release
cd release

//直接切换
cd release

   依赖安装

这里面有些包可能会找不到,换到ubuntu 16.04的apt源下载即可。

#this is x86/x64
#sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"

#this is arm64
sudo add-apt-repository "deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted"
sudo apt-get update
sudo apt-get install -y libjasper1 libjasper-dev
sudo apt-get update
sudo apt-get install -y build-essential git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y python2.7-dev python3.6-dev python-dev python-numpy python3-numpy
sudo apt-get install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2 v4l2ucp
sudo apt-get install -y curl
sudo apt-get install -y gnome gnome-devel
sudo apt-get install -y glade libglade2-dev
sudo apt-get update

   

 

    cmake

    解释:由于jetson nano的gpu的算力是5.3的所以填上,gpu编译 WITH_CUDA=ON 要用上surf sitf 等非免费算子 加上 OPENCV_ENABLE_NONFREE=ON 其他的自己理解。

cmake -D WITH_CUDA=ON -D CUDA_ARCH_BIN="5.3" -D CUDA_ARCH_PTX="5.3" -D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib-3.4.3/modules -D WITH_GSTREAMER=ON -D WITH_LIBV4L=ON -D BUILD_opencv_python2=ON -D BUILD_opencv_python3=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_OPENEXR=ON -D WITH_OPENEXR=ON -D OPENCV_ENABLE_NONFREE=ON ..

   修改文件 编译报错

In file included from /home/nvidia/opencv-3.4.3/modules/stitching/include/opencv2/stitching.hpp:49:0,
                 from /home/nvidia/opencv-3.4.3/modules/stitching/src/precomp.hpp:59,
                 from /home/nvidia/opencv-3.4.3/release/modules/stitching/opencv_stitching_pch_dephelp.cxx:1:
/home/nvidia/opencv-3.4.3/modules/stitching/include/opencv2/stitching/detail/matchers.hpp:53:123: fatal error: /home/nvidia/opencv3/opencv-3.4.3/opencv_contrib-3.4.3/modules/xfeatures2d/include/opencv2/xfeatures2d/cuda.hpp: No such file or directory

这里如果用我上传的文件编译的话,会有这个错误,原因是在我的板子上找不到cuda.hpp的路径,所以就把头文件的位置改成了绝对路径了,你们的安装目录不同的话会导致找不到这个头文件,所以在相对应的文件改成你的路径 或者 把我的删掉,用原来的。

打开 opencv-3.4.3/modules/stitching/include/opencv2/stitching/detail/matchers.hpp 文件,修改头文件

//#include "opencv2/xfeatures2d/cuda.hpp"
#include "/home/nvidia/opencv3/opencv-3.4.3/opencv_contrib-3.4.3/modules/xfeatures2d/include/opencv2/xfeatures2d/cuda.hpp"

改成

#include "opencv2/xfeatures2d/cuda.hpp"
//#include "/home/nvidia/opencv3/opencv-3.4.3/opencv_contrib-3.4.3/modules/xfeatures2d/include/opencv2/xfeatures2d/cuda.hpp"

如果改了还是找不到,那就把下面的路径改成自己的路径试试。

 

    编译安装

    nano是4核所以-j4

make -j4
sudo make install

  如make出错 查看相应解决方法即可。

更新2020.1.10-----------------------------------------------------------------------------------------------------------------------------------------------

CUDA10编译不会出现一下相关错误,可略过。

如果根据我的另一篇博客,在nano上配置了CUDA9,编译opencv时可能会遇到这些错误。

错误一:

#error

In file included from /usr/local/cuda-9.0/include/host_config.h:50:0,
                 from /usr/local/cuda-9.0/include/cuda_runtime.h:78,
                 from <command-line>:0:
/usr/local/cuda-9.0/include/crt/host_config.h:119:2: error: #error -- unsupported GNU version! gcc versions later than 6 are not supported!
 #error -- unsupported GNU version! gcc versions later than 6 are not supported!
  ^~~~~
CMake Error at cuda_compile_1_generated_gpu_mat.cu.o.RELEASE.cmake:221 (message):
  Error generating
  /home/nivida/opencv3/opencv-3.4.3/build/modules/core/CMakeFiles/cuda_compile_1.dir/src/cuda/./cuda_compile_1_generated_gpu_mat.cu.o

这是编译器版本问题,解决方法

#安装gcc g++ 6的版本,备份系统原版gcc 和 g++7版本,建立新的链接

sudo apt-get install gcc-6
sudo apt-get install g++-6
sudo ln -s /usr/bin/gcc-6 /usr/local/cuda/bin/gcc
sudo ln -s /usr/bin/g++-6 /usr/local/cuda/bin/g++

cd /usr/bin
sudo mv gcc gccbackup
sudo ln -s gcc-6 gcc
sudo mv g++ g++backup
sudo ln -s g++-6 g++

错误二:

#error

modules/core/include/opencv2/core/cuda/vec_math.hpp(203): error: calling a constexpr __host__ function("abs") from a __device__ function("abs") is not allowed. The experimental flag '--expt-relaxed-constexpr' can be used to allow this.

解决方法:

opencv根目录的 modules/core/include/opencv2/core/cuda/vec_math.hpp,对vec_math.hpp做如下修改(把203行和205行的 ::abs 也注释掉)

//原本的
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, uchar, uchar)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, char, char)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, ushort, ushort)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, short, short)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, int, int)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, uint, uint)

//修改成
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, uchar, uchar)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, char, char)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, ushort, ushort)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, short, short)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, ::abs, int, int)
CV_CUDEV_IMPLEMENT_VEC_UNARY_FUNC(abs, /*::abs*/, uint, uint)

 

更新2020.1.10-----------------------------------------------------------------------------------------------------------------------------------------------

 

   检测安装情况

pkg-config --libs --cflags opencv
pkg-config --modversion opencv

五、opencv构建工程测试

    找个文件夹进入,新建文件 CMakeLists.txt

touch CMakeLists.txt

编辑CMakeLists.txt文件,写入

cmake_minimum_required(VERSION 3.0)
 
project(OCSample)
 
set(CUDA_USE_STATIC_CUDA_RUNTIME ON) #这一句解决 cannot find -lopencv_dep_cudart
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
 
 
set(OpenCV_DIR "/usr/local/share/OpenCV") # 指定OpenCV安装路径来区分不同的OpenCV版本
find_package(OpenCV REQUIRED)
set(OpenCV_LIB_DIR ${OpenCV_INSTALL_PATH}/lib)
message(STATUS "OpenCV版本: ${OpenCV_VERSION}")
message(STATUS "    头文件目录:${OpenCV_INCLUDE_DIRS}")
message(STATUS "    库文件目录:${OpenCV_LIB_DIR}")
message(STATUS "    库文件列表:${OpenCV_LIBS}")
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIB_DIR})
 
 
CUDA_ADD_EXECUTABLE(main main.cpp)
target_link_libraries(main ${OpenCV_LIBS})

新建文件main.cpp 

touch main.cpp

编辑文件,写入


#include "opencv2/core/cuda.hpp"
#include "opencv2/opencv.hpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/xfeatures2d/cuda.hpp>
#include <opencv2/cudafeatures2d.hpp>

#include <iostream>
#include <opencv2/xfeatures2d.hpp>
using namespace cv;  //包含cv命名空间
using namespace std;

int GetMatchPointCount(const char * pic_path_1,const char * pic_path_2) {
  /*指定使用的GPU序号,相关的还有下面几个函数可以使用
    cv::cuda::getCudaEnabledDeviceCount();
    cv::cuda::getDevice();
    cv::cuda::DeviceInfo*/
  cv::cuda::setDevice(0);

  /*向显存加载两张图片。这里需要注意两个问题:
    第一,我们不能像操作(主)内存一样直接一个字节一个字节的操作显存,也不能直接从外存把图片加载到显存,一般需要通过内存作为媒介
    第二,目前opencv的GPU SURF仅支持8位单通道图像,所以加上参数IMREAD_GRAYSCALE*/
  cv::cuda::GpuMat gmat1;
  cv::cuda::GpuMat gmat2;
  cv::Mat src_image1 = cv::imread(pic_path_1,cv::IMREAD_GRAYSCALE);
  cv::Mat src_image2 = cv::imread(pic_path_2,cv::IMREAD_GRAYSCALE);


  gmat1.upload(src_image1);
  gmat2.upload(src_image2);

  /*下面这个函数的原型是:
  explicit SURF_CUDA(double 
      _hessianThreshold, //SURF海森特征点阈值
      int _nOctaves=4, //尺度金字塔个数
      int _nOctaveLayers=2, //每一个尺度金字塔层数
      bool _extended=false, //如果true那么得到的描述子是128维,否则是64维
      float _keypointsRatio=0.01f, 
      bool _upright = false 
      );
  要理解这几个参数涉及SURF的原理*/
  cv::cuda::SURF_CUDA surf(
      100,4,3
      );  

  /*分配下面几个GpuMat存储keypoint和相应的descriptor*/
  cv::cuda::GpuMat keypt1,keypt2;
  cv::cuda::GpuMat desc1,desc2;

double start = static_cast<double>(cvGetTickCount());

  /*检测特征点*/
  surf(gmat1,cv::cuda::GpuMat(),keypt1,desc1);
  surf(gmat2,cv::cuda::GpuMat(),keypt2,desc2);





  /*匹配,下面的匹配部分和CPU的match没有太多区别,这里新建一个Brute-Force Matcher,一对descriptor的L2距离小于0.1则认为匹配*/
  auto matcher=cv::cuda::DescriptorMatcher::createBFMatcher(cv::NORM_L2);
  vector<cv::DMatch> match_vec;
  matcher->match(desc1,desc2,match_vec);

    double time  = ((double)cvGetTickCount() - start)/cvGetTickFrequency();
    cout<<"used time "<<time<<" us"<<endl;
    cout<<"used time "<<time/1000<<" ms"<<endl;

  int count=0;
  for(auto & d:match_vec){
    if(d.distance<0.1) count++;
  }

    //绘制匹配出的关键点
    //Detect the keypoints
    vector<KeyPoint> keypoints_1, keypoints_2;
    surf.downloadKeypoints(keypt1,keypoints_1);
    surf.downloadKeypoints(keypt2,keypoints_2);


    Mat img_matches;
     drawMatches(src_image1, keypoints_1, src_image2, keypoints_2, match_vec, img_matches);
    imshow("【match图】", img_matches);
    //等待任意按键按下
    waitKey(0);


  return count;
}

int main(int argc, const char* argv[])
{
  GetMatchPointCount("1.jpeg","1.jpeg");
  return 0;
}  

    找张图片 命名为1.jpeg 放在当前文件夹下

    编译,运行

cmake .
make
./main

 

发布了19 篇原创文章 · 获赞 7 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章