0、docker

0.0 docker 介绍

Docker官网:链接
Docker中文社区:链接
Docker Hub :链接

DevOps 开发运维
CI/CD 持续集成 持续部署

DockerHub 简书参考链接
什么是 DockerHub 以及为什么它很重要?
DockerHub 是一个由 Docker 公司运行和管理的基于云的存储库。它是一个在线存储库,Docker 镜像可以由其他用户发布和使用。有两种库:公共存储库和私有存储库。如果你是一家公司,你可以在你自己的组织内拥有一个私有存储库,而公共镜像可以被任何人使用。

你也可以使用公开发布的官方 Docker 镜像。DockerHub 上发布了数千镜像供你使用。DockerHub 作为默认存储库硬编码到 Docker 中,所以当你对任何镜像运行 docker pull 命令时,它将从 DockerHub 下载。

镜像和容器
通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量和配置文件。
容器是镜像的运行实例,当被运行时有镜像状态和用户进程,可以使用docker ps 查看。

大白话讲解Docker是什么?
容器(动态),镜像运行实体(静态)
容器和虚拟机的区别?
虚拟机:就是模拟正泰机器包含硬件,每台虚拟机都需要自己的操作系统,虚拟机开启了,预分配资源全部被占用。

docker:和宿主机共享硬件资源及操作系统实现资源动态分配,与其他容器共享内核。
docker启动属于秒级,虚拟机启动需要几分钟
docker轻量,占用资源很少,一般一个容器才几十M
docker容器创建 删除 都是分钟的

  1. 查看内存:free -lh
  2. 查看版本:cat /etc/lsb-release
  3. 内核详细信息:cat /etc/os-release
  4. 内核基本信息:uname -r
  5. 显卡:nvidia-smi
  6. cuda版本:nvcc -V

nvidia-docker2的安装需要和docker版本一致,因此需要查询本地docker版本

sudo docker -v

然后查询可安装的nvidia-docker2及nvidia-container-runtime

apt-cache madison nvidia-docker2 nvidia-container-runtime

查看NVIDIA-Docker版本和docker版本:

nvidia-docker version

0.1 docker基本指令

基本指令:

搜索镜像:docker search 
获取镜像: docker pull
查看镜像:docker images
删除镜像:docker rmi

重启docker:systemctl start docker
docker版本:docker -v
随机启动nginx 容器 随机端口 docker run -d -p 80:80 --name mynginx nginx  -d表示后台运行  --name 别名

查看容器启动情况: docker ps
进入容器:docker exec -it id /bin/bash
查看日志情况:docker logs Name/ID
查看最近20行日志:docker logs  -f --tail -20 id

显示一个运行的容器里面的进程信息:docker top id
停止容器:docker stop id
启动容器:docker start id
查看容器启动情况:docker ps
查询所有容器:docker ps -a

强制停止容器:docker kill id
删除容器:docker rm id
强制删除容器:docker rm -f id

查看容器日志:docker logs id
首先docker images 查看容器名称和别名
批量停止容器:docker rm -f $(docker ps -aq)
docker run -d -p 81:80 --name myngin1 nginx

查看docker的硬盘空间使用情况:docker system df

0.2 docker 实例

eg:

sudo docker pull ubuntu #下拉一个镜像,如果本地没有进行网上下载
sudo docker run -i -t ubuntu /bin/bash #i 交互式操作 t 代表一个终端 ubuntu:镜像名字 /bin/bash 交互式shell  指令运行后进入ubuntu终端
cd home  #进入ubuntu home 目录
exit #退出这个容器
sudo docker ps #查询运行的容器
sudo docker ps -a #查询所有的容器 包括没有运行的容器
sudo start id # 启动停止的容器
sudo docker ps # 查看上条指令是否启动容器
sudo docker run -i -t -d --name ubuntu-test ubuntu /bin/bash  #d 后台使用 name进行名字命名
sudo docker stop id #停止容器
sudo docker ps # 查看是否停止容器
sudo docker restart id # 重启停止的容器
sudo docker ps # 查看容器是否重启
sudo docker attach id #进入终端
exit # 退出
sudo docker ps # 查看容器状态 容器退出终止
sudo docker restart id # 启动容器
sudo docker ps # 查看是否启动 启动
sudo docker exec -it id /bin/bash #进入容器
exit  # 退出容器
sudo docker ps # 容器没有终止

###########容器导出导入
mkdir ubuntu-t  #创建文件夹
cd ubuntu-t  # 进入文件夹
sudo docker export id > ubuntu.tar #导出
ls  # 显示ubuntu.tar 导出成功
cat /ubuntu.tar | sudo docker import - test/ubuntu:v1
sudo docker images #查看镜像是否导入成功
sudo docker ps -a #查询所有镜像
sudo docker rm -f id # 删除镜像

sudo docker pull training/webapp #拉镜像
sudo docker run -d -P training/webapp python app.py #运行镜像 大写的P
sudo docker ps
sudo docker run -d -p 5000:5000 training/webapp python app.py# 更改端口号  内部5000转本地5000 小写的p
sudo docker port id #
sudo docker logs -f id #运行日志查询
sudo docker top id #查询当前进程
sudo docker inspect id #查询配置与状态信息
sudo docker stop id #停止

sudo docker images # 镜像
sudo docker search httpd#查找镜像
sudo docker pull httpd# 拉镜像
sudo docker images
sudo docker rmi httpd#删除镜像
sudo docker ps #找容器
sudo docker commit -m="update" -a="fu" bf25 ubuntu-fu:v2  #创建镜像 
sudo docker images
mkdir Dockerfile  # 创建镜像的另一种方法
cd Dockerfile
gedit Dockerfile
	from ubuntu:18.04 
	run apt-get update
sudo docker build -t fu/ubuntu .#运行

1、nvidia最新驱动安装

若在容器中使用nvidia驱动,则需要安装nvidia-docker。(宿主机中已经安装好nvidia驱动)
宿主机手动安装与docker镜像文件中一致的nvidia驱动
参考链接:
https://blog.csdn.net/chxw098/article/details/79741586
https://blog.csdn.net/a12345676abc/article/details/84302513
安装前注意:安装nvidia-docker之前,需要先给宿主机安装nvidia驱动,docker内不需要安装驱动!

宿主机手动安装与docker镜像文件中一致的nvidia驱动

宿主机手动安装驱动:desktop版本和server版本驱动安装链接如下
https://blog.csdn.net/zml194849/article/details/121827610

2、docker 和nvidia-docker的安装

2.1 docker 的安装

1)可选操作,卸载旧版本

sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update

2)安装软件包以允许apt通过HTTPS使用存储库:

sudo apt-get install \apt-transport-https \ca-certificates \curl \gnupg-agent \software-properties-common

3)添加Docker的官方GPG密钥:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -  

9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 通过搜索指纹的后8个字符,验证您现在是否拥有带有指纹的密钥 。

$ sudo apt-key fingerprint 0EBFCD88

pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb) docker@docker.com
sub rsa4096 2017-02-22 [S]

4) 使用以下命令来设置稳定的存储库。请在以下命令中的单词后面添加nightly或test(或同时添加)stable。
注意:下面的lsb_release -cs子命令返回Ubuntu发行版的名称,例如xenial。有时,在Linux Mint等发行版中,您可能需要更改$(lsb_release -cs) 为父Ubuntu发行版。例如,如果您使用 Linux Mint Tessa,则可以使用bionic。Docker对未经测试和不受支持的Ubuntu发行版不提供任何保证。

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

jetson_nano命令(jetson_nano自带docker)

sudo add-apt-repository \
   "deb [arch=arm64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

5)更新apt包索引。

 sudo apt-get update

6.安装最新版本的Docker Engine-Community和containerd

sudo apt-get install docker-ce docker-ce-cli containerd.io

可选linux的安装后步骤
以非root用户身份管理Docker
Docker守护程序绑定到Unix套接字而不是TCP端口。默认情况下,Unix套接字由用户拥有root,其他用户只能使用sudo来访问它。Docker守护程序始终以root用户身份运行。
如果你不想在前言docker与命令sudo,创建一个名为UNIX组docker和用户添加到它。Docker守护程序启动时,它会创建一个可由该docker组成员访问的Unix套接字。
1.创建用户组

sudo groupadd docker

2.将您的用户添加到该docker组。

sudo usermod -aG docker $USER

3.注销并重新登录,以便重新评估您的组成员身份。
如果在虚拟机上进行测试,则可能需要重新启动虚拟机以使更改生效。
在桌面Linux环境(例如X Windows)上,完全注销会话,然后重新登录。
在Linux上,您还可以运行以下命令来激活对组的更改:

newgrp docker

4.验证您是否可以运行docker不带命令的命令sudo

docker run hello-world

在这里插入图片描述

docker version

在这里插入图片描述
完成

2.2 ubuntu完全卸载docker

  1. 删除某软件,及其安装时自动安装的所有包
sudo apt-get autoremove docker docker-ce docker-engine  docker.io  containerd runc
  1. 删除docker其他没有没有卸载
dpkg -l | grep docker
dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P # 删除无用的相关的配置文件
  1. 卸载没有删除的docker相关插件(结合自己电脑的实际情况)
    在这里插入图片描述
sudo apt-get autoremove docker-ce-*

  1. 删除docker的相关配置&目录
sudo rm -rf /etc/systemd/system/docker.service.d
sudo rm -rf /var/lib/docker
  1. 确定docker卸载完毕
docker --version

2.3 安装nvidia-docker2

(1)移除之前的旧版本

docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
sudo apt-get purge -y nvidia-docker

(2)添加环境配置

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update

(3)安装nvidia-docker2版本,备注:nvidia-docker2和nvidia-docker1区别后续说明。

sudo apt-get install -y nvidia-docker2
sudo pkill -SIGHUP dockerd

(4)安装 nvidia-container-runtime 软件包:

sudo apt-get install nvidia-container-runtime

(5)添加docker守护进程文件
docker的守护进程参数配置一般在文件 /etc/docker/daemon.json,在该文件中写入

{
    "default-runtime" : "nvidia",
 
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

配置完成后,重启docker

systemctl restart docker

(6)测试
从Docker Hub查找镜像—https://www.runoob.com/docker/docker-search-command.html

2.4 docker 示例

语法

docker search [OPTIONS] TERM
OPTIONS说明:
--automated :只列出 automated build类型的镜像;
--no-trunc :显示完整的镜像描述;
-s :列出收藏数不小于指定值的镜像。

实例

从Docker Hub查找所有镜像名包含java,并且收藏数大于10的镜像

runoob@runoob:~$ docker search -s 10 java
NAME                  DESCRIPTION                           STARS   OFFICIAL   AUTOMATED
java                  Java is a concurrent, class-based...   1037    [OK]       
anapsix/alpine-java   Oracle Java 8 (and 7) with GLIBC ...   115                [OK]
develar/java                                                 46                 [OK]
isuper/java-oracle    This repository contains all java...   38                 [OK]
lwieske/java-8        Oracle Java 8 Container - Full + ...   27                 [OK]
nimmis/java-centos    This is docker images of CentOS 7...   13                 [OK]

参数说明:

NAME: 镜像仓库源的名称
DESCRIPTION: 镜像的描述
OFFICIAL: 是否 docker 官方发布
stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
AUTOMATED: 自动构建。

测试

sudo docker run -ti --rm nvidia/cuda:9.0-base nvidia-smi

sudo docker run --runtime=nvidia --rm 5aafb863776b nvidia-smi

(第一次运行该指令会先下载对应版本的镜像文件,可能耗时较长)
下载成功后会输出证明安装成功
在这里插入图片描述

2.5 nvidia-docker1和nvidia-docker2区别

那么两个版本之间有何区别呢?
(1) 虽然nvidia-docker1 和nvidia-docker2 都依赖于docker, 但版本1是一个整体的可行性文件,内部实现连接docker容器与硬件GPU,版本2将整体部分拆分层一个基于docker的薄封装(cat /usr/bin/nvidia-docker 可查看)和一个插件(nvidia-container-runtime , 该插件直接实现一个 hook的功能,连接GPU硬件),在版本2 的nvidia-docker 可发现,实际上还是运行docker ,只是指定了 --runtime 参数,同时指定GPU设备,默认全部GPU设备。
(2)当需要运行一个使用GPU的容器时,版本1 必须用nvidia-docker run/create 启动, 版本二可通过设置 守护进行default-runtime参数可直接通过 docker run/create 直接启动GPU容器
docker的守护进程参数配置一般在文件 /etc/docker/daemon.json

cat /etc/docker/daemon.json
[root@localhost hadoop]# cat /etc/docker/daemon.json
{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

配置默认的插件环境 后

{
  "default-runtime" : "nvidia", 

  "runtimes": {
       		"nvidia": {
       			"path": "nvidia-container-runtime",
       			"runtimeArgs": []
      		}
  	}
}

配置完成后,重启docker

systemctl restart docker

docker容器的导入导出有两个方式docker export和docker import以及docker save和docker load。docker import和docker load导入都是导入成一个镜像,然后再跑一个容器。

docker export导出的是容器的快照,不会保存元数据。然后如果用这一种方式,就算你在你机器上创建的容器导出再导入都会出错。会使用不了GPU资源。所以,如果你想让其他人也使用也就需要使用docker save,docker save是针对镜像的,所以我们需要先将我们搭建好的docker容器提交为一个镜像:

sudo docker commit container-name image-name:version

sudo docker commit 容器id 镜像名(自定义):版本(自定义)
然后使用docker save命令导出就好(save命令导出的是docker镜像文件,注意与容器文件区分):

docker save -o image-name.tar image-name:version

然后就OK了

3、cuda10.2 docker拉取及docker ssh配置

3.1 deepstream5.0 镜像获取(适合无opencv需求场景)

1、环境配置
配置环境是一个很麻烦的事情,推荐直接在nvidia ngc中下载docker来进行部署。
事前准备:需要注册nvidia的ngc平台,在用户设置中获取到自己的key,该平台储存了nvidia预训练的模型和一些专用的docker image,比如deepstream sdk 和Transfer Learning Toolkit。
注册账号:官网地址https://ngc.nvidia.com/,注册后登录生成API Key(重要)https://ngc.nvidia.com/setup
然后在Generate API Key中点击Get API Key,点击右上角绿色按钮Generate API Key

1.1 安装docker和nvidia-docker2

apt-get update
apt-get install docker
apt-get install nvidia-docker2

1.2 登录nvidia的ngc平台下载deestream镜像

docker login nvcr.io

Username: $oauthtoken

Password:bjBsMHJucnFzOHY5dmw4YzFzMzNhbmFtcTc6ZDM5Y2RlODAtM2I0MS00Y2VmLWFmZTctMmFmYmZlZmI5MWRk

输入自己在平台获取到的Username和Password。如果未登录,在下载镜像时会出现验证错误的字样。

下载镜像并运行,使用docker images查看所有镜像,使用docker ps查看运行中的镜像
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_docker_containers.html

docker拉取镜像。推荐早上5,6点的时候下载 docker pull
nvcr.io/nvidia/deepstream:5.0-dp-20.04-triton

#允许外部连接主机xhost +# 第一种镜像运行方法,使用-v来挂载需要导入镜像的目录,-p设置镜像接口,方便之后ssh登入。
docker run --gpus all --privileged=true -it -v /home/jdh/data:/root/host -p 5000:22 -m 2g -e DISPLAY=$DISPLAY -w /opt/nvidia/deepstream/deepstream-5.0 nvcr.io/nvidia/deepstream:5.0-dp-20.04-triton

#该命令可以输出显示图像
docker run --gpus all --privileged=true -it -v /tmp/.X11-unix:/tmp/.X11-unix -p 5000:22 -m 2g -e DISPLAY=$DISPLAY -w /opt/nvidia/deepstream/deepstream-5.0 nvcr.io/nvidia/deepstream:5.0-dp-20.04-triton

#第二种镜像运行方法,当执行推理出现内存空间不够时用
nvidia-docker run --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --rm -it -v /tmp/.X11-unix:/tmp/.X11-unix -p 127.0.0.1:5000:22 -m 2g -e DISPLAY=$DISPLAY -w /opt/nvidia/deepstream/deepstream-5.0 nvcr.io/nvidia/deepstream:5.0-dp-20.04-triton

docker run --gpus all --net=host --privileged=true -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/jdh/data:/root/software -p 6000:22 -m 2g -e DISPLAY=$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE -w /opt/nvidia/deepstream/deepstream-5.0 nvcr.io/nvidia/deepstream:5.0-dp-20.04-triton

错误解决1

unknown flag: --gpus

docker版本要>19.03才支持gpu选择
在jetson_nano上配置docker注意事项
在docker中画面显示

#宿主机
$DISPLAY
#在docker容器中添加当前使用xshell的ip以及端口—只适合CPU显示
export DISPLAY=192.168.1.64:10.0

ps:docker --privileged=true 参数作用

  • 大约在0.6版,privileged被引入docker。
  • 使用该参数,container内的root拥有真正的root权限。
  • 否则,container内的root只是外部的一个普通用户权限。
  • privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。
  • 甚至允许你在docker容器中启动docker容器。

$ docker help run

–privileged=false Give extended privileges to this container

这里以一个Mysql 例子
我们启动命令还没加 --privileged=true 参数 ,可以明确看到docker 尝试去运行容器,但是马上就关闭了。
命令

docker run --name mysql-test -e MYSQL_ROOT_PASSWORD=123456 -p 9092:3306 -d daocloud.io/library/mysql:5.7.6

尝试使用一些命令,提示permission denied,权限禁止
在这里插入图片描述
加入参数命令后

docker run --name mysql-test --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -p 9092:3306 -d daocloud.io/library/mysql:5.7.6

在这里插入图片描述

成功运行命令

3.2 获取cuda10.2镜像(适合有opencv需求场景)

1.去dockerhub搜索自己需要的cuda等镜像,或者可以使用docker search查找镜像
2.拉去合适的镜像

sudo docker pull nvidia/cuda:10.1-cudnn7-devel-ubuntu16.04
sudo docker pull nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04

3.创建容器
通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径
现在镜像内就可以共享宿主机里的文件了。
默认挂载的路径权限为读写。

#允许外部连接主机xhost +# 第一种镜像运行方法,使用-v来挂载需要导入镜像的目录,-p设置镜像接口,方便之后ssh登入。
#该命令可以输出显示图像
docker run --gpus all --net=host --privileged=true -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/jdh/disk_4t:/root/host_data -p 6000:22 -m 2g -e DISPLAY=$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE -w /root nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04
docker run --gpus all --net=host --privileged=true -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/jdh/disk_4t:/root/host_data -p 60000:22 -m 2g -e DISPLAY=$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE -w /root nvidia/cuda:8.0-cudnn7-devel-ubuntu16.04

可能问题:
1.nvcc: command not found解决
添加环境变量,打开~/.bashrc ,添加环境变量如下:

export LD_LIBRARY_PATH=/usr/local/cuda/lib
export PATH=$PATH:/usr/local/cuda/bin

2.错误解决2

unknown flag: --gpus

docker版本要>19.03才支持gpu选择

3.在docker中画面显示

#在docker容器中添加当前使用xshell的ip以及端口
export DISPLAY=192.168.1.64:10.0

ps:docker --privileged=true 参数作用

  • 大约在0.6版,privileged被引入docker。
  • 使用该参数,container内的root拥有真正的root权限。
  • 否则,container内的root只是外部的一个普通用户权限。
  • privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。
  • 甚至允许你在docker容器中启动docker容器。
 $ docker help run 
...
--privileged=false         Give extended privileges to this container
...

这里以一个Mysql 例子
我们启动命令还没加 --privileged=true 参数 ,可以明确看到docker 尝试去运行容器,但是马上就关闭了。
命令

docker run --name mysql-test -e MYSQL_ROOT_PASSWORD=123456 -p 9092:3306  -d daocloud.io/library/mysql:5.7.6

尝试使用一些命令,提示permission denied,权限禁止
在这里插入图片描述
加入参数命令后

docker run --name mysql-test --privileged=true -e MYSQL_ROOT_PASSWORD=123456 -p 9092:3306  -d daocloud.io/library/mysql:5.7.6

在这里插入图片描述
成功运行命令

3.3 docker ssh配置

3.3.1 运行容器

1、运行容器

docker run --name iubuntu -t -i -d -p 3316:22 ubuntu

参数:
–name: 指定生成的容器的名称
-i: 以交互模式运行容器,保证容器中STDIN是开启的。通常与 -t 同时使用;
-t: 为容器重新分配一个伪tty终端,通常与 -i 同时使用;
-d: 后台运行容器,并返回容器ID;
-p:可以指定要映射的IP和端口,但是在一个指定端口上只可以绑定一个容器。支持的格式有 hostPort:containerPort、ip:hostPort:containerPort、 ip::containerPort。
ubuntu 则是镜像名称,镜像ID也可以的。

2、查看是否运行成功#
查看正在运行的镜像

docker ps

3.3.2 安装ssh服务
  1. 进入容器终端安装ssh服务

bash docker exec -t -i iubuntu /bin/bash

在这里插入图片描述

  1. 执行更新

apt-get update

等待,输入Y就可以了
在这里插入图片描述
3. 安装ssh-client、ssh-server
安装ssh-client命令#

apt-get install openssh-client

等待,输入Y就可以了
在这里插入图片描述
安装ssh-server命令#

apt-get install openssh-server

等待,输入Y就可以了
在这里插入图片描述
安装完成后,先启动服务

/etc/init.d/ssh start

在这里插入图片描述查看是否正确启动

ps -e|grep ssh

在这里插入图片描述

编辑sshd_config文件
需要先安装vim编辑器

apt-get install vim

在这里插入图片描述编辑sshd_config文件

vim /etc/ssh/sshd_config

在这里插入图片描述添加UsePAM no
在这里插入图片描述
保存退出 ESC + : + WQ
ps:如果无法进入端口可在宿主机查看端口是否被占用,更换端口

sudo netstat -ap | grep 6000

如果还不行,可以在docker中该文件下更改端口号为自己设置的端口号,也可以远程接入
在这里插入图片描述
重启ssh服务

service ssh restart

在这里插入图片描述
设置ssh密码

passwd root

在这里插入图片描述
查看容器的IP
先安装net-tools工具包

apt-get install net-tools

在这里插入图片描述查看IP

apt-get install net-tools
ifconfig

在这里插入图片描述退出

exit

4、保存刚刚修改的镜像,方便后面使用

docker commit [容器ID/容器名] [REPOSITORY:TAG]

3.3.3 使用Xshell连接

1、测试
打开一个新终端,通过ssh root@host_ip -p 3316 进入docker:
在这里插入图片描述

2、在本机连接可以用localhost:3316连接也可以用宿主机IP:3316连接,账户名为root
在这里插入图片描述

然后连接就可以了 #
在这里插入图片描述

ps:docker修改容器端口映射的方法
方法一
1、停止容器(docker stop d00254ce3af7)
2、停止docker服务(systemctl stop docker)
3、修改这个容器的hostconfig.json文件中的端口(原帖有人提到,如果config.v2.json里面也记录了端口,也要修改)
hostconfig.json文件
在这里插入图片描述

config.v2.json文件
在这里插入图片描述

sudo -s
cd /var/lib/docker/containers/d00254ce3af7*     #这里是CONTAINER ID

vim hostconfig.json
如果之前没有端口映射, 应该有这样的一段:
"PortBindings":{}

增加一个映射, 这样写:
"PortBindings":{"8080/tcp":[{"HostIp":"","HostPort":"60000"}]}
前一个数字是容器端口, 后一个是宿主机端口。将宿主机的60000端口映射到容器的8080端口
而修改现有端口映射更简单, 把端口号改掉就行。
1

3、启动docker服务(systemctl start docker)
4、启动容器(docker start d00254ce3af7)

4、CUDA10.1 +CUDNN+nvidia video codec sdk 9.1安装

4.1 CUDA10.1

https://blog.csdn.net/zml194849/article/details/121832894

4.2 CUDNN安装

cuda10.1对应cudnn版本
cudnn-10.1-linux-x64-v7.6.3.30.tgz

4.3 nvidia video codec sdk 9.1安装

注意:GPU编解码必备!!!否则后续opencv编译会报错
在这里插入图片描述

fatal error: nvcuvid.h: No such file or directory

参考:https://blog.csdn.net/chanzhennan/article/details/90451968

1.需要在英伟达官网把需要的组件下载下来(https://developer.nvidia.com/nvidia-video-codec-sdk#Download),当前最新为9.1版本

2.解压缩之后把 Video_Codec_SDK_9.1.23/include/ 下面的cuviddec.h 和 nvcuvid.h文件拷贝到/usr/include下面就好了

3.继续后续操作即可

4.4 参考

https://blog.csdn.net/BigData_Mining/article/details/99670642

5.ffmpeg + nv-codec-headers9.1安装

5.1 安装ffmpeg

5.1.1 安装基础依赖
sudo apt-get update
sudo apt-get -y install autoconf automake build-essential libass-dev libfreetype6-dev \
  libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev \
  libxcb-xfixes0-dev pkg-config texinfo zlib1g-dev
apt-get install yasm -y && apt-get install libx264-dev -y && apt-get install libx265-dev -y && \
apt-get install libvpx-dev -y && \
apt-get install libfdk-aac-dev -y && \
apt-get install libmp3lame-dev -y && \
apt-get install libopus-dev -y
5.1.2 安装yasm 汇编编译器

编译某些依赖库的时候需要

sudo apt-get install yasm #版本为1.3
5.1.3 安装lib264 H.264视频编码器

如果需要输出H.264编码的视频就需要此库,所以可以说是必备

sudo apt-get install libx264-dev #版本为148
5.1.4 安装libx265

(显卡不一定支持265编码)
H.265/HEVC视频编码器。
如果不需要此编码器,可以跳过,并在ffmpeg的configure命令中移除–enable-libx265

sudo apt-get install libx265-dev
5.1.5 安装 libvpx

VP8/VP9视频编/解码器
如果不需要此编/解码器,可以跳过,并在ffmpeg的configure命令中移除–enable-libvpx

sudo apt-get install libvpx-dev #版本为1.5
5.1.6 安装 安装libfdk-aac AAC音频编码器,必备
sudo apt-get install libfdk-aac-dev # 无版本要求
5.1.7 安装libmp3lam MP3音频编码器,必备
sudo apt-get install libmp3lame-dev
5.1.8安装libopus

OPUS音频编码器
如果不需要此编码器,可以跳过,并在ffmpeg的configure命令中移除–enable-libopus

sudo apt-get install libopus-dev # 1.1.2
5.1.9 安装NVENC:

安装依赖:

sudo apt-get -y install glew-utils libglew-dbg libglew-dev libglew1.13 \
libglewmx-dev libglewmx-dbg freeglut3 freeglut3-dev freeglut3-dbg libghc-glut-dev \
libghc-glut-doc libghc-glut-prof libalut-dev libxmu-dev libxmu-headers libxmu6 \
libxmu6-dbg libxmuu-dev libxmuu1 libxmuu1-dbg
5.1.10 下载ffmpeg
git clone https://github.com/FFmpeg/FFmpeg ffmpeg -b master

5.2 安装nv-codec-headers9.1

要让ffmpeg能够使用CUDA提供的GPU编解码器,必须重新编译ffmpeg,让其能够通过动态链接调用CUDA的能力
首先要编译安装nv-codec-headers库–https://github.com/FFmpeg/nv-codec-headers/tree/sdk/9.1
https://github.com/FFmpeg/nv-codec-headers
执行如下命令安装:
cuda10.2对应9.1版本,git clone下载的是最新版本,不适合

git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git #此为9.1版本
#有的需要下载9.0版本下载--cuda9.0需要9.0版本 cuda10.2用9.1版本即可
cd nv-codec-headers
make
sudo make install

然后cd到 ffmpeg目录下

5.3 编译ffmpeg

cd到ffmpeg安装目录下

编译命令如下:

./configure --prefix=/usr/local/ffmpeg --disable-asm --disable-x86asm \
 --enable-cuda --enable-cuvid --enable-nvenc \
 --enable-nonfree --enable-libnpp \
 --extra-cflags=-I/usr/local/cuda/include \
 --extra-cflags=-fPIC --extra-ldflags=-L/usr/local/cuda/lib64 \
 --enable-gpl --enable-libx264  --enable-libx265 \
 --enable-shared \
 --enable-libass \
 --enable-libfdk-aac \
 --enable-libfreetype \
 --enable-libmp3lame \
 --enable-libopus \
 --enable-libtheora \
 --enable-libvorbis

make -j8
sudo make -j8 install
make -j8 distclean
hash -r #清除缓存

配置环境

sudo vi /etc/ld.so.conf
添加: /usr/local/ffmpeg/lib
sudo ldconfig

然后为 Ffmpeg 加入环境变量:

sudo vi /etc/profile

加入以下内容

export PATH=/usr/local/ffmpeg/bin:$PATH
export FFMPEG_HOME=/usr/local/ffmpeg
export PATH=$FFMPEG_HOME/bin:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib #添加动态库路径
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/ffmpeg/lib/pkgconfig:/usr/local/lib

执行

source /etc/profile

ffmpeg -h
ffmpeg -version

5.4 常见问题解决

问题1:ERROR: freetype2 not found using pkg-config
解决1:安装freetype 并将路径添加到~/.bashrc中,并source ~/.bashrc
在这里插入图片描述

问题2:ERROR: vorbis not found using pkg-config
解决2:安装依赖库

sudo apt-get install -y autoconf automake build-essential git libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev
apt install libavformat-dev
apt install libavcodec-dev
apt install libswresample-dev
apt install libswscale-dev
apt install libavutil-dev
apt install libsdl1.2-dev

问题3:ERROR: opus not found using pkg-config
解决3:sudo apt-get install libopus-dev

5.5 验证安装

重新安装完ffmpeg,使用ffmpeg -hwaccels命令查看支持的硬件加速选项

Hardware acceleration methods:
cuvid

可以看到多出来一种叫做cuvid的硬件加速选项,这就是CUDA提供的GPU视频编解码加速选项
然后查看cuvid提供的GPU编解码器ffmpeg -codecs | grep cuvid

DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_cuvid ) (encoders: libx264 libx264rgb h264_nvenc nvenc nvenc_h264 )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_cuvid ) (encoders: libx265 nvenc_hevc hevc_nvenc )
 DEVIL. mjpeg                Motion JPEG (decoders: mjpeg mjpeg_cuvid )
 DEV.L. mpeg1video           MPEG-1 video (decoders: mpeg1video mpeg1_cuvid )
 DEV.L. mpeg2video           MPEG-2 video (decoders: mpeg2video mpegvideo mpeg2_cuvid )
 DEV.L. mpeg4                MPEG-4 part 2 (decoders: mpeg4 mpeg4_cuvid )
 D.V.L. vc1                  SMPTE VC-1 (decoders: vc1 vc1_cuvid )
 DEV.L. vp8                  On2 VP8 (decoders: vp8 libvpx vp8_cuvid ) (encoders: libvpx )
 DEV.L. vp9                  Google VP9 (decoders: vp9 libvpx-vp9 vp9_cuvid ) (encoders: libvpx-vp9 )

所有带有"cuvid"或"nvenc"的,都是CUDA提供的GPU编解码器
可以看到,我们现在可以进行h264/hevc/mjpeg/mpeg1/mpeg2/mpeg4/vc1/vp8/vp9格式的GPU解码,以及h264/hevc格式的GPU编码

5.6 转码测试

ffmpeg -i input.flv -c:v h264_nvenc -c:a aac output.mp4

#docker容器中出现问题参考下面解决方法
倍速对比,同样硬件条件下,gpu 提速在7-8倍左右。

frame=21022 fps=398 q=21.0 Lsize=  232698kB time=00:14:36.75 bitrate=2174.2kbits/s dup=137 drop=0 speed=16.6x

播放试了下播放效果,和cpu 播放无明显差别。

5.7 使用GPU进行视频转码

用GPU进行转码的命令和软转码命令不太一样,CPU转码的时候,我们可以依赖ffmpeg识别输入视频的编码格式并选择对应的解码器,但ffmpeg只会自动选择CPU解码器,要让ffmpeg使用GPU解码器,必须先用ffprobe识别出输入视频的编码格式,然后在命令行中指定对应的GPU解码器。
例如,将h264编码的源视频转码为指定尺寸和码率的h264编码视频:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>

使用GPU进行RTSP协议转码测试

ffmpeg -hwaccel cuvid -c:v h264_cuvid -rtsp_transport tcp -i "rtsp://admin:hk888888@192.168.1.235/h264/ch1/main/av_stream" -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y /root/2.mp4

-hwaccel cuvid:指定使用cuvid硬件加速
-c:v h264_cuvid:使用h264_cuvid进行视频解码
-c:v h264_nvenc:使用h264_nvenc进行视频编码
-vf scale_npp=1280:-1:指定输出视频的宽高,注意,这里和软解码时使用的-vf scale=x:x不一样
转码期间使用nvidia-smi查看显卡状态,能够看到ffmpeg确实是在使用GPU进行转码:
±----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 62543 C ffmpeg 193MiB |
±----------------------------------------------------------------------------+

可能错误出现:

[nvenc_hevc @ 0x3f928c0] Driver does not support the required nvenc API version. Required: 9.1 Found: 8.1
[nvenc_hevc @ 0x3f928c0] The minimum required Nvidia driver for nvenc is 390.25 or newer

原因可能是nv-codec-headers的版本是9.1,但是Nvidia driver版本只支持8.1。查看nv-codec-headers的所有tag,checkout到8.1版本,重新编译ffmpeg成功。注意:要彻底删除ffmpeg安装包,重新编译!!!

重点:nvidia-docker2遇到问题及解决

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 1.mp4 -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y out.mp4

错误信息
使用测试命令,可能会报如下错误

Cannot load libnvcuvid.so.1
Cannot load libnvidia-encode.so.1
[h264_nvenc @ 0x17f6270] Cannot load libnvidia-encode.so.1
[h264_nvenc @ 0x17f6270] The minimum required Nvidia driver for nvenc is 445.87 or newer
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

因为docker容器内没有这两个文件,经过我查找发现,在宿主机中有,我们需要拷贝今容器内,然后再作一个软连接。

#在这些目录下查找上述文件
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

找到这两个文件,我们发现,他们其实是软连接
我们ll命令文件,找到原始文件,

libnvcuvid.so.440.100
libnvidia-encode.so.440.100

后面的尾号可能不一样,它是显卡驱动版本号,
我们把这个拷贝到docker中,然后软连接

#宿主机
/usr/lib/x86_64-linux-gnu/libnvcuvid.so.440.100
/usr/lib/x86_64-linux-gnu/libnvidia-encode.so.440.100

# 拷贝到docker这里
/lib64/libnvcuvid.so.440.100
/lib64/libnvidia-encode.so.440.100


# docker内软连接
ln -s /lib64/libnvcuvid.so.440.100 /lib64/libnvcuvid.so.1
ln -s /lib64/libnvidia-encode.so.440.100 /lib64/libnvidia-encode.so.1

# 然后上面的操作,也最好写在dockerfile内

然后

vi /etc/ld.so.conf
#添加软连接路径
/lib64
#更新
ldconfig

最后再次测试GPU视频编解码
参考:https://blog.csdn.net/sunt2018/article/details/107483599

5.8 GPU转码效率测试

在配有两颗Intel-E5-2630v3 CPU和两块Nvidia Tesla M4显卡的服务器上,进行h264视频转码测试,成绩如下:

  • GPU转码平均耗时:8s
  • CPU转码平均耗时:25s
    并行转码时,CPU软转的效率有所提高,3个转码任务并行时32颗核心全被占满,此时的成绩
  • GPU转码平均耗时:8s
  • CPU转码平均耗时:18s
    不难看出,并行时GPU的转码速度并没有提高,可见一颗GPU同时只能执行一个转码任务。那么,如果服务器上插有多块显卡,ffmpeg是否会使用多颗GPU进行并行转码呢?
    很遗憾,答案是否。
    ffmpeg并不具备自动向不同GPU分配转码任务的能力,但经过一番调查后,发现可以通过-hwaccel_device参数指定转码任务使用的GPU!
    向不同GPU提交转码任务
ffmpeg -hwaccel cuvid -hwaccel_device 0 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>
ffmpeg -hwaccel cuvid -hwaccel_device 1 -c:v h264_cuvid -i <input> -c:v h264_nvenc -b:v 2048k -vf scale_npp=1280:-1 -y <output>

-hwaccel_device N:指定某颗GPU执行转码任务,N为数字
此时nvidia-smi显示:
±----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 96931 C ffmpeg 193MiB |
| 1 96930 C ffmpeg 193MiB |
±----------------------------------------------------------------------------+
可以进行并行GPU转码了!
那么在占满服务器资源时,GPU转码和CPU转码的效率如下:

  • GPU转码平均耗时:4s
  • CPU转码平均耗时:18s
    GPU效率是CPU的4.5倍

5.9 参考

https://my.oschina.net/u/2950272/blog/1796874?p=1
https://trac.ffmpeg.org/wiki/CompilationGuide
https://developer.download.nvidia.cn/designworks/ffmpeg/secure/Using_FFmpeg_with_NVIDIA_GPU_Hardware_Acceleration_v01.4.pdf?FmYbMtWf3JOjWSDYR3DOQVGgquEDeykYOYEBSx_41OtHxNVrS9xcm9RBdvjHFzMOCJB8mOvdmHSr3lZim6Bw0mRzd5i8t_qLbyq9oM-kaZA5hrYmTFEMyO05jHPgJSJir2z811llXOzTZYloVQt8YSwWCOZ7sutx1XqwqkhhjE8yKx_LckY679DouhLrvOU4YGCZc60
https://developer.nvidia.com/nvidia-video-codec-sdk/download
https://www.jianshu.com/p/59da3d350488
https://trac.ffmpeg.org/wiki/HWAccelIntro
https://blog.csdn.net/qq_37674858/article/details/81085848

6、docker tensorrt配置

6.1 运行环境

官网提供的平台支持如下(这里不介绍jetson相关内容,因为jetpack已经默认安装好deepstream)
在这里插入图片描述

在正式安装之前,先卸载掉之前安装过的残留,如果从来没装过,可以跳过这步

sudo rm -rf /usr/local/deepstream /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstnv* /usr/bin/deepstream* /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libnvdsgst* /usr/lib/x86_64-linux-gnu/gstreamer-1.0/deepstream* /opt/nvidia/deepstream/deepstream* /usr/lib/x86_64-linux-gnu/libv41/plugins/libcuvidv4l2_plugin.so

安装依赖

sudo apt install libssl1.0.0  libgstreamer1.0-0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-bad  gstreamer1.0-plugins-ugly gstreamer1.0-libav libgstrtspserver-1.0-0 libjansson4
sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio libgstrtspserver-1.0-dev gstreamer1.0-rtsp
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgstrtspserver-1.0-dev libx11-dev libgstrtspserver-1.0-dev gstreamer1.0-rtsp
#若使用ffmpeg源码编译,则不需要安装
sudo apt-get install ffmpeg
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgstrtspserver-1.0-dev libx11-dev libjson-glib-dev

6.2 安装python/anaconda

(docker内有python3.6+版本的可以暂时不用安装,直接安装tensorrt)

6.2.1 安装Anaconda

https://blog.csdn.net/zml194849/article/details/121849905

6.2.2 安装python

若不想安装anaconda,直接安装python:包括安装python和切换python版本https://blog.csdn.net/zml194849/article/details/121850369

6.3 安装tensorRT

https://blog.csdn.net/zml194849/article/details/121852648

安装 uff模块支持 tensorflow 模型转化
tensorflow 版本要与 cuda 版本对应
TensorFlow 安装:
https://blog.csdn.net/zml194849/article/details/121860412

7.docker opencv编译

amd64和arm 安装opencvhttps://blog.csdn.net/zml194849/article/details/121861389

7.1 opencv依赖库—ubuntu16.04

ps:建议使用ubuntu官方源,本人在配置中使用其他原出现错误

[1] - 官方必须依赖库

sudo apt-get update
sudo apt-get install cmake git
sudo apt-get install build-essential \
                     libgtk2.0-dev \
                     pkg-config \
                     libavcodec-dev \
                     libavformat-dev 

[2] - 官方建议依赖库

sudo apt-get install python-dev \
                     libtbb2 \
                     libtbb-dev \
                     libjpeg-dev \
                     libpng-dev \
                     libtiff-dev \
                     libjasper-dev \
                     libdc1394-22-dev

[3] - OPENGL 支持依赖库

sudo apt-get install freeglut3-dev \
                     mesa-common-dev \
                     libgtkglext1 \
                     libgtkglext1-dev

[4] - 视频解码支持依赖库

sudo apt-get install checkinstall \
                     yasm \
                     libgstreamer0.10-dev \
                     libgstreamer-plugins-base0.10-dev \
                     libv4l-dev \
                     libtbb-dev \
                     libqt4-dev \
                     libgtk2.0-dev \
                     libmp3lame-dev \
                     libtheora-dev \
                     libvorbis-dev \
                     libxvidcore-dev \
                     x264 \
                     v4l-utils

[5] - 其它可能依赖项

sudo apt-get install libgphoto2-dev libavresample-dev liblapacke-dev gtk+-3.0
sudo apt-get install libgtk-3-dev libeigen3-dev tesseract-ocr liblept5 leptonica-progs libleptonica-dev

ubuntu18.04

sudo apt-get update -y # Update the list of packages
sudo apt-get remove -y x264 libx264-dev # Remove the older version of libx264-dev and x264
sudo apt-get install -y build-essential checkinstall cmake pkg-config yasm
sudo apt-get install -y git gfortran
sudo add-apt-repository -y "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt-get install -y libjpeg8-dev libjasper-dev libpng12-dev
sudo apt-get install -y libtiff5-dev
sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get install -y libxine2-dev libv4l-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y qt5-default libgtk2.0-dev libtbb-dev
sudo apt-get install -y libatlas-base-dev
sudo apt-get install -y libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get install -y libvorbis-dev libxvidcore-dev
sudo apt-get install -y libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get install -y x264 v4l-utils
 
# Some Optional Dependencies
sudo apt-get install -y libprotobuf-dev protobuf-compiler
sudo apt-get install -y libgoogle-glog-dev libgflags-dev
sudo apt-get install -y libgphoto2-dev libeigen3-dev libhdf5-dev doxygen libavresample-dev

jetson nano配置opencv
第一步:
编写 install_opencv4.0.0_Nano.sh

#!/bin/bash
#
# Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#
 
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <Install Folder>"
    exit
fi
folder="$1"
user="nvidia"
passwd="nvidia"
 
echo "** Install requirement"
sudo apt-get update
sudo apt-get install -y build-essential cmake 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 libjasper-dev libdc1394-22-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2 v4l2ucp
sudo apt-get install -y curl
sudo apt-get remove -y x264 libx264-dev # Remove the older version of libx264-dev and x264
sudo apt-get install -y build-essential checkinstall cmake pkg-config yasm
sudo apt-get install -y git gfortran
sudo add-apt-repository -y "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt-get install -y libjpeg8-dev libjasper-dev libpng12-dev
sudo apt-get install -y libtiff5-dev
sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get install -y libxine2-dev libv4l-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y qt5-default libgtk2.0-dev libtbb-dev
sudo apt-get install -y libatlas-base-dev
sudo apt-get install -y libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get install -y libvorbis-dev libxvidcore-dev
sudo apt-get install -y libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get install -y x264 v4l-utils
 
# Some Optional Dependencies
sudo apt-get install -y libprotobuf-dev protobuf-compiler
sudo apt-get install -y libgoogle-glog-dev libgflags-dev
sudo apt-get install -y libgphoto2-dev libeigen3-dev libhdf5-dev doxygen

sudo apt-get update
 
echo "** Download opencv-4.0.0"
cd $folder
#curl -L https://github.com/opencv/opencv/archive/4.0.0.zip -o opencv-4.0.0.zip
#curl -L https://github.com/opencv/opencv_contrib/archive/4.0.0.zip -o opencv_contrib-4.0.0.zip
unzip opencv-4.2.0.zip 
unzip opencv_contrib-4.2.0.zip 
cd opencv-4.2.0/
 
echo "** Building..."
mkdir build
cd build/

sudo cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-4.2.0 \
-D CMAKE_BUILD_TYPE=Debug \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.2.0/modules \
-D BUILD_opencv_hdf=OFF \
-D BUILD_opencv_python3=ON \
-D WITH_CUDA=ON \
-D WITH_OPENGL=ON \
-D WITH_OPENMP=ON \
-D WITH_GTK=ON \
-D WITH_OPENCL=ON \
-D WITH_VTK=ON -D WITH_TBB=ON \
-D WITH_GSTREAMER=ON \
-D WITH_CUDNN=ON \
-D WITH_CUBLAS=ON \
-D WITH_GTK_2_X=ON \
-D BUILD_EXAMPLES=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D WITH_FFMPEG=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_NVCUVID=ON \
-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 \
-D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \
-D CUDA_ARCH_PTX=7.5 \
..

make -j4
sudo make install
#sudo apt-get install -y python-opencv python3-opencv
 
echo "** Install opencv-4.2.0 successfully"
echo "** Bye :)"

第二步,运行 install_opencv4.0.0_Nano.sh

./install_opencv4.0.0_Nano.sh [folder you want to install OpenCV]

在安装上述依赖包的过程中,可能会存在一些错误提示,这里我将自己遇到的问题列出,并给出解决方案;
错误1:

E: Unable to locate package libjasper-dev

执行:

sudo apt-get install software-properties-common
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt-get update
sudo apt-get install libjasper-dev

再次执行安装依赖包就行;
错误2:

E: Unable to locate package libgstreamer0.10-dev

执行:

sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

即可;
错误3:

解决“/bin/bash^M: bad interpreter: No such file or directory”

原因:在执行shell脚本时提示这样的错误主要是由于shell脚本文件是dos格式,即每一行结尾以\r\n来标识,而unix格式的文件行尾则以\n来标识
解决方法:
(1)使用linux命令dos2unix filename,直接把文件转换为unix格式;
(2)使用sed命令sed -i “s/\r//” filename 或者 sed -i “s/^M//” filename直接替换结尾符为unix格式;(亲测可用)
(3)vi filename打开文件,执行 : set ff=unix 设置文件为unix,然后执行:wq,保存成unix格式。
查看脚本文件是dos格式还是unix格式的几种办法。
(1)cat -A filename 从显示结果可以判断,dos格式的文件行尾为^M $,unix格式的文件行尾为 $;
(2)od -t x1 filename 如果看到输出内容中存在0d 0a的字符,那么文件是dos格式,如果只有0a,则是unix格式;
(3)vi filename打开文件,执行 : set ff,如果文件为dos格式在显示为fileformat=dos,如果是unxi则显示为fileformat=unix。

7.2 opencv+opencv_contrib安装配置

下载库失败问题解决方法1:
需要更改一些资源的下载路径:

1.	ippicv_2020_win_intel64_20191018_general.zip下载失败
	进入opencv4.3.0\3rdparty\ippicv目录
	将 ippicv.cmake 第47行的https://raw.githubusercontent.com

	修改为:https://raw.staticdn.net

2.	opencv_videoio_ffmpeg_64.dll、opencv_videoio_ffmpeg.dll下载失败
	进入opencv4.3.0\3rdparty\ffmpeg目录
	将 ffmpeg.cmake 第25行的https://raw.githubusercontent.com

	修改为:https://raw.staticdn.net

3	.boostdesc_bgm.i相关文件下载失败
	进入opencv_contrib-4.3.0\modules\xfeatures2d\cmake目录

	将 download_boostdesc.cmake中的https://raw.githubusercontent.com改为https://raw.staticdn.net

4.	vgg_generated_120.i相关文件下载失败
	进入opencv_contrib-4.3.0\modules\xfeatures2d\cmake目录

	将 download_vgg.cmake中的https://raw.githubusercontent.com改为https://raw.staticdn.net

5.	opencv_contrib-4.3.0\modules\face下没有cmake目录,直接去CMakeLists.txt里修改下载位置

[亲测可用] 下载库失败问题解决方法2:

1)下载opencv 以及对应版本的opencv_contrib https://github.com/opencv
2)opencv_contrib文件放入opencv文件内
3)手动ippicv下载

1, 下载 ippicv_2019_lnx_intel64_general_20180723.tgz
下载地址:https://github.com/opencv/opencv_3rdparty/tree/ippicv/master_20180723/ippicv
保存路径随意,我是放在默认的下载路径/home/lc/下载
2, 修改opencv里相关配置文件
打开终端,输入
gedit /home/lc/opencv_source/opencv/3rdparty/ippicv/ippicv.cmake #记得lc换成 自己的用户名
将47行的
"https://raw.githubusercontent.com/opencv/opencv_3rdparty/${IPPICV_COMMIT}/ippicv/"
改为步骤1中手动下载的文件的本地路径:
"file:///home/lc/下载/" #(仅供参考,根据自己的路径填写) 编辑完成保存退出。

3,cmake时,到了下载ippicv那一步时会自动从本地下载。

4)face_landmark_model.dat下载

安装opencv4.2.0+ contrib时卡在face_landmark_model.dat下载的地方,一直下载不下来。
解决办法:
a.手动下载 face_landmark_model.dat ,链接如下, 文件放置路径随意
https://raw.githubusercontent.com/opencv/opencv_3rdparty/8afa57abc8229d611c4937165d20e2a2d9fc5a12/face_landmark_model.dat
b. 修改相应的配置文件

$ gedit /home/usrname/tool/opencv-3.4.0/opencv_contrib-3.4.0/modules/face/CMakeLists.txt
#usrname 换成自己的用户名, <tool/opencv-3.4.0>换成自己opencv源码对应的文件夹

将CMakeLists.txt文件的第19行修改为本地路径,即将原来的网址修改为下载的文件保存的路径

"file:///home/usrname/install/"
#"https://raw.githubusercontent.com/opencv/opencv_3rdparty/${__commit_hash}/"
# usrname记得替换为自己的用户名,路径记得替换为自己文件对应的路径

我将下载下来的face_landmark_model.dat 放在 /home/usrname/install/ 下,所以把下载网址换为本地, 如上所示。
c. 重新编译即可。

5)boostdesc_bgm.i等下载

boostdesc_bgm.i
boostdesc_bgm_bi.i
boostdesc_bgm_hd.i
boostdesc_lbgm.i
boostdesc_binboost_064.i
boostdesc_binboost_128.i
boostdesc_binboost_256.i
vgg_generated_120.i
vgg_generated_64.i
vgg_generated_80.i
vgg_generated_48.i

拷贝到opencv_contrib/modules/xfeatures2d/src/目录下,而且网上直接可以用的资源并不多。所以本人在这篇文章里分享一下资源。
百度云链接:https://pan.baidu.com/s/1BeYF8kqEZLAJYQj-MvxpmA
提取码:e1wc
然后更改opencv_contrib/modules/xfeatures2d/cmake/里的下载路径即可

5)开始编译

首选 无python版本

cd opencv
mkdir build
cd build
sudo cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-4.2.0 \
-D CMAKE_BUILD_TYPE=Debug \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.2.0/modules \
-D BUILD_opencv_hdf=OFF \
-D BUILD_opencv_python3=ON \
-D WITH_CUDA=ON \
-D WITH_OPENGL=ON \
-D WITH_OPENMP=ON \
-D WITH_GTK=ON \
-D WITH_OPENCL=ON \
-D WITH_VTK=ON -D WITH_TBB=ON \
-D WITH_GSTREAMER=ON \
-D WITH_CUDNN=ON \
-D WITH_CUBLAS=ON \
-D WITH_GTK_2_X=ON \
-D BUILD_EXAMPLES=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D WITH_FFMPEG=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_NVCUVID=ON \
-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 \
-D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \
-D CUDA_ARCH_PTX=7.5 \
..
#有anacodna版本,会有问题
cd opencv
mkdir build
cd build
sudo cmake -D CMAKE_INSTALL_PREFIX=/usr/local/opencv-4.2.0 \
-D CMAKE_BUILD_TYPE=Debug \
-D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib-4.2.0/modules \
-D BUILD_opencv_python3=ON \
-D PYTHON_DEFAULT_EXECUTABLE=/root/anaconda3/lib/python3.7 \
-D BUILD_opencv_python2=OFF \
-D PYTHON3_EXCUTABLE=/root/anaconda3/lib/python3.7 \
-D PYTHON3_INCLUDE_DIR=/root/anaconda3/include/python3.7m \
-D PYTHON3_LIBRARY=/root/anaconda3/lib/libpython3.7m.so.1.0 \
-D PYTHON_NUMPY_PATH==/root/anaconda3/lib/python3.7/site-packages \
-D BUILD_opencv_hdf=OFF \
-D WITH_CUDA=ON \
-D WITH_OPENGL=ON \
-D WITH_OPENMP=ON \
-D WITH_GTK=ON \
-D WITH_VTK=ON -D WITH_TBB=ON \
-D WITH_GSTREAMER=ON \
-D WITH_CUDNN=ON \
-D WITH_CUBLAS=ON \
-D WITH_GTK_2_X=ON \
-D BUILD_EXAMPLES=ON \
-D OPENCV_ENABLE_NONFREE=ON \
-D WITH_FFMPEG=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D WITH_NVCUVID=ON \
-D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.2 \
-D CUDA_ARCH_BIN=5.3,6.0,6.1,7.0,7.5 \
-D CUDA_ARCH_PTX=7.5 \
..

ps:重要注意事项!!!!
1.cmake选项注意:

-D WITH_OPENGL=ON  #打开OPENGL,必须
-D WITH_GTK_2_X=ON #必须,否则OPENGL无法打开
-D BUILD_EXAMPLES=ON #用于后续验证GPU编解码
-D WITH_NVCUVID=ON  #用于安装ffmpeg显卡编解码相关库 必须

2.输出configure验证检测:
【1】查看cuda是否打开,重点是NVCUVID是否打开
在这里插入图片描述

docker中配置问题 无NVCUVID解决办法

需要将host(主机)中的libnvcuvid.solibnvcuvid.so.1 libnvcuvid.so.440.80.2(库的实体)放入到docker的/usr/lib/x86_64-linux-gnu/路径下,并在docker中创建软连接

ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.450.80.02 /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1
ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/x86_64-linux-gnu/libnvcuvid.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so /usr/lib/libnvcuvid.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libnvcuvid.so.1 /usr/lib/libnvcuvid.so.1

重新cmake

【2】查看ffmpeg是否打开
在这里插入图片描述

【3】查看OpenGL support是否打开
在这里插入图片描述

如果FFMPEG=NO,则建议使用cmake-gui进行cmake,具体步骤如下:
使用cmake-gui编译

# 安装cmake-gui
sudo apt-get install cmake-qt-gui
# 进入opencv源代码目录
cd opencv
# 创建一个build文件夹,用于存放生成的代码
mkdir build
cd build
# 启动cmake-gui
cmake-gui ..

在这里插入图片描述

step.1 点击 “Browse Source” ,选择源代码根路径opencv ,
step.2 点击 “Browse Build”,选择目标代码目录 build
step.3 点击 “Configure”,弹出CMakeSetup窗口,选择Unix Makefiles,选择Use default native compilers生成配置项
step.4 配置编译参数

Name	Value	备注
CMAKE_BUILD_TYPE	Release	
CMAKE_INSTALL_PREFIX	/usr/local/opencv4.2.0	安装目录
OPENCV_EXTRA_MODULES_PATH	opencv-4.2.0/opencv_contrib/modules	opencv_contrib目录
BUILD_DOCS	ON	构建文档
BUILD_EXAMPLES	ON	构建所有示例
INSTALL_PYTHON_EXAMPLES	ON	
INSTALL_C_EXAMPLES	ON	
OPENCV_GENERATE_PKGCONFIG	ON	务必勾选-后面就无需自己造opencv4.pc
WITH_OPENGL	ON	

其余选择项,参考上述cmake指令

step.5 再次点击"Configure",然后点击"Generate"
step.6 开始编译

cd到build目录下

sudo make -j12
sudo make install

可能错误解决
1.编译opencv_contrib库时出现如下错误:

fatal error: vgg_generated_120.i: No such file or directory

Solutions:
Step 1:在如下链接下载缺失文件
链接:https://pan.baidu.com/s/10-lqsBanBIJaX3j_iSP7qQ
提取码:qj8e
Step 2:将所有文件复制到如下目录里面

opencv_contrib/modules/xfeatures2d/src/

Step 3:重新make

make -j4

2.make中可能出现的错误

XXX.hpp 没有那个文件或者目录
fatal error: features2d/test/test_detectors_invariance.impl.hpp: No such file

一般是说在features2d/test目录下没有XXX.hpp什么的,处理方式是将opencv-4.1.2/modules/features2d/test该目录下对于的缺少文件复制到opencv_contrib-4.1.2/modules/xfeatures2d/test该目录下,然后修改报错的文件的#include,将前面的地址删除,就让其在本地找

例如 :
报错说在文件test_rotation_and_scale_invariance.cpp中找不到
#include “xxxx/test_detectors_invariance.impl.hpp”,
那么就在opencv-4.1.2/modules/features2d/test下去找test_detectors_invariance.impl.hpp文件,
将其复制到opencv_contrib-4.1.2/modules/xfeatures2d/test目录,
然后打开test_rotation_and_scale_invariance.cpp文件,
修改#include "xxxx/test_detectors_invariance.impl.hpp"为#include "test_detectors_invariance.impl.hpp"即可
如果觉得每个文件去找很麻烦,那么干脆将目录中的所有文件复制过去,之后就对于报错文件的#include位置就好了。

cp ../modules/features2d/test/test_detectors_regression.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ &&
cp ../modules/features2d/test/test_descriptors_regression.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ &&
cp ../modules/features2d/test/test_detectors_invariance.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ &&
cp ../modules/features2d/test/test_descriptors_invariance.impl.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/ &&
cp ../modules/features2d/test/test_invariance_utils.hpp ../opencv_contrib-4.2.0/modules/xfeatures2d/test/

3.anaconda编译错误
报错信息如下

libtbb.so.2: undefined reference to `__cxa_init_primary_exception@CXXABI_1.3

解决:
anaconda3/lib中的libtbb.so.2文件出现了一些无法解释的错误,到x86_64-linux-gnu下复制相同名字的文件进行替换编译成功。暂时不知道为什么,这个tbb文件是intel的一个多线程库,推测还是系统或者编译路径配置的问题

4.对于opencv2/xfeatures2d/cuda.hpp: No such file or directory 类问题的解决方法
遇到问题

/usr/local/arm/opencv-3.4.0/opencv_contrib-3.4.0/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp:42:10: 
fatal error: /opencv2/xfeatures2d.hpp: No such file or directory
 #include "/opencv2/xfeatures2d.hpp"
          ^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

根据给的路径找到xfeature2d.hpp的文件并打开,找到第42行如下:

40 #ifndef __OPENCV_XFEATURES2D_HPP__
41 #define __OPENCV_XFEATURES2D_HPP__
 
42 #include"/opencv2/xfeatures2d.hpp"

改为绝对路径

40 #ifndef __OPENCV_XFEATURES2D_HPP__
41 #define __OPENCV_XFEATURES2D_HPP__

42#include"/usr/local/arm/opencv3.4.0/opencv_contrib3.4.0/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp"

之后可能会遇到问题5,如下

5.遇到问题

undefined reference to `cv::cuda::SURF_CUDA::SURF_CUDA()'

解决方法
修改 <build_dir>/samples/gpu/CMakeFiles/example_gpu_surf_keypoint_matcher.dir/link.txt by 在
“<build_dir>/modules/xfeatures2d/CMakeFiles/opencv_xfeatures2d.dir/src/surf.cuda.cpp.o” 增加如下命令:

CMakeFiles/example_gpu_surf_keypoint_matcher.dir/surf_keypoint_matcher.cpp.o 
#增加命令
../../modules/xfeatures2d/CMakeFiles/opencv_xfeatures2d.dir/src/surf.cuda.cpp.o 
../../modules/xfeatures2d/CMakeFiles/cuda_compile_1.dir/src/cuda/cuda_compile_1_generated_surf.cu.o 
#
-o .....

重新make

6)opencv环境变量配置
环境配置添加opencv库路径

sudo gedit /etc/ld.so.conf.d/opencv.conf ##若没有则创建文件
//打开后可能是空文件,在文件内容最后添加
/usr/local/opencv-4.2.0/lib ##lib库路径,根据个人设置路径改变

更新系统库

sudo ldconfig

配置bash

sudo gedit /etc/bash.bashrc  
//在末尾添加
#根据opencv的lib设置的路径更改
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opencv-4.2.0/lib/pkgconfig 
export PKG_CONFIG_PATH

保存退出,然后执行如下命令使得配置生效

source /etc/bash.bashrc
//激活配置然后更新database
sudo updatedb 

配置本地bash
打开~/.bashrc

$ gedit ~/.bashrc

在文件末尾增加以下内容

export PKG_CONFIG_PATH=/usr/local/opencv-4.2.0/lib/pkgconfig
export LD_LIBRARY_PATH=/usr/local/opencv-4.2.0/lib

更新~/.bashrc

$ source ~/.bashrc 

查询OpenCV版本

pkg-config opencv4 --modversion 
# or
pkg-config --cflags --libs opencv4
#出现如下问题:
Package opencv was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv4.pc'
to the PKG_CONFIG_PATH environment variable
No package 'opencv4' found

原因:在configrue时,为指定 OPENCV_GENERATE_PKGCONFIG为NO(OFF为关闭),而安装后并未自动生成响应的opencv4.pc文件
当然,如果你勾选吧,那么,就没有下面4.3的问题啦

7.3 创建opencv4.pc

sudo gedit /usr/local/lib/pkgconfig/opencv4.pc

添加如下内容

# Package Information for pkg-config
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv4/opencv
includedir_new=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.2.0
Libs: -L${exec_prefix}/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_videostab -lopencv_video -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir_old} -I${includedir_new}

再次pkg-config测试

pkg-config --cflags --libs opencv4
-I/usr/local/include/opencv4/opencv -I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dnn_objdetect -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hfs -lopencv_img_hash -lopencv_line_descriptor -lopencv_quality -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_dnn -lopencv_plot -lopencv_videostab -lopencv_video -lopencv_xfeatures2d -lopencv_shape -lopencv_ml -lopencv_ximgproc -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core

测试成功!

pkg-config 命令介绍:用于获得某一个库/模块的所有编译相关的信息
所有用opencv的其他程序,在编译时,只需要写“pkg-config opencv –libs –cflags”,而不需要自己去找opencv的头文件在哪里,要链接的库在哪里!省时省力!
pkg-config介绍参考:https://www.cnblogs.com/sddai/p/10266624.html

sudo ldconfig 命令介绍: ldconfig是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享。
主要是在默认搜寻目录/lib和/usr/lib以及动态库配置文件/etc/ld.so.conf内所列的目录下,否则需要 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/<you_dir>/lib
搜索出可共享的动态链接库(格式如lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件,
缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。
linux下的共享库机制采用了类似高速缓存机制,将库信息保存在/etc/ld.so.cache,程序连接的时候首先从这个文件里查找,然后再到ld.so.conf的路径中查找。
为了让动态链接库为系统所共享,需运行动态链接库的管理命令ldconfig,此执行程序存放在/sbin目录下。
ldconfig介绍参考 https://blog.csdn.net/winycg/article/details/80572735

参考:https://blog.csdn.net/youlinhuanyan/article/details/104109599

8.OpenCV GPU视频编解码测试

opencv_cuda.cpp

#include <iostream>

#include "opencv2/opencv_modules.hpp"

#if defined(HAVE_OPENCV_CUDACODEC)

#include <string>
#include <vector>
#include <algorithm>
#include <numeric>

#include <opencv2/core.hpp>
#include <opencv2/core/opengl.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>

int main(int argc, const char* argv[])
{
    if (argc != 2)
        return -1;

    const std::string fname(argv[1]);
    
    //显示视频
    //cv::namedWindow("CPU", cv::WINDOW_NORMAL);
    cv::namedWindow("GPU", cv::WINDOW_OPENGL);
    cv::cuda::setGlDevice();

    //cv::Mat frame;
    //cv::VideoCapture reader(fname);

    cv::cuda::GpuMat d_frame;
    cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);

    cv::TickMeter tm;
    std::vector<double> cpu_times;
    std::vector<double> gpu_times;

    int gpu_frame_count=0, cpu_frame_count=0;

/*
    for (;;)
    {
        tm.reset(); tm.start();
        if (!reader.read(frame))
            break;
        tm.stop();
        cpu_times.push_back(tm.getTimeMilli());
        cpu_frame_count++;

        cv::imshow("CPU", frame);

        if (cv::waitKey(3) > 0)
            break;
    }
*/
    for (;;)
    {
        tm.reset(); tm.start();
        if (!d_reader->nextFrame(d_frame))
            break;
        tm.stop();
        gpu_times.push_back(tm.getTimeMilli());
        gpu_frame_count++;

        cv::imshow("GPU", d_frame);

        if (cv::waitKey(3) > 0)
            break;
    }

    if (!cpu_times.empty() || !gpu_times.empty())
    {
        std::cout << std::endl << "Results:" << std::endl;

        //std::sort(cpu_times.begin(), cpu_times.end());
        std::sort(gpu_times.begin(), gpu_times.end());

        //double cpu_avg = std::accumulate(cpu_times.begin(), cpu_times.end(), 0.0) / cpu_times.size();
        double gpu_avg = std::accumulate(gpu_times.begin(), gpu_times.end(), 0.0) / gpu_times.size();

        //std::cout << "CPU : Avg : " << cpu_avg << " ms FPS : " << 1000.0 / cpu_avg << " Frames " << cpu_frame_count << std::endl;
        std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << " Frames " << gpu_frame_count << std::endl;
    }

    return 0;
}

#else

int main()
{
    std::cout << "OpenCV was built without CUDA Video decoding support\n" << std::endl;
    return 0;
}

#endif

Makefile

opencv_cuda.o:opencv_cuda.cpp
	g++ -std=c++11 -g -o main.out opencv_cuda.cpp `pkg-config opencv4 --cflags --libs` \
    -I/usr/local/opencv-4.2.0/include/opencv4/opencv2 \
    -I/usr/local/cuda/include \
    -L/usr/local/cuda/lib64 \
    -I/usr/include/eigen3 \
    -L/usr/lib/x86_64-linux-gnu -lcuda -ldl -lnvcuvid
    
clean:
	rm *.o main.out 

编译并运行

make
./main.out test.h264
# or
./main.out rtsp://admin:hk888888@10.171.1.233/h265/ch1/main/av_stream

运行效果(4k视频、H265编码)

cpu利用率
在这里插入图片描述

GPU使用
在这里插入图片描述

9.deepstream5.0配置_环境打包_测试例

安装deepstream5.0

安装依赖

sudo apt install libssl1.0.0  libgstreamer1.0-0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-plugins-bad  gstreamer1.0-plugins-ugly gstreamer1.0-libav libgstrtspserver-1.0-0 libjansson4
sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio libgstrtspserver-1.0-dev gstreamer1.0-rtsp
sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgstrtspserver-1.0-dev libx11-dev libgstrtspserver-1.0-dev gstreamer1.0-rtsp
#若使用ffmpeg源码编译,则不需要安装
sudo apt-get install ffmpeg
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgst

下载SDK
在官网下载SDK压缩包并解压

sudo tar -jxvf deepstream_sdk_v5.0.0_x86_64.tbz2 -C /

如果之前安装过4.0版本的SDK,则先卸载掉

cd /opt/nvidia/deepstream/deepstream-5.0
sudo vim uninstall.sh 
//打开后,设置PREV_DS_VER=4.0
sudo ./uninstall.sh

安装依赖,同jetson安装部分

安装

$ cd /opt/nvidia/deepstream/deepstream-5.0/
$ sudo ./install.sh
$ sudo ldconfig

添加环境变量

sudo vim /etc/ld.so.conf
/opt/nvidia/deepstream/deepstream-5.0/lib/       //在文本后边添加该路径
sudo ldconfig    //执行ldconfig立即生效

至此deepstream5.0安装完成,输入deepstream-app --version-all 来查看安装的版本,得到输出如下

deepstream-app version 5.0.0
DeepStreamSDK 5.0.0
CUDA Driver Version: 10.2
CUDA Runtime Version: 10.2
TensorRT Version: 7.0
cuDNN Version: 7.6
libNVWarp360 Version: 2.0.1d3

可能问题1

GStreamer-WARNING **: 03:47:40.589: Failed to load plugin '/usr/lib/x86_64-linux-gnu/gstreamer-1.0/deepstream/libnvdsgst_inferserver.so': libtrtserver.so: cannot open shared object file: No such file or directory

解决方法

sudo apt install \
    libssl1.0.0 \
    libgstreamer1.0-0 \
    gstreamer1.0-tools \
    gstreamer1.0-plugins-good \
    gstreamer1.0-plugins-bad \
    gstreamer1.0-plugins-ugly \
    gstreamer1.0-libav \
    libgstrtspserver-1.0-0 \
    libjansson4=2.11-1

可能问题2

deepstream-app: error while loading shared libraries: libcudart.so.10.2: can

解决方法

sudo vim /etc/ld.so.conf
#增加路径
/usr/local/cuda-10.2/lib64
ldconfig
重新测试

可能问题3
如果是在服务器上运行,没有显示界面的话会报错如下

No EGL Display 
nvbufsurftransform: Could not get EGL display connection

需要修改环境变量,如下

vim ~/.bashrc
 
#打开后在最后边加下边语句
unset DISPLAY
export DISPLAY=:0 
#或者 export DISPLAY=:1
 
#保存退出
source ~/.bashrc
rm ${HOME}/.cache/gstreamer-1.0/registry.*
 
#然后再运行
deepstream-app -c source30_1080p_dec_infer-resnet_tiled_display_int8.tx

查看deepstearm安装情况

deepstream-app --version-all

在这里插入图片描述运行案例:

cd /opt/nvidia/deepstream/deepstream
#测试案例
deepstream-app -c samples/configs/deepstream-app/source8_1080p_dec_infer-resnet_tracker_tiled_display_fp16_nano.txt

如果如下错误:
在这里插入图片描述需要删除缓冲文件

sudo rm ~/.cache/gstreamer-1.0/*

正常运行输出为:
在这里插入图片描述安装librdkafka

$ git clone https://github.com/edenhill/librdkafka.git
$ cd librdkafka
$ git reset --hard 7101c2310341ab3f4675fc565f64f0967e135a6a
$ ./configure
$ make
$ sudo make install
$ sudo cp /usr/local/lib/librdkafka* /opt/nvidia/deepstream/deepstream-5.0/lib

保存刚刚修改的镜像,方便后面使用

docker commit  [容器ID/容器名]  [REPOSITORY:TAG]

镜像存储到本地
docker save : 将指定镜像保存成 tar 归档文件。
语法

docker save [OPTIONS] IMAGE [IMAGE...]

OPTIONS 说明:
-o :输出到的文件。
实例
将镜像 runoob/ubuntu:v3 生成 my_ubuntu_v3.tar 文档

runoob@runoob:~$ docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3
runoob@runoob:~$ ll my_ubuntu_v3.tar
-rw------- 1 runoob runoob 142102016 Jul 11 01:37 my_ubuntu_v3.ta

10.docker使用技巧

10.1在docker中配置自己的环境

1 单个文件宿主机与docker容器文件互传

#宿主机到容器
docker cp 本地文件路径 ID全称:容器路径
#容器到宿主机
docker cp ID全称:容器文件路径 本地路径

2 如何ssh远程连接上docker
文档:docker ssh连接
链接:http://note.youdao.com/noteshare?id=4b68e5b9d65802c2feb5619c32a85a09&sub=wcp1600847257843142

10.2提交和打包docker

10.3重新启动容器

通过 docker ps -a 命令查看已经在运行的容器,然后使用容器 ID 进入容器。
查看已经在运行的容器 ID:

# docker ps -a 
...
9df70f9a0714        openjdk             "/usercode/script.sh…" 
...

第一列的 9df70f9a0714 就是容器 ID。
通过 exec 命令对指定的容器执行 bash:

# docker exec -it 9df70f9a0714 /bin/bash

若报错:

docker 报错 Container is not running

出现这个问题,是因为Container容器之前已经启动过了
需要执行docker start 56b90db5253e就可以解决了。
然后重新执行即可

# docker exec -it 9df70f9a0714 /bin/bash

10.4载入自己的docker

如果已经有docker,则启动docker

docker load -i fsym_ubuntu.tar
docker images
sudo docker run -t -i fsym_ubuntu:1 /bin/bash

10.5.迁移Docker到其它磁盘

# 停止docker服务
systemctl stop dcoker

# 迁移docker目录到数据盘vdb2
mv /var/lib/docker/* /mnt/vdb2/docker/

# 挂载docker目录至原目录
mount --bind /mnt/vdb2/docker /var/lib/docker

# 添加挂载命令至开机脚本
vi /etc/rc.local

# 在文件最后一行添加以下挂载命令
mount --bind /mnt/vdb2/docker /var/lib/docker

# 保存退出
systemctl restart dcoker

10.6 问题解决汇总

10.6.1 docker建立镜像时出现如下错误
W: GPG error: https://developer.download.nvidia.cn/compute/cuda/repos/ubuntu1804/x86_64  Release: The following signatures were invalid: BADSIG F60F4B3D7FA2AF80 cudatools<cudatools@nvidia.com>
E: The repository'https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64  Release' is not signed.                                                       

解决办法1

gpg --keyserver keyserver.ubuntu.com --recv-keys F60F4B3D7FA2AF80

转自https://github.com/NVIDIA/nvidia-docker/issues/969

解决办法2
(我就是用了这个才解决了,前两个有人有用,对我没用,万分感谢下面这位大哥)
在这里插入图片描述

1.安装apt-transport-https
2.list里面的http改为https
3.执行下面这个

wget -qO - https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub | sudo apt-key add -

搞定!

10.7 如何使用dockerfile创建镜像

dockerfile参考:https://blog.csdn.net/sunt2018/article/details/107483599

FROM nvidia/cuda:10.2-cudnn7-devel-centos7

MAINTAINER tenten  "vtenten@163.com"

WORKDIR /work

RUN mkdir ffmpeg_source

# 更换yum源
COPY ./docker_env/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
RUN yum makecache && yum install -y  autoconf automake bzip2 cmake freetype-devel gcc gcc-c++ git libtool make mercurial pkgconfig zlib-devel zip unzip

# 编译 nasm-2.13.02
ADD ./ffmpeg_souRUN cd ffmpeg_source/nasm-2.13.02 && ./autogen.sh && ./configure --prefix="/root/ffmpeg_build" --bindir="/root/bin" && make && make install

# 设置bin目录 lib
ENV PATH="/root/bin:${PATH}"
ENV LD_LIBRARY_PATH="/root/ffmpeg_build/lib"
ENV PKG_CONFIG_PATH="/root/ffmpeg_build/lib/pkgconfig"

# 编译 yasm-1.3.0
ADD ./ffmpeg_source/yasm-1.3.0.tar.gz  ./ffmpeg_source/
RUN cd ffmpeg_source/yasm-1.3.0 && ./configure --prefix="/root/ffmpeg_build" --bindir="/root/bin" && make && make install

# 编译 x264
ADD ./ffmpeg_source/x264.tar.gz  ./ffmpeg_source/rce/nasm-2.13.02.tar.bz2 ./ffmpeg_source/
RUN cd ffmpeg_source/x264  && ./configure --prefix="/root/ffmpeg_build" --bindir="/root/bin" --enable-static && make && make install

# 编译 libfdk_acc
ADD ./ffmpeg_source/fdk-aac.tar.gz  ./ffmpeg_source/
RUN cd ffmpeg_source/fdk-aac && autoreconf -fiv && ./configure --prefix="/root/ffmpeg_build" --disable-sharedi && make && make install

# 编译 libmp3lame
ADD ./ffmpeg_source/lame-3.100.tar.gz  ./ffmpeg_source/
RUN cd ffmpeg_source/lame-3.100 && ./configure --prefix="/root/ffmpeg_build" --bindir="/root/bin" --disable-shared --enable-nasm && make && make install

# 编译 nv-codec-headers
ADD ./ffmpeg_source/nv-codec-headers.tar.gz  ./ffmpeg_source/
RUN cd ffmpeg_source/nv-codec-headers && make PREFIX="/root/ffmpeg_build" BINDDIR="/root/bin" && make install PREFIX="/root/ffmpeg_build" BINDDIR="/root/bin"

# 编译 ffmpeg
ADD ./ffmpeg_source/ffmpeg-3.3.8.tar.bz2  ./ffmpeg_source/
RUN cd ffmpeg_source/ffmpeg-3.3.8 && ./configure --prefix="/root/ffmpeg_build" --pkg-config-flags="--static"  \
    --extra-cflags="-I/root/ffmpeg_build/include -I/usr/local/cuda/include" \
    --extra-ldflags="-L/root/ffmpeg_build/lib -L/usr/local/cuda/lib64"  \
    --extra-libs=-lpthread  --extra-libs=-lm  --bindir="/root/bin" \
    --enable-gpl  --enable-libfdk_aac  --enable-libmp3lame  --enable-libx264  --enable-nonfree \
    --enable-cuda \
    --enable-cuvid \
    --enable-nvenc \
    --enable-libnpp \
    && make && make install && hash -r

10.8 docker显示GUI界面

解决方案2—已经启动的容器修改系统参数
参考文章https://blog.csdn.net/wzw_mzm/article/details/70916202
有的时候,我们在已经启动的容器里做了一些事情,有了显示图像的需要,但从头新启动一个容器有点麻烦。
这时候可以用上面博客里讲的方法实现图形界面显示,也还算方便。
思路上也是把主机和docker看做服务器和客户端的关系,通过IP地址来映射显示。
1 具体操作
1)使用 ifconfig 查看主机和docker的IP地址
例如:主机的IP为 xxx
docker 的IP为YYY
2)docker 中

export DISPLAY= XXX       #把环境变量映射到主机IP

3.)主机中

sudo gedit /etc/lightdm/lightdm.conf      #增加一行    xserver-allow-tcp=true

sudo systemctl restart lightdm               

xhost  +                #注意加号前应有空格

这样配置就完成了,这是第一次配置的操作.
以后每次重新开机时,还是要在主机里运行一下 xhost +,在docker里运行一下export DISPLAY= XXX 。
其实还是挺麻烦的。
最关键的是,这种方式用的是IP地址,在系统没联网时,网卡就没有分配的IP地址了,这种方法就行不通了。

10.9 怎样测试能否显示图像界面

第二篇参考文章中用了一个显示时钟的小程序xclock
不过我在Ubuntu16.04的环境里搜不到这个了,能安装的叫xarclock,功能一样
在docker中运行

sudo apt-get install xarclock       #安装这个小程序
xarclock                            #运行,如果配置成功,会显示出一个小钟表动画

参考:https://blog.csdn.net/ericcchen/article/details/79253416

10.11.docker 拉取镜像加速

docker默认镜像拉取地址为国外仓库下载速度较慢,甚至会报Error response from daemon: Get https://docker.elastic.co/v2/: net/http: TLS handshake timeout这种错。
解决方法修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值。然后重启docker就可以了

{
  "registry-mirrors": ["https://hub-mirror.c.163.com","https://registry.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn"]
}

修改后重启docker服务

service docker restart

10.12 nvbuf_utils: Could not get EGL display connection

No EGL Display 
nvbuf_utils: Could not get EGL display connection

需要修改环境变量,如下

vim ~/.bashrc

#打开后在最后边加下边语句或者也可直接输入命令

unset DISPLAY
export DISPLAY=:0 
#或者 export DISPLAY=:1
 
#保存退出
source ~/.bashrc
rm ${HOME}/.cache/gstreamer-1.0/registry.*
 
#然后再运行
deepstream-app -c source30_1080p_dec_infer-resnet_tiled_display_int8.txt

11.deepstream源码学习

应用程序整体PipeLine结构图
在这里插入图片描述

deepstream-test2程序注释
一、首先是运行这个程序:
拷贝sample_720p.h264到deepstream-test2

cd deepstream-test2/
make
./deepstream-test2-app sample_720p.h264

deepstream-test2相对deepstream-test1多了目标跟踪和分类。所以运行速度较慢。五个模型对视频的处理(目标跟踪模型以库的形式提供)。如下图:
在这里插入图片描述
二、理解代码需要Gstreamer的知识,还需要C语言的基础
代码如下:

#include 
#include 

#include 
#include 
#include 

#include "gstnvdsmeta.h"

#define PGIE_CONFIG_FILE  "dstest2_pgie_config.txt"
#define SGIE1_CONFIG_FILE "dstest2_sgie1_config.txt"
#define SGIE2_CONFIG_FILE "dstest2_sgie2_config.txt"
#define SGIE3_CONFIG_FILE "dstest2_sgie3_config.txt"
#define MAX_DISPLAY_LEN 64

#define TRACKER_CONFIG_FILE "dstest2_tracker_config.txt"
#define MAX_TRACKING_ID_LEN 16

#define PGIE_CLASS_ID_VEHICLE 0
#define PGIE_CLASS_ID_PERSON 2

/* The muxer output resolution must be set if the input streams will be of
 * different resolution. The muxer will scale all the input frames to this
 * resolution. */
#define MUXER_OUTPUT_WIDTH 1920
#define MUXER_OUTPUT_HEIGHT 1080

/* Muxer batch formation timeout, for e.g. 40 millisec. Should ideally be set
 * based on the fastest source's framerate. */
#define MUXER_BATCH_TIMEOUT_USEC 4000000

gint frame_number = 0;
/* These are the strings of the labels for the respective models */
gchar sgie1_classes_str[12][32] = { "black", "blue", "brown", "gold", "green",
  "grey", "maroon", "orange", "red", "silver", "white", "yellow"
};

gchar sgie2_classes_str[20][32] =
    { "Acura", "Audi", "BMW", "Chevrolet", "Chrysler",
  "Dodge", "Ford", "GMC", "Honda", "Hyundai", "Infiniti", "Jeep", "Kia",
      "Lexus", "Mazda", "Mercedes", "Nissan",
  "Subaru", "Toyota", "Volkswagen"
};

gchar sgie3_classes_str[6][32] = { "coupe", "largevehicle", "sedan", "suv",
  "truck", "van"
};

gchar pgie_classes_str[4][32] =
    { "Vehicle", "TwoWheeler", "Person", "RoadSign" };

/* gie_unique_id is one of the properties in the above dstest2_sgiex_config.txt
 * files. These should be unique and known when we want to parse the Metadata
 * respective to the sgie labels. Ideally these should be read from the config
 * files but for brevity we ensure they are same. */

guint sgie1_unique_id = 2;
guint sgie2_unique_id = 3;
guint sgie3_unique_id = 4;

/* This is the buffer probe function that we have registered on the sink pad
 * of the OSD element. All the infer elements in the pipeline shall attach
 * their metadata to the GstBuffer, here we will iterate & process the metadata
 * forex: class ids to strings, counting of class_id objects etc. */
 
 //这是我们在OSD元素的sink pad上注册的缓冲区探测函数。
 //管道中的所有推理单元都应将其元数据附加到GstBuffer,
 //在这里,我们将迭代并处理元数据,显示和统计物体个数等。
static GstPadProbeReturn
osd_sink_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer u_data)
{
    GstBuffer *buf = (GstBuffer *) info->data;
    guint num_rects = 0;
    NvDsObjectMeta *obj_meta = NULL;
    guint vehicle_count = 0;
    guint person_count = 0;
    NvDsMetaList * l_frame = NULL;
    NvDsMetaList * l_obj = NULL;
    NvDsDisplayMeta *display_meta = NULL;

    NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);

    for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
      l_frame = l_frame->next) {
        NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
        int offset = 0;
        for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;
                l_obj = l_obj->next) {
            obj_meta = (NvDsObjectMeta *) (l_obj->data);
            if (obj_meta->class_id == PGIE_CLASS_ID_VEHICLE) {
                vehicle_count++;
                num_rects++;//统计汽车个数
            }
            if (obj_meta->class_id == PGIE_CLASS_ID_PERSON) {
                person_count++;
                num_rects++;//统计人的个数
            }
        }
        display_meta = nvds_acquire_display_meta_from_pool(batch_meta);//要显示的文字类数据
        NvOSD_TextParams *txt_params  = &display_meta->text_params[0];
        display_meta->num_labels = 1;
        txt_params->display_text = g_malloc0 (MAX_DISPLAY_LEN);
        offset = snprintf(txt_params->display_text, MAX_DISPLAY_LEN, "Person = %d ", person_count);
        offset = snprintf(txt_params->display_text + offset , MAX_DISPLAY_LEN, "Vehicle = %d ", vehicle_count);

        /* Now set the offsets where the string should appear */
        txt_params->x_offset = 10;
        txt_params->y_offset = 12;

        /* Font , font-color and font-size *///字体相关的设置
        txt_params->font_params.font_name = "Serif";
        txt_params->font_params.font_size = 10;
        txt_params->font_params.font_color.red = 1.0;
        txt_params->font_params.font_color.green = 1.0;
        txt_params->font_params.font_color.blue = 1.0;
        txt_params->font_params.font_color.alpha = 1.0;

        /* Text background color */
        txt_params->set_bg_clr = 1;//背景颜色的设置
        txt_params->text_bg_clr.red = 0.0;
        txt_params->text_bg_clr.green = 0.0;
        txt_params->text_bg_clr.blue = 0.0;
        txt_params->text_bg_clr.alpha = 1.0;

        nvds_add_display_meta_to_frame(frame_meta, display_meta);//显示帧数据、图像数据、文字等
    }

    g_print ("Frame Number = %d Number of objects = %d "
            "Vehicle Count = %d Person Count = %d\n",
            frame_number, num_rects, vehicle_count, person_count);
    frame_number++;
    return GST_PAD_PROBE_OK;
}

static gboolean//针对不同的消息类型进行相应的处理
bus_call (GstBus * bus, GstMessage * msg, gpointer data)
{
  GMainLoop *loop = (GMainLoop *) data;
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_EOS://文件流结束的处理
      g_print ("End of stream\n");
      g_main_loop_quit (loop);
      break;
    case GST_MESSAGE_ERROR:{//错误的处理
      gchar *debug;
      GError *error;
      gst_message_parse_error (msg, &error, &debug);
      g_printerr ("ERROR from element %s: %s\n",
          GST_OBJECT_NAME (msg->src), error->message);
      if (debug)
        g_printerr ("Error details: %s\n", debug);
      g_free (debug);
      g_error_free (error);
      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }
  return TRUE;
}

/* Tracker config parsing */

#define CHECK_ERROR(error) \
    if (error) { \
        g_printerr ("Error while parsing config file: %s\n", error->message); \
        goto done; \
    }

#define CONFIG_GROUP_TRACKER "tracker"
#define CONFIG_GROUP_TRACKER_WIDTH "tracker-width"
#define CONFIG_GROUP_TRACKER_HEIGHT "tracker-height"
#define CONFIG_GROUP_TRACKER_LL_CONFIG_FILE "ll-config-file"
#define CONFIG_GROUP_TRACKER_LL_LIB_FILE "ll-lib-file"
#define CONFIG_GROUP_TRACKER_ENABLE_BATCH_PROCESS "enable-batch-process"
#define CONFIG_GPU_ID "gpu-id"

static gchar *
get_absolute_file_path (gchar *cfg_file_path, gchar *file_path)
{
  gchar abs_cfg_path[PATH_MAX + 1];
  gchar *abs_file_path;
  gchar *delim;

  if (file_path && file_path[0] == '/') {
    return file_path;
  }

  if (!realpath (cfg_file_path, abs_cfg_path)) {
    g_free (file_path);
    return NULL;
  }

  // Return absolute path of config file if file_path is NULL.
  if (!file_path) {
    abs_file_path = g_strdup (abs_cfg_path);
    return abs_file_path;
  }

  delim = g_strrstr (abs_cfg_path, "/");
  *(delim + 1) = '\0';

  abs_file_path = g_strconcat (abs_cfg_path, file_path, NULL);
  g_free (file_path);

  return abs_file_path;
}

static gboolean
set_tracker_properties (GstElement *nvtracker)
{
  gboolean ret = FALSE;
  GError *error = NULL;
  gchar **keys = NULL;
  gchar **key = NULL;
  GKeyFile *key_file = g_key_file_new ();

  if (!g_key_file_load_from_file (key_file, TRACKER_CONFIG_FILE, G_KEY_FILE_NONE,
          &error)) {
    g_printerr ("Failed to load config file: %s\n", error->message);
    return FALSE;
  }//导入配置文件

  keys = g_key_file_get_keys (key_file, CONFIG_GROUP_TRACKER, NULL, &error);
  //返回tracker的keys
  //tracker-width
  //tracker-height
  //gpu-id
  //ll-lib-file
  //ll-config-file
  //enable-batch-process
  CHECK_ERROR (error);
  //对nvtracker进行相应的设置
  for (key = keys; *key; key++) {
    if (!g_strcmp0 (*key, CONFIG_GROUP_TRACKER_WIDTH)) {
      gint width =
          g_key_file_get_integer (key_file, CONFIG_GROUP_TRACKER,
          CONFIG_GROUP_TRACKER_WIDTH, &error);
      CHECK_ERROR (error);
      g_object_set (G_OBJECT (nvtracker), "tracker-width", width, NULL);
    } else if (!g_strcmp0 (*key, CONFIG_GROUP_TRACKER_HEIGHT)) {
      gint height =
          g_key_file_get_integer (key_file, CONFIG_GROUP_TRACKER,
          CONFIG_GROUP_TRACKER_HEIGHT, &error);
      CHECK_ERROR (error);
      g_object_set (G_OBJECT (nvtracker), "tracker-height", height, NULL);
    } else if (!g_strcmp0 (*key, CONFIG_GPU_ID)) {
      guint gpu_id =
          g_key_file_get_integer (key_file, CONFIG_GROUP_TRACKER,
          CONFIG_GPU_ID, &error);
      CHECK_ERROR (error);
      g_object_set (G_OBJECT (nvtracker), "gpu_id", gpu_id, NULL);
    } else if (!g_strcmp0 (*key, CONFIG_GROUP_TRACKER_LL_CONFIG_FILE)) {
      char* ll_config_file = get_absolute_file_path (TRACKER_CONFIG_FILE,
                g_key_file_get_string (key_file,
                    CONFIG_GROUP_TRACKER,
                    CONFIG_GROUP_TRACKER_LL_CONFIG_FILE, &error));
      CHECK_ERROR (error);
      g_object_set (G_OBJECT (nvtracker), "ll-config-file", ll_config_file, NULL);
    } else if (!g_strcmp0 (*key, CONFIG_GROUP_TRACKER_LL_LIB_FILE)) {
      char* ll_lib_file = get_absolute_file_path (TRACKER_CONFIG_FILE,
                g_key_file_get_string (key_file,
                    CONFIG_GROUP_TRACKER,
                    CONFIG_GROUP_TRACKER_LL_LIB_FILE, &error));
      CHECK_ERROR (error);
      g_object_set (G_OBJECT (nvtracker), "ll-lib-file", ll_lib_file, NULL);
    } else if (!g_strcmp0 (*key, CONFIG_GROUP_TRACKER_ENABLE_BATCH_PROCESS)) {
      gboolean enable_batch_process =
          g_key_file_get_integer (key_file, CONFIG_GROUP_TRACKER,
          CONFIG_GROUP_TRACKER_ENABLE_BATCH_PROCESS, &error);
      CHECK_ERROR (error);
      g_object_set (G_OBJECT (nvtracker), "enable_batch_process",
                    enable_batch_process, NULL);
    } else {
      g_printerr ("Unknown key '%s' for group [%s]", *key,
          CONFIG_GROUP_TRACKER);
    }
  }

  ret = TRUE;
done:
  if (error) {
    g_error_free (error);
  }
  if (keys) {
    g_strfreev (keys);
  }
  if (!ret) {
    g_printerr ("%s failed", __func__);
  }
  return ret;
}

int
main (int argc, char *argv[])
{
  GMainLoop *loop = NULL;
  GstElement *pipeline = NULL, *source = NULL, *h264parser = NULL,
      *decoder = NULL, *streammux = NULL, *sink = NULL, *pgie = NULL, *nvvidconv = NULL,
      *nvosd = NULL, *sgie1 = NULL, *sgie2 = NULL, *sgie3 = NULL, *nvtracker = NULL;
  g_print ("With tracker\n");
#ifdef PLATFORM_TEGRA
  GstElement *transform = NULL;
#endif
  GstBus *bus = NULL;
  guint bus_watch_id = 0;
  GstPad *osd_sink_pad = NULL;

  /* Check input arguments */
  if (argc != 2) {
    g_printerr ("Usage: %s \n", argv[0]);
    return -1;
  }

  /* Standard GStreamer initialization */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */

  /* Create Pipeline element that will be a container of other elements */
  pipeline = gst_pipeline_new ("dstest2-pipeline");
  //通过gst_pipeline_new创建pipeline,参数为pipeline的名字。
  /* Source element for reading from the file */
  source = gst_element_factory_make ("filesrc", "file-source");
  //创建一个element  类型是filesrc,名字是file-source。
  //该element用于读取文件
  /* Since the data format in the input file is elementary h264 stream,
   * we need a h264parser */
  h264parser = gst_element_factory_make ("h264parse", "h264-parser");
  //创建一个element  类型是h264parse,名字是h264-parser。
  //该element用于解析h264文件
  /* Use nvdec_h264 for hardware accelerated decode on GPU */
  decoder = gst_element_factory_make ("nvv4l2decoder", "nvv4l2-decoder");
  //该element用于调用GPU硬件加速解码h264文件

  /* Create nvstreammux instance to form batches from one or more sources. */
  streammux = gst_element_factory_make ("nvstreammux", "stream-muxer");
 //该element用于把输入按照参数处理成一系列的视频帧
  if (!pipeline || !streammux) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  /* Use nvinfer to run inferencing on decoder's output,
   * behaviour of inferencing is set through config file */
  pgie = gst_element_factory_make ("nvinfer", "primary-nvinference-engine");
  //目标检测的模型,对输入图像进行推理,通过推理的配置文件
  /* We need to have a tracker to track the identified objects */
  nvtracker = gst_element_factory_make ("nvtracker", "tracker");
  //跟踪器  跟踪识别出来的目标
  /* We need three secondary gies so lets create 3 more instances of
     nvinfer */
  sgie1 = gst_element_factory_make ("nvinfer", "secondary1-nvinference-engine");
  //分类器--车的颜色
  sgie2 = gst_element_factory_make ("nvinfer", "secondary2-nvinference-engine");
  //分类器--车的厂家
  sgie3 = gst_element_factory_make ("nvinfer", "secondary3-nvinference-engine");
  //分类器--车的类型
  /* Use convertor to convert from NV12 to RGBA as required by nvosd */
  nvvidconv = gst_element_factory_make ("nvvideoconvert", "nvvideo-converter");
    //视频颜色格式转换

  /* Create OSD to draw on the converted RGBA buffer */
  nvosd = gst_element_factory_make ("nvdsosd", "nv-onscreendisplay");
  //处理RGBA buffer 绘制ROI,绘制识别对象的Bounding Box,绘制识别对象的文字标签(字体、颜色、标示框)
  
  /* Finally render the osd output */
#ifdef PLATFORM_TEGRA
  transform = gst_element_factory_make ("nvegltransform", "nvegl-transform");
    // 转换成 EGLImage instance 给nveglglessink使用

#endif
  sink = gst_element_factory_make ("nveglglessink", "nvvideo-renderer");

  if (!source || !h264parser || !decoder || !pgie ||
      !nvtracker || !sgie1 || !sgie2 || !sgie3 || !nvvidconv || !nvosd || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

#ifdef PLATFORM_TEGRA
  if(!transform) {
    g_printerr ("One tegra element could not be created. Exiting.\n");
    return -1;
  }
#endif

  /* Set the input filename to the source element */
  g_object_set (G_OBJECT (source), "location", argv[1], NULL);
   //设置source的位置,source是视频文件

  g_object_set (G_OBJECT (streammux), "width", MUXER_OUTPUT_WIDTH, "height",
      MUXER_OUTPUT_HEIGHT, "batch-size", 1,
      "batched-push-timeout", MUXER_BATCH_TIMEOUT_USEC, NULL);
   //设置视频格式,如分辨率等

  /* Set all the necessary properties of the nvinfer element,
   * the necessary ones are : */
  g_object_set (G_OBJECT (pgie), "config-file-path", PGIE_CONFIG_FILE, NULL);//目标检测的配置文件
  g_object_set (G_OBJECT (sgie1), "config-file-path", SGIE1_CONFIG_FILE, NULL);//颜色分类的配置文件
  g_object_set (G_OBJECT (sgie2), "config-file-path", SGIE2_CONFIG_FILE, NULL);//车厂分类的配置文件
  g_object_set (G_OBJECT (sgie3), "config-file-path", SGIE3_CONFIG_FILE, NULL);//车型分类的配置文件

  /* Set necessary properties of the tracker element. */
  //设置目标跟踪器
  if (!set_tracker_properties(nvtracker)) {
    g_printerr ("Failed to set tracker properties. Exiting.\n");
    return -1;
  }

  /* we add a message handler */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);//指定消息处理函数
  gst_object_unref (bus);

  /* Set up the pipeline */
  /* we add all elements into the pipeline */
  /* decoder | pgie1 | nvtracker | sgie1 | sgie2 | sgie3 | etc.. */
#ifdef PLATFORM_TEGRA
  gst_bin_add_many (GST_BIN (pipeline),
      source, h264parser, decoder, streammux, pgie, nvtracker, sgie1, sgie2, sgie3,
      nvvidconv, nvosd, transform, sink, NULL);//element加入到pipeline
#else
  gst_bin_add_many (GST_BIN (pipeline),
      source, h264parser, decoder, streammux, pgie, nvtracker, sgie1, sgie2, sgie3,
      nvvidconv, nvosd, sink, NULL);
#endif

  GstPad *sinkpad, *srcpad;
  gchar pad_name_sink[16] = "sink_0";
  gchar pad_name_src[16] = "src";

  sinkpad = gst_element_get_request_pad (streammux, pad_name_sink);
  if (!sinkpad) {
    g_printerr ("Streammux request sink pad failed. Exiting.\n");
    return -1;
  }//获取指定element中的指定pad  该element为 streammux

  srcpad = gst_element_get_static_pad (decoder, pad_name_src);
  if (!srcpad) {
    g_printerr ("Decoder request src pad failed. Exiting.\n");
    return -1;
  }

  if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) {
      g_printerr ("Failed to link decoder to stream muxer. Exiting.\n");
      return -1;
  }

  gst_object_unref (sinkpad);
  gst_object_unref (srcpad);

  /* Link the elements together */
  if (!gst_element_link_many (source, h264parser, decoder, NULL)) {
    g_printerr ("Elements could not be linked: 1. Exiting.\n");
    return -1;
  }

#ifdef PLATFORM_TEGRA
  if (!gst_element_link_many (streammux, pgie, nvtracker, sgie1,
      sgie2, sgie3, nvvidconv, nvosd, transform, sink, NULL)) {
    g_printerr ("Elements could not be linked. Exiting.\n");
    return -1;
  }
#else
  if (!gst_element_link_many (streammux, pgie, nvtracker, sgie1,
      sgie2, sgie3, nvvidconv, nvosd, sink, NULL)) {
    g_printerr ("Elements could not be linked. Exiting.\n");
    return -1;
  }
#endif

  /* Lets add probe to get informed of the meta data generated, we add probe to
   * the sink pad of the osd element, since by that time, the buffer would have
   * had got all the metadata. */
  osd_sink_pad = gst_element_get_static_pad (nvosd, "sink");
  
  if (!osd_sink_pad)
    g_print ("Unable to get sink pad\n");
  else
    gst_pad_add_probe (osd_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
        osd_sink_pad_buffer_probe, NULL, NULL);
//osd_sink_pad_buffer_probe 创建探针 
//以上都是设置属性,连接Elements,设置消息等操作,先把整个的视频处理流程勾勒出来。



  /* Set the pipeline to "playing" state */
  g_print ("Now playing: %s\n", argv[1]);
  gst_element_set_state (pipeline, GST_STATE_PLAYING);//运行

  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);//bus_call 消息处理函数可以结束loop

  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping playback\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);//释放为pipeline分配的所有资源
  g_print ("Deleting pipeline\n");
  gst_object_unref (GST_OBJECT (pipeline));
  g_source_remove (bus_watch_id);
  g_main_loop_unref (loop);//销毁loop对象
  return 0;
}

参考:文档:DeepStream之deepstream_test1_app解析…
链接:http://note.youdao.com/noteshare?id=0d899e08d337ea8ebf8d462cb7071f9e&sub=wcp1606817821530347

12.Gstreamer学习

在这里插入图片描述

1.为什么使用Gstreamer
硬解码就是利用硬件芯片来解码的,TX2有单独的解码模块,NVDEC。软解码是用软件程序来解码,比较占用CPU资源。截止当前,nvidia的硬件编码官方提供了nvenc的方法,且在ffmpeg中已经增加了对nvenc的编码库。对于硬件解码,官方提供了基于cuda的解码方法,但是ffmpeg中还没有相应的解码库。

查看cpu gpu 以及编解码模块的使用:

sudo jtop

首先,要先讨论下为什么需要在OpenCV上用上Gstreamer, 比如我直接一个摄像头 v4l2 图像传给 OpenCV 不行吗?

Gstreamer是嵌入式平台处理Media的首选组件, 像Nvdia/TI/NXP/Rockchip平台, 都是使用Gstreamer来整合Media应用. 在Rockchip平台上, 我们已经有为Gstreamer开发了像Decode/Encode/ISP-Camera/2D加速器/DRM-Display-sink这些的Plugin。所以OpenCV如果链接上Gstreamer,输入源就不仅仅是摄像头, 还可以是RTSP/本地视频;输出显示的代码可以不用写, 让Gstreamer来显示; 转换格式让Gstreamer来转, 利用硬件加速; 处理的图像送回Gstreamer编码。
参考:
https://www.cnblogs.com/xleng/p/11791944.html
https://blog.csdn.net/han2529386161/article/details/102896875
https://www.cnblogs.com/xleng/p/10948838.html

13. jetson nano开发配置

Jetson Nano从零开始(1):介绍
摘要https://blog.csdn.net/qqqzmy/article/details/96729609#_1
介绍https://blog.csdn.net/qqqzmy/article/details/96729609#_12
摘要
最近开始玩Jetson Nano,写下这个从零开始的教程备忘,这个教程主要分为四部分:
介绍:对板子情况进行介绍
硬件篇:拿到板子后如何做
软件篇:板子系统上的软件配置
TensorRT使用:深度学习推断环境,写如何实现深度学习模型的部署
这一篇主要介绍Jetson Nano板子的基本情况。

介绍
在GTC 2019上,NVIDIA推出人工智能计算机Jetson Nano,外观小巧玲珑如同树莓派,但性能却非常强大,可以提供高达472 GFLOPS的浮点运算能力,而且耗电量仅为5W。
在这里插入图片描述

为了方便大家开发软件程序,JetPack SDK中新增了CUDA-X平台,里面包含40多个加速库,包含用于深度学习、计算机视觉、计算机图形和多媒体处理的加速库,可以加快开发者、企业对于程序上的应用开发。此外还包含有最新版本的CUDA、cuDNN、TensorRT和完整版桌面Linux操作系统。
在这里插入图片描述

Jetson Nano支持高分辨率传感器,可以并行处理多个传感器,并且可在每个传感器流上运行多个现代神经网络。它还支持许多常见的人工智能框架,让开发人员轻松地将自己偏爱的模型及框架集成到产品中。
Jetson Nano硬件为四核Cortex-A57 CPU,GPU则是规模最小的Maxwell架构显卡,只有128个CUDA单元,配备了4GB LPDDR4内存以及16GB存储空间。
按我的理解Jetson就是一块带有GPU的arm开发板,适合边缘计算部署。
板子的主要接口
在这里插入图片描述

一些有用的参考链接:
入门链接:
https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#troubleshooting
2天入门教程:
https://developer.nvidia.com/embedded/twodaystoademo
gpio库,用于控制硬件:
https://github.com/NVIDIA/jetson-gpio
jetbot:
https://github.com/NVIDIA-AI-IOT/jetbot
kit指南下载:
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_docker_containers.html
https://developer.download.nvidia.cn/assets/embedded/secure/jetson/Nano/docs/NVIDIA_Jetson_Nano_Developer_Kit_User_Guide.pdf?G1QqLiZkCG-S_GSqDED8RKsQbnB1ESW3FVknTNaZ5hB6Nd21JSlD4xyA-IKIQV20chAoUD0ld6wUx_c_Ctf8Mx6OP9IN6KOKJLupen6luggEzxMgwyNyi28ksZyBkbw9fVtmpVxBeM3rIaOe2OB_QH0-hzhGaDqE2kXR_MxyLF_VlgNtoDQjDFUn3LLeuEq6N2TZxrxZ

Jetson Nano从零开始(2):硬件篇
摘要
主要硬件:
步骤
1、烧写系统镜像到TF卡
2、开机
其他硬件信息
电源供电方式
连接树莓派相机的方式
其它硬件参考文章:
摘要
这一篇主要讲nano的硬件配置,但我们拿到新的板子后应该怎么做
主要硬件:
1、jetson nano板一块
2、tf卡一块:官方推荐16GB起步,推荐使用64GB UHS-3级别的卡,这个容量够大,速度不错
3、读卡器:用于把系统烧进tf卡
4、5V4A DC电源:推荐使用该电源。nano有多种电源供电方式,这种是供电功率较大的,可以保证系统的稳定,官方推荐5V4A,我用了5V6A的,使用也没问题
5、HDMI线,带HDMI显示器:用于显示,第一次开机时必须要显示器的,但后期如果设置了远程桌面,可以不用
6、其它周边配件:鼠标键盘,USB无线网卡/M2接口网卡Edimax EW-7811Un/网线,USB摄像头/Pi V2摄像头,二脚短路跳帽(必须,用于修改供电方式)
有了这些部件就可以开发了。

步骤
1、烧写系统镜像到TF卡
该步是在win10下进行的,linux、mac下也可以做,参考官方教程
先下载最新系统:
https://developer.nvidia.com/embedded/dlc/jetson-nano-dev-kit-sd-card-image
把tf卡插到读卡器,读卡器插电脑
下载tf卡格式化工具,我们使用使用SD Card Formatter格式化
在这里插入图片描述

下载烧写工具Etcher写入镜像:
https://www.balena.io/etcher/
在这里插入图片描述

20多分钟系统就写好了,把读卡器拔下来,然后把tf卡插到nano上
2、开机
我们使用的时DC供电(HDMI左边黑色的供电口),需要在板子上设置电源供电模式,使得USB供电模式失能才能使用。
我们找到J48的两个引脚,短接上跳线帽即可
在这里插入图片描述

之后我们插上tf卡(位置在散热器下方)、HDMI线、键盘鼠标、USB无线网卡,最后插上电源就可以开机了
在这里插入图片描述

第一次开机会有点久,30s到1min左右,开机之后的设置。然后按照正常的ubuntu系统安装步骤进行安装即可
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
到这里硬件部分的准备就完成了,后面我会介绍软件的设置以及tensorRT的用法
其他硬件信息
电源供电方式
Nano的供电方式有四种模式:
第一种是mirco USB口供电,功率是5W(5V2A)板子本身设计的最大功率是10W,但是如果有其他的外设,比如屏幕什么的,那么对电源的要求就会高于10W
第二种是GPIO引脚供电,功率是15W(5V3A)
第三种是DC接口供电方式,可以承载的功率最大,在20W(5V4A)以上,目前我在用的是5V4A或者5V6A的DC电源,都可以使用。
电源口的尺寸是:长9.5mm,外径5.5mm,内径2.1mm
第四种是所有电源IO反向供电,可以达到30W(5V6A)

连接树莓派相机的方式
Nano可以使用的相机类型有2种,一种时USB摄像头,这种是免驱的,直接插上就可以用了。
此外Nano上还有一个CSI相机接口可以连接相机,目前只支持树莓派的V2摄像头,连接方法如下:
在这里插入图片描述

其它硬件参考文章:
测评:
http://www.52pi.net/archives/1850
外设使用:
https://www.ncnynl.com/category/Nano-hardware/

环境配置
注:配置过程可参考上述安装配置过程,nano无法使用ffmpeg的CUDA加速功能
1 CUDA CUDNN OpenCV 检查是否安装完整
1.1 CUDA 的配置

#编辑环境变量
sudo vim  ~/.bashrc

#在最后添加以下内容
export CUDA_HOME=/usr/local/cuda-10.2
export LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH
export PATH=/usr/local/cuda-10.2/bin:$PATH

#保存生效一下
source ~/.bashrc 

注意:如果添加了环境变量还是显示nvcc not found情况:
先查看 cd /usr/local/cuda/bin 是否存在nvcc文件,如果存在,把上面减少为下面两句:

export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
#保存生效一下
source ~/.bashrc
#查看是否正确 
nvcc -V

显示如下图配置正确:
在这里插入图片描述

1.2 CUDNN 的查看
nano系统已经安装好了cuda及cudnn,运行下mnist案例验证下cudnn是否可用。

#进入案例文件
cd /usr/src/cudnn_samples_v8/mnistCUDNN/mnistCUDNN
#编译一下例子
sudo make     
#运行测试
./mnistCUDNN

注:如果以上无法运行可以添加权限如下方法:

sudo chmod a+x mnistCUDNN # 为可执行文件添加执行权限

运行成功为最后显示检测结果为:1 3 5
1.3 python OpenCV 的查看
python下查看Opencv正常使用及版本

python
import cv2

print(cv2.__version__)

输出为系统OpenCV版本
二、配置基本的系统
4.jetson nano中有docker,因此可以直接拉取docker镜像

#jetson_nano docker
docker pull nvcr.io/nvidia/deepstream-l4t:5.0.1-20.09-samples
或
sudo docker pull nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04
#启动
#cuda10.2有问题,用不了
docker run --gpus all --net=host --privileged=true -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/jdh/data:/root/software -p 6000:22 -m 2g -e DISPLAY=$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE -w /root nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04
docker run --gpus all --net=host --privileged=true -it -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/jdh/data:/root/software -p 0.0.0.0:6000:22 -m 2g -e DISPLAY=$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE -w /root nvcr.io/nvidia/deepstream-l4t:5.0.1-20.09-samples

这些步骤应该在每个NANO上重复:
1.禁用GUI模式,默认是启用的,会消耗资源:(可以暂时不禁用,方便调试)

sudo systemctl set-default multi-user.target

记住,这样做,你的Jetson Nano将启动到文本模式。但是,如果需要,您可以通过将默认系统模式重置为“graphics .target”来逆转这种情况。
2. 确认你的NANO是在高功耗 (10W) 模式下:

sudo nvpmodel -m 0

这通常是一个默认设置。然而,最好还是检查一下。低功耗(5W)模式降低了板的计算性能。
3. 禁用swap——swap会导致Kubernetes的问题:

sudo swapoff -a

4.将NVidia运行时设置为Docker中的默认运行时。对于这个编辑/etc/docker/daemon.json文件,所以它看起来像这样:
添加docker守护进程文件
docker的守护进程参数配置一般在文件 /etc/docker/daemon.json,在该文件中写入

{
    "default-runtime" : "nvidia",
 
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

配置完成后,重启docker

systemctl restart docker

在这里提供的设置中,上面的设置是非常、非常、非常关键的。如果您没有正确地设置此选项,您将遇到很多问题。关于为什么需要这个的详细信息,请看这里的例子
https://github.com/NVIDIA/nvidia-docker/wiki/Advanced-topics#default-runtime.
通过改变默认的运行时,你可以确保每个Docker命令和每个基于Docker的工具都可以访问GPU。

  1. 最后,只是为了确保,更新您的系统到最新版本的安装包:
sudo apt-get update
sudo apt-get dist-upgrade
  1. 将当前用户添加到docker组以使用docker命令而不使用sudo,请遵循以下指南: https://docs.docker.com/install/linux/linux-postinstall/.所需的命令如下:
    sudo groupadd docker
    sudo usermod -aG docker $USER
    newgrp docker
  2. 在所有这些之后,强烈建议重新启动系统。记住,它应该重新启动到文本模式,这很好!

二、jetson nano配置opencv
第一步:
编写 install_opencv4.0.0_Nano.sh

#!/bin/bash
#
# Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#
 
if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <Install Folder>"
    exit
fi
folder="$1"
user="nvidia"
passwd="nvidia"
 
echo "** Install requirement"
sudo apt-get update
sudo apt-get install -y build-essential cmake 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 libjasper-dev libdc1394-22-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2 v4l2ucp
sudo apt-get install -y curl
sudo apt-get update
 
echo "** Download opencv-4.0.0"
cd $folder
curl -L https://github.com/opencv/opencv/archive/4.0.0.zip -o opencv-4.0.0.zip
curl -L https://github.com/opencv/opencv_contrib/archive/4.0.0.zip -o opencv_contrib-4.0.0.zip
unzip opencv-4.0.0.zip 
unzip opencv_contrib-4.0.0.zip 
cd opencv-4.0.0/
 
echo "** Building..."
mkdir release
cd release/
cmake -D WITH_CUDA=ON -D CUDA_ARCH_BIN="5.3" -D CUDA_ARCH_PTX="" -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.0.0/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 ..
make -j3
sudo make install
sudo apt-get install -y python-opencv python3-opencv
 
echo "** Install opencv-4.0.0 successfully"
echo "** Bye :)"

第二步,运行 install_opencv4.0.0_Nano.sh

./install_opencv4.0.0_Nano.sh [folder you want to install OpenCV]

问题解决:
Ubutu18.04无法进入桌面解决方法(输入密码后黑屏后又回到用户登录界面)
gdm出现了兼容性问题

# 安装unity界面
sudo apt-get install unity   

# 启动图形化界面,如果输入命令没有任何动作,执行下一条安装命令
sudo service gdm3 start

# 安装lightdm图形界面,确定y,开始安装,耗时较长30分钟左右
sudo apt-get install lightdm

# 然后执行重启,登陆界面用户名还是哪里点击下拉里面有两个选项
# ubuntu  还有一个ubuntu onwayxxx 啥的(太快了,没看清具体单词),选择这个,然后黑屏,等一会儿就进入桌面了

# 在进行上面步骤之前也可以看下,登陆界面是否有其他图形化界面选择
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐