我与边缘计算 - [Jetson Xavier] - [浪潮边缘主机环境拓荒]

目录

 

目的

过程

1.opencv

2.darknet

3.TensorRT

 

 

附录1:blas、lapack、cblas在Ubuntu上的安装

1.确保机器上安装了gfortran编译器,如果没有安装的话,可以使用

2.下载blas, cblas, lapack 源代码

3.这里就是具体的编译步骤(一定要按照顺序)

附录2:在Ubuntu18.04 Arm64架构下编译和运行c#程序

1.安装SDK

2.安装Visual Studio Code

3.测试


目的

目的是使用边缘主机运行yolov4.

过程

因为边缘主机架构为aarch64的arm64架构,所以很多x86x64架构下的应用没办法使用。

我使用的这款机器说明书名称为NE1008N1边缘智算小站,我就叫他边缘主机了,因为搭载的是英伟达的JetsonNano后边简称jn,所以去网上查资料准备安装环境,网上说jn拿到的时候一般已经安装好cuda,opencv等深度学习环境,但是我找了一圈没找到,可能是浪潮那边弄掉了吧。所以这种情况下只能自己搭建环境,这里记录一下过程,以便自己后边迁移。

1.opencv

这里使用的是opencv3.3.1版本,github下载后使用mv 命令移动到 /usr/local/opencv中,使用unzip解压。

因为安装opencv要一些依赖的环境,这里直接贴上先:

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff5-dev libdc1394-22-dev         # 处理图像所需的包
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev liblapacke-dev
sudo apt-get install libxvidcore-dev libx264-dev         # 处理视频所需的包
sudo apt-get install libatlas-base-dev gfortran          # 优化opencv功能
sudo apt-get install ffmpeg

这里我也遇到了一些问题,不知道是边缘主机的问题还是怎么,因为我一拿到机器就替换了apt-get的源,后边在使用suao apt-get update的时候会一直报错http 404说是找不到目的源,清华和阿里云都试过了,最后还是还原成了边缘主机一开始的源,这里上个图

还原之后,update就没问题了,以上那些依赖包也可以下载了。

接下来就是编译opencv,首先cd到opencv的目录中,注意这里都是sudo,不使用的话会报错permission的问题。

cd opencv

sudo mkdir build

cd build

sudo cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
make install

接下来就是cmake遇到的问题了,我执行cmake命令的时候,居然没有成功,后来查了很多资料说是gcc,g++的问题,我随即按照指示去把我的gcc,g++从7降到了5,但是还是不行。

这里提一下, 有的人cmake失败了,把build删除后重新弄一遍就可以了,我始终不行的。

cd ..
sudo rm -r build
sudo mkdir build
cd build

最后很离谱的就是想起来去upgrade一下,后来居然可以了。

sudo apt-get update
sudo apt-get upgrade

cmake这关终于过去了。

后面就是make,在make的时候也遇到了一些问题。

第一个问题就是进行到百分之60左右的时候报错找不到glib.h,我已经使用了命令安装了glib2.0-dev,正常的情况下你在,/usr/include目录下应该可以看到glib2.0这个文件夹,但是我的就是没有,每次安装还是提示我已经是最新的了。

sudo apt-get install libglib2.0-dev

这里还去下载了deb文件和源码文件来使用,都无果,最后的解决方法还是,卸载,更新,重新下,然后就有了。

sudo apt-get remove libglib2.0-dev
sudo apt-get update
sudo apt-get install libglib2.0-dev
cd /usr/include

有了之后,重新cmake然后make,这次终于不报错找不到glib.h了。

第二个问题就是编译的时候报错:

undefined reference to `cblas_sgemm(CBLAS_ORDER, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, int, int, int, float, float const, int, float const, int, float, float*, int)

这个报错要感谢下边这个文章 https://blog.csdn.net/dbdxnuliba/article/details/106895321 但是在编译lapack时,报错了,最终编译lapack时按照的是这边文章https://blog.csdn.net/mlnotes/article/details/9676269

这里我在下边附录中记录一下这个过程。

这个问题解决后又重新cmake然后make,这次没有报错了。成功的编译成功,执行sudo make install后,opencv就编译完成了。

下面就是把opencv配置到环境中。

sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

最后运行测试。

测试我在build下面新建了opencv_test文件夹,cd进去后,创建了opencv_test.cpp文件。

sudo mkdir opencv_test
cd opencv_test
sudo gedit opencv_test.cpp

测试文件如下:

#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include <iostream>
 
using namespace cv;
using namespace std;
 
 
int main()
{
  cout << "Built with OpenCV " << CV_VERSION << endl;
  VideoCapture video;
  video.open("rtsp://admin:admin123@192.168.1.116:554/h264/ch1/main/av_stream");
  if(!video.isOpened())
  {
    cout << "open video file failed. " << endl;
    return -1;
  }
	
  while(true)
  {
    Mat frame;
    video>>frame;
    if(!frame.empty())
    {
      imshow("video", frame);
    }
 
    if(waitKey(30) == 27)
    {
      break;
    }
  }
 
  return 0;
}

然后创建CMakeLists.txt文件。

sudo gedit CMakeLists.txt

文件内容如下:

project(opencv_test)
find_package(OpenCV REQUIRED)
add_executable(opencv_test opencv_test.cpp)
target_link_libraries(opencv_test ${OpenCV_LIBS})

然后编译执行。

sudo cmake .
sudo make
sudo ./opencv_test

执行的测试的以后遇到了一些问题。

第一个问题就是报错找不到gtk,可能是因为你没有正确安装gtk2.0-dev,安装正常后重新编译没有报错了。

第二个问题就是报错:

Gtk-Message:Failed to load module &quot;canberra-gtk-module&quot;

执行命令后解决。

sudo apt-get install libcanberra-gtk-module

至此opencv的编译和测试就完成了。

2.darknet

首先下载darknet源码

git clone https://github.com/AlexeyAB/darknet.git

 下载完成后,解压,进入文件夹

cd darknet
gedit Makefile

找到Makefile文件,打开后先将GPU=1,OPENCV=1,然后修改ARCH后的参数和你的GPU有关,此处我的是72。

which nvcc

 然后将Makefile文件中的nvcc路径改为查到的路径。保存即可。

sudo make -j8

 编译完成后,进行测试。

图片测试命令:

./darknet detect yolo4/yolov4.cfg yolo4/yolov4.weights data/dog.jpg

视频测试命令:

./darknet detector demo cfg/coco.data yolo4/yolov4.cfg yolo4/yolov4.weights data/test.mp4

 如果遇到报错例如,文件无法打开等问题,这大概率是因为你的cfg或data文件是从windows拷贝来的,所以需要修改一下文件格式。

vi ./yolov4.cfg
:set ff=unix

如果遇到报错例如,no kernal image is available for execution on the device,这大概率是因为在编译前你的arch设置错误,确定后重新编译,再次运行

这里,检测一张768x576的图片的时间大约为1300毫秒左右吗,检测视频的fps为2.5左右,可见效率并不理想,将继续做优化。

 

3.TensorRT

因为在不适用tensorrt的情况下跑yolo的确太吃力了,所以这里实验下接入tensorrt后,看看检测效率会不会有提升。

首先检查你的jetson上有没有装好tensorrt,这里可以使用jtop工具,很实用,这里附上安装使用教程:

https://blog.csdn.net/chongzi865458/article/details/102789374/

可以看到下部的info,里面包含了jetson的信息,其中就有tensorrt,大多数人应该这里都显示了版本号,所以是已经安装好的,我的显示NOT_INSTALLED,所以你还要看看你的/usr/lib/aarch64-linux-gnu/下有没有libnvinfer.so,libnvinfer.so.7,libnvinfer.so.7.1.3等链接库文件,有的说明你的tensorrt也是安装好的,如果没有,那么就使用如下命令进行安装:

sudo apt-get install tensorrt

 这里可能会遇到科学上网的问题,但是其实你所需要的包在普通网络下就可以下载完,我是在下载samples的时候,下不动导致失败,所以就没有使用samples,但是/usr/lib/aarch64-linux-gnu/下已经存在需要的文件。

确定tensorrt安装好之后,这里要说下我的jtop一眼无法显示出tensorrt版本,依然是NOT_INSTALLED,没关系后边不耽误使用。

到了这里附上一篇干货:https://github.com/enazoe/yolo-tensorrt

darket下可以接入tensorrt,按照指定操作就可以运行,这里注意要把类型从INT8改为FP32,因为使用INT8会使用图像矫正,会报错。

这里附下权重文件:https://share.weiyun.com/dcMV5hG1

核心代码在modules中,配置文件在configs中,测试代码在samples中,这里附上一个实时视频的测试文件:

#include "class_timer.hpp"
#include "class_detector.h"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include <memory>
#include <thread>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
	Config config_v3;
	config_v3.net_type = YOLOV3;
	config_v3.file_model_cfg = "../configs/yolov3.cfg";
	config_v3.file_model_weights = "../configs/yolov3.weights";
	config_v3.calibration_image_list_file_txt = "../configs/calibration_images.txt";
	config_v3.inference_precison =FP32;
	config_v3.detect_thresh = 0.5;

	Config config_v3_tiny;
	config_v3_tiny.net_type = YOLOV3_TINY;
	config_v3_tiny.detect_thresh = 0.7;
	config_v3_tiny.file_model_cfg = "../configs/yolov3-tiny.cfg";
	config_v3_tiny.file_model_weights = "../configs/yolov3-tiny.weights";
	config_v3_tiny.calibration_image_list_file_txt = "../configs/calibration_images.txt";
	config_v3_tiny.inference_precison = FP32;

	Config config_v4;
	config_v4.net_type = YOLOV4;
	config_v4.file_model_cfg = "../configs/yolov4.cfg";
	config_v4.file_model_weights = "../configs/yolov4.weights";
	config_v4.calibration_image_list_file_txt = "../configs/calibration_images.txt";
	config_v4.inference_precison =FP32;
	config_v4.detect_thresh = 0.5;

	Config config_v4_tiny;
	config_v4_tiny.net_type = YOLOV4_TINY;
	config_v4_tiny.detect_thresh = 0.5;
	config_v4_tiny.file_model_cfg = "../configs/yolov4-tiny.cfg";
	config_v4_tiny.file_model_weights = "../configs/yolov4-tiny.weights";
	config_v4_tiny.calibration_image_list_file_txt = "../configs/calibration_images.txt";
	config_v4_tiny.inference_precison = FP32;

	Config config_v5;
	config_v5.net_type = YOLOV5;
	config_v5.detect_thresh = 0.5;
	config_v5.file_model_cfg = "../configs/yolov5-4.0/yolov5s.cfg";
	config_v5.file_model_weights = "../configs/yolov5-4.0/yolov5s.weights";
	config_v5.calibration_image_list_file_txt = "../configs/calibration_images.txt";
	config_v5.inference_precison = FP32;


	std::unique_ptr<Detector> detector(new Detector());
	detector->init(config_v4_tiny);

	VideoCapture video;
	video.open("rtsp://admin:admin123@192.168.1.116:554/h264/ch1/main/av_stream");
	if(!video.isOpened())
	{
		cout << "open video file failed. " << endl;
		return -1;
	}

	std::vector<BatchResult> batch_res;	
	Timer timer;


	while(true)
	{
		Mat frame;
		video>>frame;
		std::vector<cv::Mat> batch_img;
		if(!frame.empty())
		{
			batch_img.push_back(frame);
			timer.reset();
			detector->detect(batch_img, batch_res);
			timer.out("detect");
			for (int i=0;i<batch_img.size();++i)
			{
				for (const auto &r : batch_res[i])
				{
					std::cout <<"batch "<<i<< " id:" << r.id << " prob:" << r.prob << " rect:" << r.rect << std::endl;
					cv::rectangle(batch_img[i], r.rect, cv::Scalar(255, 0, 0), 2);
					std::stringstream stream;
					stream << std::fixed << std::setprecision(2) << "id:" << r.id << "  score:" << r.prob;
					cv::putText(batch_img[i], stream.str(), cv::Point(r.rect.x, r.rect.y - 5), 0, 0.5, cv::Scalar(0, 0, 255), 2);
				}
				cv::imshow("image"+std::to_string(i), batch_img[i]);
			}
			cv::waitKey(10);
		}
	
		if(waitKey(30) == 27)
		{
			break;
		}
	}
}

这里测试yolo4的detect时间大约为110ms左右,tiny版本大约为20ms左右,相比于不使用tensorrt的一秒3帧已经很不错了。 

 

 

附录1:blas、lapack、cblas在Ubuntu上的安装

 

1.确保机器上安装了gfortran编译器,如果没有安装的话,可以使用

sudo apt-get install gfortran

 

2.下载blas, cblas, lapack 源代码

这些源码都可以在 http://www.netlib.org 上找到,下载并解压。这里提供我安装时的下载链接 

http://www.netlib.org/blas/blas.tgz
       http://www.netlib.org/blas/blast-forum/cblas.tgz
       http://www.netlib.org/lapack/lapack-3.4.2.tgz
       解压之后会有三个文件夹,BLAS-3.8.0, CBLAS, lapack-3.4.2

 

3.这里就是具体的编译步骤(一定要按照顺序)

tar xvf blas.tgz  #解压三个文件

1)编译blas

进入BLAS文件夹,执行以下几条命令

gfortran -c  -O3 *.f  # 编译所有的 .f 文件,生成 .o文件 注意这里的不是零3  而是大写的O
ar rv libblas.a *.o  # 链接所有的 .o文件,生成 .a 文件
sudo cp libblas.a /usr/local/lib  # 将库文件复制到系统库目录

##################################################################

#如果上面代码有问题,可以试试下面的编译方法
gfortran -c  -O3  -fPIC  *.f # 编译所有的 .f 文件,生成 .o文件   加上了-fPIC
gcc -shared *.o -fPIC -o  libblas.so
cp libblas.so /usr/local/lib/
ar rv libblas.a *.o  # 链接所有的 .o文件,生成 .a 文件  
su cp libblas.a /usr/local/lib  # 将库文件复制到系统库目录

2)编译cblas

进入CBLAS文件夹,首先根据你自己的计算机平台,将目录下某个 Makefile.XXX 复制为 Makefile.in , XXX表示计算机的平台,如果是Linux,那么就将Makefile.LINUX 复制为 Makefile.in,然后执行以下命令

cp ../BLAS-3.8.0/libblas.a  testing  # 将上一步编译成功的 libblas.a 复制到 CBLAS目录下的testing子目录
make # 编译所有的目录
sudo cp lib/cblas_LINUX.a /usr/local/lib/libcblas.a # 将库文件复制到系统库目录下

3)编译 lapack以及lapacke

这一步比较麻烦,首先当然是进入lapack-3.4.2文件夹,然后根据平台的特点,将INSTALL目录下对应的make.inc.XXX 复制一份到 lapack-3.4.2目录下,并命名为make.inc, 这里我复制的是 INSTALL/make.inc.gfortran,因为我这里用的是gfortran编译器。

修改lapack-3.4.2/Makefile, 因为lapack以来于blas库,所以需要做如下修改

#修改~!
#lib: lapacklib tmglib
lib: blaslib variants lapacklig tmglib

接下来编译

make # 编译所有的lapack文件
cd lapacke # 进入lapacke 文件夹,这个文件夹包含lapack的C语言接口文件
make # 编译lapacke
cp include/*.h /usr/local/include #将lapacke的头文件复制到系统头文件目录
cd .. #返回到 lapack-3.4.2 目录
cp *.a /usr/local/lib # 将生成的所有库文件复制到系统库目录

这里的头文件包括: lapacke.h, lapacke_config.h, lapacke_mangling.h, lapacke_mangling_with_flags.h lapacke_utils.h

生成的库文件包括:liblapack.a, liblapacke.a, librefblas.a, libtmglib.a

至此cblas和lapack就成功安装到你的电脑上了。

 

 

附录2:在Ubuntu18.04 Arm64架构下编译和运行c#程序

 

1.安装SDK

首先需要在系统中安装.Net的SDK,网址如下:

https://docs.microsoft.com/zh-cn/dotnet/core/install/linux

按照指引进行安装,注意:

这里选择手动安装。

按照指引就可以安装完成并将dotnet写入到环境变量中。

 

2.安装Visual Studio Code

直接进入vscode官网选择对应版本安装即可。

这里进入vscode后会提示安装c#的扩展,这里不用安装,因为扩展不支持aarch架构。

 

3.测试

打开终端输入:

$ dotnet new console -o testconsole
$ code testconsole

这时会有一个新的vscode窗口出现,在vscode终端中输入:

$ dotnet restore
$ dotnet run

程序即可运行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值