TX2上的CSI摄像头(简易方式)
我喜欢Nvidia的新嵌入式计算机。在Nvidia的杰特森嵌入式计算产品线,包括TK1,TX1,TX2和,是一系列小型电脑制造流畅运行计算机视觉,神经网络和人工智能软件,而无需使用吨的能量。更好的是,他们的开发人员套件可以用作优秀的单板计算机,所以如果你曾经希望加强Raspberry Pi,这就是你想要的。我个人使用Jetson TX2,这是目前功能最强大的模块,并且被广泛使用。
使用Jetson设备的一个重大缺点是文档没有(也不能)涵盖所有用例。社区尚未成熟到可以随时找到随机博客的指南(例如Raspberry Pi和Arduino),所以你经常要为自己找出一些东西。
但是,我在这里至少消除了一件事 - 使用你的TX2上的CSI摄像头。这些方法也适用于其他Jetson设备!
我们将考虑利用Jetson的图像处理能力并从TX2自己的特殊CSI摄像头端口捕获视频。具体来说,我会告诉你:
为什么你甚至想要CSI相机。
哪里可以买到好的CSI相机。
如何 使用和Nvidia多媒体管道从CSI摄像机获得高分辨率,高帧率视频gstreamer。
如何在OpenCV和ROS中使用该视频。
目录
为何选择CSI摄像头(与USB相比)?
为什么CSI相机的性能优于USB?
哪里可以获得CSI摄像头(适用于Jetson设备)
从CSI相机中取出视频
选择正确的管道
命令行工具
OpenCV的
在Nvidia Jetson上使用GStreamer支持编译OpenCV 3
从OpenCV中的GStreamer管道捕获视频
机器人操作系统(ROS)
为何选择CSI摄像头(与USB相比)?
如果您希望获得最大性能(在FPS,分辨率和CPU使用方面)或者您需要对相机进行低级别控制 - 如果您愿意支付相机,CSI相机应该是您的主要相机选择这些功能的优质。
我个人使用CSI摄像头,因为我需要高分辨率视频,同时保持可接受的帧率。使用TX2和Leopard Imaging IMX377CS,我可以轻松地以~20 fps的速度拉动4k视频。真棒。我也喜欢在CSI摄像机上更换镜头的能力,这些摄像机通常使用小型C-Mount或M12镜头。由于GoPro的普及,有大量的C / CS-Mount镜头以及用于将DSLR相机镜头转换为C-Mount的镜头适配器。
另一方面,USB摄像头可以非常便宜,通常通过V4L2协议开箱即用,是您不需要高性能视频的应用的绝佳选择。您可以使用Logitech C270以20美元的价格购买720p视频,正如加利福尼亚理工州立大学所做的那样,他们的“Jet”机器人套件就足够了,这足以使他们的机器人玩具车识别和收集物品,找到面孔,找到线条等等。 。
用户Jazza 在Nvidia开发者论坛上发布的一篇精彩帖子指出了USB和CSI摄像机之间的进一步比较:
USB摄像头:
很容易整合。
可以做很多离线图像工作(曝光控制,帧速率等)。
许多提供输入/中断可以帮助您的应用程序计时(例如,在新帧上中断)。
由于USB总线使用CPU时间,如果它使用100%CPU,这将影响您的应用程序。
对于硬件视觉管道(硬件编码器等)的使用不是最佳的。
可以长距离工作(最高可达USB标准)。
可以支持更大的图像传感器(1英寸或更高,以获得更好的图像质量和更低的噪音)。
CSI总线摄像头:
在CPU和内存使用方面进行了优化,可以处理图像并将其处理到内存中。
可以充分利用硬件视觉管道。
距离TX1的距离很短(通常最大10cm),除非您使用的是序列化系统(GMSL,FPD Link,COAXPress,Ambarella),这些系统目前尚不成熟且高度定制。
主要是来自手机相机模块的较小传感器,但定制的传感器可以付出代价。通过TX1 / 2中的硬件降噪可以减轻来自较小传感器的附加噪声。
使您可以访问传感器/摄像头的低级控制。
我建议您查看完整帖子以获取更多见解,例如联网摄像头的注意事项。
为什么CSI相机的性能优于USB?
USB最大的问题是带宽和处理需求。USB 3.0可以推动5 Gbps,这在技术上足以允许以60 fps或甚至4k(3840p)以20 fps 推送未压缩的 1080p视频流(请亲自看看)。但是,这仅基于带宽,并未揭示处理视频时额外处理和内存管理瓶颈的真实性。例如,See3CAM_CU130 USB 3.0相机应该能够支持60fps 1080p,但在TK1 的真实世界测试中,它只能在1080p压缩时获得18 fps,而在未压缩时仅需1fps。虽然在功能更强大的机器上性能会更好,但这是问题的证据。
相比之下,Jetson TX1和TX2 采用 “六个专用MIPI CSI-2摄像机端口,每个通道带宽高达2.5 Gb / s,双图像服务处理器(ISP)提供1.4 gigapixels / s处理。”换句话说,它具有三个4k摄像头(或六个1080p摄像头,30 fps的带宽))。同样,带宽并非一切,因为这些图像需要移动和处理,但是通过使用硬件视觉管道,图像跳过加载到DRAM中并通过独立于主CPU处理视频来减少CPU负载。根据我自己的经验,我已经能够通过利用TX2上的这些硬件功能以~20 fps运行4k视频。这就是为什么视频通过CSI摄像机如此有效地工作 - 专用于视频的独立硬件,就像GPU专用于3D图形一样。
哪里可以获得CSI摄像头(适用于Jetson设备)
在我自己的研究中,我发现只有少数资源来寻找CSI相机。Jetson Wiki有一个不错的页面来调查不同的相机选项,你可以找到关于Jetson开发者表单的一些提示,但就是这样。
至于实际的商店,有:
e-con Systems,为Jetson设备生产CSI摄像头和USB摄像头。
Leopard Imaging,为Jetson制作CSI相机。
这两家公司都是Nvidia的官方影像合作伙伴,并提供从相机中提取数据所需的驱动程序和说明。
我个人使用Leopard Imaging IMX377CS并发现它非常强大。此外,他们有很好的安装驱动程序的说明,这是值得欢迎的。
从CSI相机中取出视频
在Nvidia的“ JetPack Camera API入门 ”中,他们解释了与Jetson的多媒体硬件(包括CSI摄像头的端口)连接的最佳方式是通过他们的libargusC ++库或通过gstreamer。Nvidia不支持CSI摄像机的V4L2视频协议。由于gstreamer有很好的记录和非常普遍,我专注于它。
GStreamer使用管道进行配置,该管道解释了从输入到输出应用于视频流的一系列操作。从CSI相机获取视频的关键归结为能够(1)gstreamer在您的程序中使用以及(2)使用高效的管道。
关于驱动程序的注意事项:在任何GStreamer功能工作之前,您很可能需要为相机安装驱动程序。由于CSI摄像机往往是一个较小的市场,您可能无法在线找到指南,但应该能够从制造商那里获得一个。例如,Leopard Imaging提供了一个很好的指导(通过电子邮件)来设置他们的驱动程序,但它只让我到终端使用GStreamer。在这篇文章中,我们将进一步冒险并将这些数据放入您的代码中。
选择正确的管道
正如我刚才提到的,使用CSI摄像头获得高质量性能的关键之一就是使用最有效的gstreamer流水线。这通常意味着以正确的格式输出。你会看到我反复使用一条管道:
1
nvcamerasrc ! video/x-raw(memory:NVMM), width=1920, height=(int)1080, format=(string)I420, framerate=(fraction)30/1 ! nvvidconv flip-method=2 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink
这里非常重要的部分是video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR确保来自CSI摄像机的原始视频转换为BGR色彩空间。
在OpenCV和许多其他程序的情况下,图像以该BGR格式存储。通过使用图像管道预转换为BGR,我们确保使用这些硬件模块来转换图像而不是CPU。在我自己的实验中,使用没有这种转换的管道会导致可怕的性能,TX2上的1080p视频最大约为10fps。
命令行工具
我将简要介绍一些命令行工具。
nvgstcapture
nvgstcapture-1.0是L4T附带的一个程序,可以轻松捕获并将视频保存到文件中。这也是从相机中提取视图的快捷方式。
GST推出
你可以运行GStreamer管道gst-launch-1.0 。
示例1:从相机查看1080p视频
gst-launch-1.0 nvcamerasrc ! ‘video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)I420, framerate=(fraction)60/1’ ! nvvidconv ! ‘video/x-raw(memory:NVMM), format=(string)I420’ ! nvoverlaysink -e
示例2:从相机查看1080p视频并将真实的fps打印到控制台。
gst-launch-1.0 nvcamerasrc ! ‘video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)I420, framerate=(fraction)60/1’ ! nvvidconv ! ‘video/x-raw(memory:NVMM), format=(string)I420’ ! fpsdisplaysink text-overlay=false -v
查看Tegra X1指南的Gstreamer管道,了解更多示例管道。
gst-inspect
您可以使用检查管道元素gst-inspect-1.0
示例:检查CSI摄像头接口的功能。
1
gst-inspect-1.0 nvcamerasrc
OpenCV的
好吧,让我们开始在我们自己的代码中捕获视频,而不是只是搞乱终端中的东西。
在设置Jetson设备时,Nvidia Jetpack安装了一个名为OpenCV4Tegra的OpenCV的特殊闭源版本,该版本针对Jetson进行了优化,并且比开源版本略快。虽然OpenCV4Tegra运行速度比普通OpenCV 2好,但OpenCV 2的所有版本都不支持视频捕获gstreamer,因此我们无法轻松从中获取视频。
如果您使用正确的选项从源代码编译视频,OpenCV 3 确实支持捕获视频。因此,我们将使用自编译的OpenCV 3替换OpenCV4Tegra。一旦完成,通过管道捕获视频非常容易。gstreamer gstreamer
在Nvidia Jetson上使用GStreamer支持编译OpenCV 3
通过运行以下命令删除OpenCV4Tegra:
sudo apt-get purge libopencv4tegra-dev libopencv4tegra
sudo apt-get purge libopencv4tegra-repo
sudo apt-get update
下载Jetson Hacks的Jetson TX2 OpenCV安装程序:
git clone https://github.com/jetsonhacks/buildOpenCVTX2.git
cd buildOpenCVTX2
(有关此脚本的更多信息,请参阅Jetson Hacks自己的安装指南。)
打开buildOpenCV.sh并将行更改-DWITH_GSTREAMER=OFF \为-DWITH_GSTREAMER=ON \。这将确保OpenCV在编译时得到gstreamer支持。
通过运行安装脚本来构建OpenCV。这需要一些时间。
./buildOpenCV.sh
Jetson Hacks还警告说“ 有时make工具不能构建所有东西。经验要求返回构建目录并再次运行make,以确保。“我推荐同样的。如果您真的需要帮助,请查看他们的视频指南。
最后,切换到build目录以安装刚刚构建的库。
cd ~/opencv/build
sudo make install
从OpenCV中的GStreamer管道捕获视频
我们现在安装了可以捕获视频的OpenCV gstreamer,让我们使用它!幸运的是,我在Github上有一个很好的C ++示例脚本,旨在通过OpenCV捕获和显示来自gstreamer的视频。让我们来看看。
gstreamer_view.cppC++
/*
Example code for displaying gstreamer video from the CSI port of the Nvidia Jetson in OpenCV.
Created by Peter Moran on 7/29/17.
https://gist.github.com/peter-moran/742998d893cd013edf6d0c86cc86ff7f
*/
#include
std::string get_tegra_pipeline(int width, int height, int fps) {
return “nvcamerasrc ! video/x-raw(memory:NVMM), width=(int)” + std::to_string(width) + “, height=(int)” +
std::to_string(height) + “, format=(string)I420, framerate=(fraction)” + std::to_string(fps) +
“/1 ! nvvidconv flip-method=2 ! video/x-raw, format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink”;
}
int main() {
// Options
WIDTH = 1920;
HEIGHT = 1080;
FPS = 30;
// Define the gstream pipeline
std::string pipeline = get_tegra_pipeline(WIDTH, HEIGHT, FPS);
std::cout << "Using pipeline: \n\t" << pipeline << "\n";
// Create OpenCV capture object, ensure it works.
cv::VideoCapture cap(pipeline, cv::CAP_GSTREAMER);
if (!cap.isOpened()) {
std::cout << "Connection failed";
return -1;
}
// View video
cv::Mat frame;
while (1) {
cap >> frame; // Get a new frame from camera
// Display frame
imshow("Display window", frame);
cv::waitKey(1); //needed to show frame
}
}
首先,我们使用Nvidia的nvcamerasrc界面定义一个有效的管道,并确保我们预先转换为BGR颜色空间。然后我们定义一个使用GStreamer的捕获对象。最后,我们捕获每个帧并以无限循环显示它。而已!
我还有另一个脚本用于测试各种不同分辨率和FPS的FPS。
ROS用户注意事项:如果安装了ROS,您可能会发现此脚本不起作用。这通常是因为您将端口附近的~/.bashrc线包括在内source /opt/ros//setup.bash,正如ROS安装指南所建议的那样。这会导致ROS在您的安装中导入自己的ROS版本。如果您只需要视频捕获,那么只需使用jetson_csi_camROS的下一部分即可。如果某些特定应用程序不需要ROS,则解决此问题的方法是从~/.bashrc需要ROS时删除该行并运行安装文件。
定制OpenCV和ROS在一起?您不应该尝试在ROS程序中使用自编译的OpenCV安装。ROS使用它自己的OpenCV版本,称为opencv2和opencv3,它涉及一个难以避免的纠结的依赖网络。如果你愿意让事情变得混乱,可以使用你自己的OpenCV版本,但我真的不推荐它。
机器人操作系统(ROS)
让你的CSI摄像机在ROS中运行起来比OpenCV更容易。您需要做的就是安装我的ROS软件包jetson_csi_cam(README将指导您完成所需的所有步骤)。它的工作方式与OpenCV解决方案相同,但使用不同的库从gstreamer中获取视频,并提供ROS中预期的额外细节。重要的是,它还为CSI摄像机使用正确,高效的管道。
http://petermoran.org/csi-cameras-on-tx2/
这是原文的网址