模板: RPi Camera picamera2 Guide

来自Waveshare Wiki
跳转至: 导航搜索

代码调用摄像头

树莓派官方提供的picamera2库是针对libcamera 驱动提供的 python库。
注意:Picamera2仅支持Raspberry Pi OS Bullseye 镜像。

库安装

安装picamera2,Picamera2 现已预装在最新的几版Raspberry Pi OS Bullseye镜像中,您可以通过终端做以下操作来更新库:

sudo apt update
sudo apt upgrade
sudo apt install -y python3-picamera2

CSI摄像头使用

CSI摄像头检测

使用前需要先打开终端输入以下指令,来检查摄像头是否正常工作

libcamera-hello -t 0 

预览窗口实现

预览窗口参数
  • x - 预览窗口的 x 偏移量
  • y - 预览窗口的 y 偏移量
  • width - 预览窗口的宽度
  • height - 预览窗口的高度
  • transform - 允许相机图像在显示器上水平和/或垂直翻转的变换

所有参数都是可选的,如果省略,将选择默认值。以下示例将放置一个800x600像素的预览窗口位于显示屏上的(100,200),并将水平镜像相机预览图像:

from picamera2 import Picamera2, Preview
from libcamera import Transform
picam2 = Picamera2()
picam2.start_preview(Preview.QTGL, x=100, y=200, width=800, height=600,
transform=Transform(hflip=1))
picam2.start()
支持的转换
  • Transform() - 恒等转换,这是默认值
  • Transform(hflip=1) - 水平翻转
  • Transform(vflip=1) - 垂直翻转
  • Transform(hflip=1,vflip=1) - 水平和垂直翻转(相当于180度旋转)

注意:这里的显示转换对实际图像并没有任何影响,在上面的示例中,必须在调用picam2.start()之前调用start_preview()函数,如果相机的图像与预览窗口的长宽比不同,它们将被变成letter-boxed或者pillar-boxed式以使图像保持合适的长宽比

无预览(NULL preview)

通常是预览窗口通过接收和传递相机图像来驱动libcamera系统到应用程序,然后在用户不再需要这些缓冲区时将它们回收回libcamera。结果是,即使没有显示预览图像,仍然需要运行一些东西来接收和返回这些相机图像。这正是无预览所做的。它什么也没有显示,它只是驱动摄像系统。如果系统尚未运行预览,则必须提前开启备用预览窗口。实际上每当启动相机系统 (picam2.start())时,都会自动启动无预览。您可以开启无预览显示,像这样:

from picamera2 import Picamera2, Preview
picam2 = Picamera2()
picam2.start_preview(Preview.NULL)
开启和关闭预览

start_preview函数的第一个参数可以采用以下值:

  • None - 不启动任何类型的预览。应用程序必须提供自己的代码来驱动摄像头系统。
  • False - NULL预览启动。
  • True - 其他三个预览中的一个已经开始。

不建议开始和停止预览窗口同时进行,因为在此期间摄像头帧很可能被丢弃。Start函数会接受一个show_preview形参,该形参可以是这些相同值中的任意一个。这是只是一种简写,可以减少代码的书写量。注意,停止相机(Picamera2.stop)不会停止预览窗口,因此必须在此之前显式调用stop_preview函数,例如,下面的脚本将启动相机系统运行,运行一会儿,然后尝试自动检测要使用哪个预览窗口,以便实际开始显示图像:

from picamera2 import Picamera2, Preview
import time
picam2 = Picamera2()
config = picam2.create_preview_configuration()
picam2.configure(config)
picam2.start() #启动相机捕获
time.sleep(2) #为等待相机初始化完成延迟2秒
picam2.stop_preview() #停止相机预览,防止占用资源,从而开启相机失败
picam2.start_preview(True) #开启相机预览
time.sleep(2) #两秒后关闭相机

Picamera2的高级API

Picamera2有一些高级和非常方便的功能,用于捕获图像和视频录制。寥寥几句代码便可实现捕获图像:

from picamera2 import Picamera2
picam2 = Picamera2()
picam2.start_and_capture_file("test.jpg")

也可以使用start_and_capture_files函数捕获多个图像,或者录制一个五秒钟的视频:

from picamera2 import Picamera2
picam2 = Picamera2()
picam2.start_and_record_video("test.mp4", duration=5)

如果想了解底层代码,您可以参考以下代码:

from picamera2 import Picamera2, Preview
import time
picam2 = Picamera2() # 创建一个 Picamera2 实例
camera_config = picam2.create_preview_configuration() # 创建摄像头预览配置
picam2.configure(camera_config) # 配置摄像头
picam2.start_preview(Preview.QTGL) # 启动摄像头预览(使用 QTGL 预览窗口管理器)
picam2.start() # 启动摄像头
time.sleep(2) # 等待 2 秒,确保摄像头已启动
picam2.capture_file("test.jpg")  # 拍摄照片并保存为 "test.jpg"

配置摄像头

Picamera2提供了许多配置生成方法,可用于提供合适的配置,常见的用例如下:

  • Picamera2. create_preview_configuration 将生成用于在显示器上或在捕获静止图像之前显示相机预览图像的配置
  • Picamera2. create_still_configuration 将生成一个适合捕获高分辨率静止图像的配置
  • Picamera2. create_video_configuration 将生成一个适合录制视频文件的配置

例如,设置摄像头,让它开始传送你可能会用到的预览图像流:

from picamera2 import Picamera2
picam2 = Picamera2()
config = picam2.create_preview_configuration()
picam2.configure(config)
picam2.start()
一般参数配置
  • transform -无论相机图像水平或垂直镜像或两者兼而有之(给予180度旋转)。
    可以使用transform关键字参数将转换传递给所有的配置生成方法,Picamera2只支持上面所示的转换。其他变换(包括图像变换)存在,但是不支持。如果未指定,则转换始终默认为恒等转换。如下:
    from picamera2 import Picamera2
    from libcamera import Transform
    picam2 = Picamera2()
    preview_config = picam2.create_preview_configuration(transform=Transform(hflip=True))
    

  • colour_space -输出图像的颜色空间。主流和 lores 流必须始终共享相同色彩空间。原始流总是在相机特定的色彩空间中。
    libcamera中色彩空间的实现与Linux V4L2 API非常接近。具体的选择有为每种原色提供传递函数、YCbCr编码矩阵和量化(或范围)。此外,libcamera为常用的色彩空间提供了方便的速记形式:
    >>> from libcamera import ColorSpace
    >>> ColorSpace.Sycc()
    <libcamera.ColorSpace 'sYCC'>
    >>> ColorSpace.Rec709()
    <libcamera.ColorSpace 'Rec709'>
    

    这些实际上是Pi的相机系统所支持的唯一色彩空间。所需的选择可以传递给所有使用 color_space 关键字参数的配置生成方法:

    from picamera2 import Picamera2
    from libcamera import ColorSpace
    picam2 = Picamera2()
    preview_config = picam2.create_preview_configuration(colour_space=ColorSpace.Sycc())
    

    当省略时,Picamera2将根据用例选择默认值:
    •create_preview_configuration和create_still_configuration将默认使用sYCC颜色空间平均sRGB原色和传递函数和全范围BT.601 YCbCr编码)。
    •如果主流请求RGB格式,create_video_configuration将选择sYCC。对于YUV格式,如果分辨率小于1280x720,它会选择SMPTE 170M,否则选择Rec.709。

  • buffer_count -分配给相机系统的缓冲区的数量。一组缓冲区表示每个被请求的流都有一个缓冲区。
    这定义了为相机系统分配多少组缓冲区(每个请求流一个)使用。分配更多的缓冲可以意味着相机将运行更平稳,丢帧更少,缺点是,特别是在高分辨率下,可能没有足够的可用内存。
    •create_preview_configuration请求四组缓冲区
    •create_still_configuration只请求一组缓冲区(因为这些通常是大的全分辨率缓冲区)
    •create_video_configuration请求六个缓冲区,作为编码和输出视频所涉及的额外工作流使得它更容易受到抖动或延迟的影响,这可以通过更长的缓冲区队列来缓解。
    可以使用buffer_count关键字参数在所有配置生成方法中重写缓冲区的数量:
    from picamera2 import Picamera2
    picam2 = Picamera2()
    preview_config = picam2.create_still_configuration(buffer_count=2)
    
  • queue -是否允许系统将准备捕获请求的帧排队。
    默认情况下,Picamera2保留从相机接收到的最后一帧,当你进行捕获时请求时,此帧可能会返回给您。这对于突发捕获很有用,特别是当应用程序正在进行一些处理时,可能需要比帧周期稍长的时间。在这些情况下,排队的帧可以是立即返回,而不是闲置到下一个相机帧到达。 但这确实意味着返回的帧可以在捕获请求发生之前稍早一点,最多一个帧周期。如果不需要此行为,请将队列参数设置为False。例如:
    from picamera2 import Picamera2
    picam2 = Picamera2()
    preview_config = picam2.create_preview_configuration(queue=False)
    

    注意,当buffer_count设置为1时(仍然是捕获配置的默认情况),则没有帧永远排队(因为唯一的缓冲区会完全停止相机管道)。

  • display - 这个名称(如果有的话)的流将显示在预览窗口。它实际上不会以任何方式影响相机图像,只会影响Picamera2对它们的处理。
    通常我们会在预览窗口中显示主流。在某些情况下,最好是显示较低分辨率的图像(来自lores流)。我们可以用:
    from picamera2 import Picamera2
    picam2 = Picamera2()
    config = picam2.create_still_configuration(lores={"size": (320, 240)}, display="lores")
    

    这将请求一个全分辨率的主流,但随后也会显示一个QVGA图像流(即使应用程序没有显式地请求,主流也总是被定义的)。display参数可以取None值,这意味着没有图像将被呈现到预览窗口。事实上,这是create_still_configuration方法的默认选择。

  • encode - 这个名称(如果有的话)的流是要编码的,如果一个视频录制开始。这也是不会以任何方式影响相机图像,只会影响Picamera2对它们的处理。
    这类似于display参数,因为它命名了在开始视频录制时将被编码的流为main或lores。默认情况下,我们通常会对主流进行编码,但用户可以有一个应用程序,如果用户想要录制低分辨率的视频流的话:
    from picamera2 import Picamera2
    picam2 = Picamera2()
    config = picam2.create_video_configuration(main={"size": (2048, 1536)}, lores={"size": (320,
    240)}, encode="lores")
    

    这将允许录制QVGA流,同时允许同时捕获2048 × 1536静态图像。encode参数也可以取值None,这也是create_still_configuration的默认选择方法。

自动对焦功能

  • 仅适用于能自动对焦的摄像头

自动对焦控制和其他控制一样遵循同样的一般规则。只要使用libcamera的版本(如libcamera),这些控件就可以正常工作(由Raspberry Pi提供)正确地实现了libcamera发布的自动对焦API,以及附加的相机模块实际上有自动对焦(如树莓派相机模块3)。 不支持自动对焦的相机模块(包括早期的树莓派相机模块和HQ相机)这些选项不可用(在 Picamera2.camera_controls属性中),当尝试设置会显示失败。 以下为将相机设置为连续自动对焦模式:

from picamera2 import Picamera2
from libcamera import controls
import time
picam2 = Picamera2()
config = picam2.create_preview_configuration()
picam2.configure(config)
picam2.start(show_preview=True)
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})
time.sleep(2)

USB摄像头

Picamera2对USB摄像头(如网络摄像头)的支持有限。可以连接多个USB摄像头和CSI2摄像头(后者连接到Pi的专用摄像头端口),可以用通常的方式创建Picamera2对象,但是只有主流可用。支持的格式将取决于相机,但Picamera2原则上可以处理MJPEG和YUYV相机,在哪里相机支持两种格式,您可以通过请求格式“MJPEG”或“YUYV”来选择。 USB相机只能使用软件渲染的Qt预览窗口(preview . Qt)。没有硬件辅助支持渲染。MJPEG流可以直接渲染,但是YUYV需要安装OpenCV以便将图像转换为Qt可以理解的格式。这两种情况都将使用大量额外的CPU。capture_buffer方法将为你提供每帧的原始相机数据(来自MJPEG相机的JPEG比特流,或来自YUYV相机的未压缩YUYV图像)。如下:

from picamera2 import Picamera2, Preview
picam2 = Picamera2()
config = picam2.create_preview_configuration({"format": "MJPEG"})
picam2.configure(config)
picam2.start_preview(Preview.QT)
picam2.start()
jpeg_buffer = picam2.capture_buffer()

如果您有多个相机,需要发现要打开哪个摄像头,请使用Picamera2.global_camera_info方法。一般来说,用户应该假设其他功能,如视频录制,摄像头控制是支持的树莓派(Raspberry Pi)摄像头等等都是不可用的。USB摄像头也不支持热插拔, 当增加或减少摄像头时,应完全关闭并重新启动。