在NVIDIA Jetson Nano上使用树莓派相机模块(Raspberry Camera V2)

Apr 12,2023   21806 words   78 min


这篇笔记我们简单记录在Jetson Nano上使用树莓派相机的步骤。

1.开发板软硬件环境

我手头的Nano设备是Jetson Nano 4GB版本,如下。 系统安装的是Ubuntu18.04,如下。 利用jtop查看相关信息如下。 同时,在这个网页中,列出了Jetpack SDK、Jetson Linux、Ubuntu Version、Linux Kernel、CUDA Version、Jetson Board之间的对应关系,简单摘录如下。

2.相机传感器

这里我们使用之前介绍过的树莓派相机V2,相机采用Sony IMX219传感器,像素为800万。关于相机传感器更详细的信息可以参考之前的笔记。同时该相机采用了MIPI-CSI接口,正好可以和Nano上的CSI插槽匹配。关于MIPI-CSI接口的进一步介绍可以参考这个网页,里面说的很详细。因此,我们只需要像在树莓派上安装相机一样,将其插入对应CSI插槽即可,安装完的相机和Nano主板如下所示。 如果不会安装,在这个网页中有动图,可以参考。安装好以后,建议重启一下,因为CSI相机不支持热插拨。

3.测试与基本使用

3.1 安装成功测试

重启以后,我们可以在终端输入ls /dev/video*,如果有/dev/video0则表示系统识别到了我们刚刚安装的树莓派相机,如下所示。 这就表示相机安装成功了。如果你的电脑上有V4L库,我们还可以通过v4l2-ctl工具查看相关设备的更多信息(如果没安装输入apt-get install v4l-utils安装,更多用法参考之前笔记)。比如,在终端中输入v4l2-ctl --list-devices同样能看到树莓派相机。 输入v4l2-ctl --list-formats-ext -d /dev/video0就能看到指定相机传感器所支持的数据输出格式,如下。 可以看到树莓派相机支持最高3264x2464@21FPS的输出,也支持1280x720@60FPS的输出。同时,输出像素格式为RG10,也就是10bit量化的RGRG或GBGB的Bayer Pattern数据。

3.2 数据获取
3.2.1 背景知识

需要注意的是,CSI相机和普通的USB相机略有不同,走不同的pipeline。这在之后的内容中再详细介绍,涉及到调用不同库的问题。在Jetson Nano上,它并不支持通过OpenCV,利用之前这篇博客的代码获取数据。代码如下。

# coding=utf-8
import cv2

# 新建一个VideoCapture对象,指定第0个相机进行视频捕获
cap = cv2.VideoCapture(0)

# 一直循环捕获,直到手动退出
while 1:
    # 返回两个值,ret表示读取是否成功,frame为读取的帧内容
    ret, frame = cap.read()
    # 判断传入的帧是否为空,为空则退出
    if frame is None:
        break
    else:
        # 调用OpenCV图像显示函数显示每一帧
        cv2.imshow("video", frame)
        # 用于进行退出条件的判断,这里与0xFF进行了与运算,取输入的低八位
        k = cv2.waitKey(1) & 0xFF
        # 27是ESC键,表示如果按ESC键则退出
        if k == 27:
            break

# 释放VideoCapture对象
cap.release()

强行获取就会报下面的错误,提示资源暂时不可用。 但如果我们在Jetson Nano上插一个普通的USB相机,如下。 则是可以通过上述代码获取数据的。插上USB相机以后,我们可以ls /dev/video*看一下,如下。 可以看到,现在系统里多了一个/dev/video1这就是刚刚插入的USB相机,他在系统里的序号为1。所以我们将上述代码中要获取相机的索引也变为1,运行代码效果如下。 类似的,我们也可以用v4l2-ctl --list-formats-ext -d /dev/video1命令查看一下这个USB相机支持的数据格式,如下。

ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'YUYV'
	Name        : YUYV 4:2:2
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x176
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 432x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 544x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 752x416
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x448
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 864x480
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x544
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x720
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1024x576
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1184x656
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.133s (7.500 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x960
			Interval: Discrete 0.133s (7.500 fps)
			Interval: Discrete 0.200s (5.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 160x120
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 176x144
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x176
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 320x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 352x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 432x240
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 544x288
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 640x360
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 752x416
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x448
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 864x480
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x544
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 960x720
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1024x576
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1184x656
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)
		Size: Discrete 1280x960
			Interval: Discrete 0.033s (30.000 fps)
			Interval: Discrete 0.040s (25.000 fps)
			Interval: Discrete 0.050s (20.000 fps)
			Interval: Discrete 0.067s (15.000 fps)
			Interval: Discrete 0.100s (10.000 fps)
			Interval: Discrete 0.200s (5.000 fps)

可以看到,这个USB相机主要支持两种像素格式输出,一种是YUYV,另一种则是MJPG,并且该相机支持非常多的分辨率和帧率组合。不过,相比于树莓派相机,这个USB相机不支持Raw数据的输出。

那么前面说了这么多,言归正传,到底该怎么获取树莓派CSI相机的数据呢?也有多种方式,下面进行介绍。

3.2.2 利用nvarguscamerasrc插件

NVIDIA为我们提供了Gstreamer插件便于我们调用。我们可以以如下格式启动Gstreamer Pipeline:gst-launch-1.0 <pipeline_name>。因此,我们可以在终端中输入如下命令,即可打开摄像头预览。

gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=3820, height=2464, framerate=21/1, format=NV12' ! nvvidconv flip-method=0 ! 'video/x-raw,width=960, height=616' ! nvvidconv ! nvegltransform ! nveglglessink -e

效果如下。 这行命令的作用是,我们打开一个3264x2464的相机stream(索引为0的相机),然后在一个960x616的窗口中进行展示,帧率为21。更具体的内容之后再介绍,总之,现在我们已经可以在Jetson Nano上正常读取CSI相机的数据了。nvarguscamerasrc插件参数可以通过在终端输入gst-inspect-1.0 nvarguscamerasrc查询。比如在本机的查询结果如下。

xuhui@xuhui-nano:~$ gst-inspect-1.0 nvarguscamerasrc
Factory Details:
  Rank                     primary (256)
  Long-name                NvArgusCameraSrc
  Klass                    Video/Capture
  Description              nVidia ARGUS Camera Source
  Author                   Viranjan Pagar <vpagar@nvidia.com>, Amit Pandya <apandya@nvidia.com>

Plugin Details:
  Name                     nvarguscamerasrc
  Description              nVidia ARGUS Source Component
  Filename                 /usr/lib/aarch64-linux-gnu/gstreamer-1.0/libgstnvarguscamerasrc.so
  Version                  1.0.0
  License                  Proprietary
  Source module            nvarguscamerasrc
  Binary package           NvARGUSCameraSrc
  Origin URL               http://nvidia.com/

GObject
 +----GInitiallyUnowned
       +----GstObject
             +----GstElement
                   +----GstBaseSrc
                         +----GstNvArgusCameraSrc

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      video/x-raw(memory:NVMM)
                  width: [ 1, 2147483647 ]
                 height: [ 1, 2147483647 ]
                 format: { (string)NV12, (string)P010_10LE }
              framerate: [ 0/1, 2147483647/1 ]

Element has no clocking capabilities.
Element has no URI handling capabilities.

Pads:
  SRC: 'src'
    Pad Template: 'src'

Element Properties:
  name                : The name of the object
                        flags: 可读, 可写
                        String. Default: "nvarguscamerasrc0"
  parent              : The parent of the object
                        flags: 可读, 可写
                        Object of type "GstObject"
  blocksize           : Size in bytes to read per buffer (-1 = default)
                        flags: 可读, 可写
                        Unsigned Integer. Range: 0 - 4294967295 Default: 4096 
  num-buffers         : Number of buffers to output before sending EOS (-1 = unlimited)
                        flags: 可读, 可写
                        Integer. Range: -1 - 2147483647 Default: -1 
  typefind            : Run typefind before negotiating (deprecated, non-functional)
                        flags: 可读, 可写, 已废弃
                        Boolean. Default: false
  do-timestamp        : Apply current stream time to buffers
                        flags: 可读, 可写
                        Boolean. Default: true
  silent              : Produce verbose output ?
                        flags: 可读, 可写
                        Boolean. Default: true
  timeout             : timeout to capture in seconds (Either specify timeout or num-buffers, not both)
                        flags: 可读, 可写
                        Unsigned Integer. Range: 0 - 2147483647 Default: 0 
  wbmode              : White balance affects the color temperature of the photo
                        flags: 可读, 可写
                        Enum "GstNvArgusCamWBMode" Default: 1, "auto"
                           (0): off              - GST_NVCAM_WB_MODE_OFF
                           (1): auto             - GST_NVCAM_WB_MODE_AUTO
                           (2): incandescent     - GST_NVCAM_WB_MODE_INCANDESCENT
                           (3): fluorescent      - GST_NVCAM_WB_MODE_FLUORESCENT
                           (4): warm-fluorescent - GST_NVCAM_WB_MODE_WARM_FLUORESCENT
                           (5): daylight         - GST_NVCAM_WB_MODE_DAYLIGHT
                           (6): cloudy-daylight  - GST_NVCAM_WB_MODE_CLOUDY_DAYLIGHT
                           (7): twilight         - GST_NVCAM_WB_MODE_TWILIGHT
                           (8): shade            - GST_NVCAM_WB_MODE_SHADE
                           (9): manual           - GST_NVCAM_WB_MODE_MANUAL
  saturation          : Property to adjust saturation value
                        flags: 可读, 可写
                        Float. Range:               0 -               2 Default:               1 
  sensor-id           : Set the id of camera sensor to use. Default 0.
                        flags: 可读, 可写
                        Integer. Range: 0 - 255 Default: 0 
  sensor-mode         : Set the camera sensor mode to use. Default -1 (Select the best match)
                        flags: 可读, 可写
                        Integer. Range: -1 - 255 Default: -1 
  total-sensor-modes  : Query the number of sensor modes available. Default 0
                        flags: 可读
                        Integer. Range: 0 - 255 Default: 0 
  exposuretimerange   : Property to adjust exposure time range in nanoseconds
			Use string with values of Exposure Time Range (low, high)
			in that order, to set the property.
			eg: exposuretimerange="34000 358733000"
                        flags: 可读, 可写
                        String. Default: null
  gainrange           : Property to adjust gain range
			Use string with values of Gain Time Range (low, high)
			in that order, to set the property.
			eg: gainrange="1 16"
                        flags: 可读, 可写
                        String. Default: null
  ispdigitalgainrange : Property to adjust digital gain range
			Use string with values of ISP Digital Gain Range (low, high)
			in that order, to set the property.
			eg: ispdigitalgainrange="1 8"
                        flags: 可读, 可写
                        String. Default: null
  tnr-strength        : property to adjust temporal noise reduction strength
                        flags: 可读, 可写
                        Float. Range:              -1 -               1 Default:              -1 
  tnr-mode            : property to select temporal noise reduction mode
                        flags: 可读, 可写
                        Enum "GstNvArgusCamTNRMode" Default: 1, "NoiseReduction_Fast"
                           (0): NoiseReduction_Off - GST_NVCAM_NR_OFF
                           (1): NoiseReduction_Fast - GST_NVCAM_NR_FAST
                           (2): NoiseReduction_HighQuality - GST_NVCAM_NR_HIGHQUALITY
  ee-mode             : property to select edge enhnacement mode
                        flags: 可读, 可写
                        Enum "GstNvArgusCamEEMode" Default: 1, "EdgeEnhancement_Fast"
                           (0): EdgeEnhancement_Off - GST_NVCAM_EE_OFF
                           (1): EdgeEnhancement_Fast - GST_NVCAM_EE_FAST
                           (2): EdgeEnhancement_HighQuality - GST_NVCAM_EE_HIGHQUALITY
  ee-strength         : property to adjust edge enhancement strength
                        flags: 可读, 可写
                        Float. Range:              -1 -               1 Default:              -1 
  aeantibanding       : property to set the auto exposure antibanding mode
                        flags: 可读, 可写
                        Enum "GstNvArgusCamAeAntiBandingMode" Default: 1, "AeAntibandingMode_Auto"
                           (0): AeAntibandingMode_Off - GST_NVCAM_AEANTIBANDING_OFF
                           (1): AeAntibandingMode_Auto - GST_NVCAM_AEANTIBANDING_AUTO
                           (2): AeAntibandingMode_50HZ - GST_NVCAM_AEANTIBANDING_50HZ
                           (3): AeAntibandingMode_60HZ - GST_NVCAM_AEANTIBANDING_60HZ
  exposurecompensation: property to adjust exposure compensation
                        flags: 可读, 可写
                        Float. Range:              -2 -               2 Default:               0 
  aelock              : set or unset the auto exposure lock
                        flags: 可读, 可写
                        Boolean. Default: false
  aeregion            : Property to set region of interest for auto exposure
			with values of ROI coordinates (left, top, right, bottom)
			and weight (float number) in that order, to set the property
			use for example: aeregion="0 0 256 256 1"
                        flags: 可读, 可写
                        String. Default: null
  awblock             : set or unset the auto white balance lock
                        flags: 可读, 可写
                        Boolean. Default: false
  bufapi-version      : set to use new Buffer API
                        flags: 可读, 可写
                        Boolean. Default: false
3.2.3 利用OpenCV

在前面我们展示了,直接使用OpenCV无法在Jetson Nano上获取树莓派CSI相机的数据。但我们可以将cv2.VideoCapture()函数的参数修改一下,修改成上面的nvarguscamerasrc参数即可,本质上还是利用Gstreamer。代码如下。

# coding=utf-8
import cv2

csiSet = r"nvarguscamerasrc sensor-id=0  ! video/x-raw(memory:NVMM),width=3820, height=2464, framerate=21/1, format=NV12  ! nvvidconv flip-method=0 ! video/x-raw,width=960, height=616, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink"

# 新建一个VideoCapture对象,传入参数
cap = cv2.VideoCapture(csiSet)

# 一直循环捕获,直到手动退出
while 1:
    # 返回两个值,ret表示读取是否成功,frame为读取的帧内容
    ret, frame = cap.read()
    # 判断传入的帧是否为空,为空则退出
    if frame is None:
        break
    else:
        # 调用OpenCV图像显示函数显示每一帧
        cv2.imshow("video", frame)
        # 用于进行退出条件的判断,这里与0xFF进行了与运算,取输入的低八位
        k = cv2.waitKey(1) & 0xFF
        # 27是ESC键,表示如果按ESC键则退出
        if k == 27:
            break

# 释放VideoCapture对象
cap.release()

执行效果如下。 这个方法本质上来说和第一种是一样的还是通过nvarguscamerasrc获取相机数据,OpenCV更像是一个“套壳”。在这个网页中,还提供了C++版本的代码,感兴趣可以参考。

3.2.4 利用nvstcapture

打开终端,输入nvstcapture-1.0即可接收数据,控制台会输出如下内容。

xuhui@xuhui-nano:~$ nvgstcapture-1.0
Encoder null, cannot set bitrate!
Encoder Profile = High
Supported resolutions in case of ARGUS Camera
  (2) : 640x480
  (3) : 1280x720
  (4) : 1920x1080
  (5) : 2104x1560
  (6) : 2592x1944
  (7) : 2616x1472
  (8) : 3840x2160
  (9) : 3896x2192
  (10): 4208x3120
  (11): 5632x3168
  (12): 5632x4224

Runtime ARGUS Camera Commands:

  Help : 'h'
  Quit : 'q'
  Set Capture Mode:
      mo:<val>
          (1): image
          (2): video
  Get Capture Mode:
      gmo
  Set sensor orientation:
      so:<val>
          (0): none
          (1): Rotate counter-clockwise 90 degrees
          (2): Rotate 180 degrees
          (3): Rotate clockwise 90 degrees
  Get sensor orientation:
      gso
  Set sensor mode:
      smo:<val> e.g., smo:1
  Get sensor mode:
      gsmo
  Set Whitebalance Mode:
      wb:<val>
          (0): off
          (1): auto
          (2): incandescent
          (3): fluorescent
          (4): warm-fluorescent
          (5): daylight
          (6): cloudy-daylight
          (7): twilight
          (8): shade
          (9): manual
  Get Whitebalance Mode:
      gwb
  Set Saturation (0 to 2):
      st:<val> e.g., st:1.25
  Get Saturation:
      gst
  Set Exposure Compensation (-2 to 2):
      ec:<val> e.g., ec:-2
  Get Exposure Compensation:
      gec
  Set Auto Whitebalance Lock:
      awbl:<val> e.g., awbl:0
  Get Auto Whitebalance Lock:
      awbl
  Set Auto Exposure Lock:
      ael:<val> e.g., ael:0
  Get Auto Exposure Lock:
      gael
  Set TNR Mode:
      tnrm:<val> e.g., tnrm:1
          (0): OFF
          (1): FAST
          (2): HIGH QUALITY
  Get TNR Mode:
      gtnrm
  Set TNR Strength (-1 to 1):
      tnrs:<val> e.g., tnrs:0.5
  Get TNR Strength:
      gtnrs
  Set EE Mode:
      eem:<val> e.g., eem:1
          (0): OFF
          (1): FAST
          (2): HIGH QUALITY
  Get EE Mode:
      geem
  Set EE Strength (-1 to 1):
      ees:<val> e.g., ees:0.5
  Get EE Strength:
      gees
  Set Auto Exposure Anti-Banding (0 to 3):
      aeab:<val> e.g., aeab:2
          (0): OFF
          (1): MODE AUTO
          (2): MODE 50HZ
          (3): MODE 60HZ
  Get Auto Exposure Anti-Banding:
      gaeab
  Set Gain Range:
      gr:<val><space><val> e.g., gr:1 16
  Get Gain Range:
      ggr
  Set Exposure Time Range:
      etr:<val><space><val> e.g., etr:34000 35000
  Get Exposure Time Range:
      getr
  Set ISP Digital Gain Range:
      dgr:<val><space><val> e.g., dgr:2 152
  Get ISP Digital Gain Range:
      gdgr
  Capture: enter 'j' OR
           followed by a timer (e.g., jx5000, capture after 5 seconds) OR
           followed by multishot count (e.g., j:6, capture 6 images)
           timer/multihot values are optional, capture defaults to single shot with timer=0s
  Start Recording : enter '1'
  Stop Recording  : enter '0'
  Video snapshot  : enter '2' (While recording video)
  Get Preview Resolution:
      gpcr
  Get Image Capture Resolution:
      gicr
  Get Video Capture Resolution:
      gvcr


Runtime encoder configuration options:

  Set Encoding Bit-rate(in bytes):
      br:<val> e.g., br:4000000
  Get Encoding Bit-rate(in bytes):
      gbr
  Set Encoding Profile(only for H.264):
      ep:<val> e.g., ep:1
          (0): Baseline
          (1): Main
          (2): High
  Get Encoding Profile(only for H.264):
      gep
  Force IDR Frame on video Encoder(only for H.264):
      Enter 'f' 


bitrate = 4000000
Encoder Profile = High
Encoder control-rate = 1
Encoder EnableTwopassCBR = 0
Opening in BLOCKING MODE 
** Message: 18:55:08.923: <main:4674> iterating capture loop ....
NvMMLiteOpen : Block : BlockType = 4 
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4 
GST_ARGUS: Creating output stream
CONSUMER: Waiting until producer is connected...
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 3264 x 2464 FR = 21.000000 fps Duration = 47619048 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 3264 x 1848 FR = 28.000001 fps Duration = 35714284 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1920 x 1080 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1640 x 1232 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1280 x 720 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1280 x 720 FR = 120.000005 fps Duration = 8333333 ; Analog Gain range min 1.000000, max 10.625000; Exposure Range min 13000, max 683709000;

GST_ARGUS: Running with following settings:
   Camera index = 0 
   Camera mode  = 5 
   Output Stream W = 1280 H = 720 
   seconds to Run    = 0 
   Frame Rate = 120.000005 
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.
CONSUMER: Producer has connected; continuing.
^C** Message: 18:55:10.127: <_intr_handler:4262> User Interrupted.. 

Terminating the camera pipeline ...
GST_ARGUS: Cleaning up
CONSUMER: Done Success
GST_ARGUS: Done Success
** Message: 18:55:10.737: <main:4684> Capture completed
** Message: 18:55:10.737: <main:4733> Camera application will now exit

从控制台的输出来看,可以看到,Argus支持多种模式,最高甚至可以支持1280x720@120FPS的模式,效果如下。 当然它也有一些参数可以设置,可以参考这个网页,之后再做介绍。

3.2.5 利用v4l2-ctl

根据之前的笔记,我们还可以使用V4L2来获取数据。首先在终端中输入v4l2-ctl --list-formats-ext查询树莓派相机支持的分辨率大小(其实在3.1部分已经查看过了)。比如我们选择1280x720的分辨率。然后输入如下命令,开启拍摄。

v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=JPEG --stream-mmap --stream-count=1 --stream-to=test.jpg

但不知道为什么,这个命令在我的Jetson Nano上运行会卡住,暂时还不清楚原因。如果有了解的小伙伴欢迎交流。

[2023-04-13更新]

根据这个网页的介绍,其中提到:The best way to interface with the Jetson’s multimedia hardware (including the ports for CSI cameras) is via their libargus C++ library or through gstreamer. Nvidia does not support the V4L2 video protocol for CSI cameras. 因此,对于CSI相机,Jetson平台不支持基于V4L2的数据获取。上面提到的这个问题,大概率是因为在Jetson平台上,V4L2不支持CSI相机而导致的。我们可以在Jetson上通过V4L2获取其它USB相机的数据。

[更新结束]

3.2.6 利用v4l2src插件

NVIDIA官方除了nvarguscamerasrc插件,还提供了一个叫做v4l2src的Gstreamer插件,我们也可以基于它获取数据。命令如下。

gst-launch-1.0 -v v4l2src device=/dev/video0 ! jpegdec ! video/x-raw,framerate=21/1,width=3820,height=2464 ! videoconvert ! xvimagesink 
3.2.7 利用libargus

最后的最后,也就是利用Jetson平台提供的Argus API自己编写程序,实现对于相机的完全控制。这部分内容会在之后的笔记中再进一步介绍。感兴趣可以先看这个Youtube视频

4.参考资料

  • [1] https://zhuanlan.zhihu.com/p/599531271
  • [2] https://mp.weixin.qq.com/s?__biz=MjM5NTE3Nzk4MQ==&mid=2651234579&idx=1&sn=7f10f030e9c60b15c6805fa1ea495347
  • [3] http://www.taodudu.cc/news/show-4199292.html
  • [4] https://blog.csdn.net/weixin_45463952/article/details/124068859
  • [5] https://zhuanlan.zhihu.com/p/347215782
  • [6] https://www.stereolabs.com/blog/nvidia-jetson-l4t-and-jetpack-support/

本文作者原创,未经许可不得转载,谢谢配合

返回顶部