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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章