基于Raspberry 的 libcamera 使用

发布时间 2023-06-06 16:33:37作者: 小淼博客

1. libcamera and libcamera-apps工具简介

  • I. libcamera 是一款用来支持用户基于Linux 操作系统控制复杂相机的应用程序,用户可以通过libcamera直接操作树莓派芯片集成的GPU模块。
  • II. libcamera 开放了基于C++语言的应用程序接口用于配置相机并从相机获取图像的功能API,同时libcamera管理的图像缓冲buffer能够直接输入到图像编码器或者直接输出到显示模块中。
  • III. libcamera-app 是基于libcamera完成的相机控制例程,其代码设计主要是模拟基于博通专有GPU代码的传统堆栈的功能,具体提供的功能如下:
    • libcamera-hello: 输出从相机中获取的预览图像功能
    • libcamera-jpeg: 通过相机获取高分辨率的JPEG图像
    • libcamera-still: 一个功能类似于raspistill的相机视频获取程序
    • libcamera-vid: 视频捕获程序
    • libcamera-raw: 直接从相机中获取未压缩的原始RAW图像程序
    • libcamera-detect: 这个程序默认是不编译的,如果用户在树莓派上安装了TensorFlow Lite软件则可以使用此程序进行目标检测图像捕获。
  • IV. libcamera工具基于树莓派提供的图像pipeline处理流程,能够完成ISP图像预处理功能,所有的功能均在树莓派的ARM核心下完成,包括的功能如下:
    • AEC/AGC (Auto Exposure/Gain Control)
    • AWB (Auto White Balance)
    • ALSC (Auto Lens Shading Correction)
  • V. libcamera能够支持的相机:OV5647 ,IMX219 ,IMX477 ,IMX708 ,IMX290, IMX327, OV9281, IMX378
  • VI. Raspberry支持了用户可编辑的 IQ Tunning File,从而能够让用户进行图像预处理ISP功能的调试优化,具体参考 官方 Tuning Guide for the Raspberry Pi cameras and libcamera树莓派相机Tuning实战

2. libcamera 使用测试

I. libcamera-hello 一般功能测试

libcamera-hello # 获取相机设备并展示5s的实时视频
libcamera-hello -t 0 # 一直获取相机设备并展示,永不停止(使用Ctrl+C终止)
libcamera-hello --tuning-file /usr/share/libcamera/ipa/raspberrypi/imx219_noir.json -t 0 # 使用imx219无红外滤波片模组的tuning文件进行ISP预处理
libcamera-hello --info-text "red gain %rg, blue gain %bg, Lens Focus %focus" # 直接获取Camera当前红色通道以及蓝色通道的增益信息,相机镜头焦距(仅支持HQ Camera)
libcamera-hello --roi 0.25,0.25,0.5,0.5 # --roi Select a crop (region of interest) from the camera <x,y,w,h> 设置ROI起点和宽度&高度
libcamera-still --hdr -o hdr.jpg # 开启相机的HDR模式
  • 相机信息的查看 Tips: --info-text
    Directive Substitution
    %frame The sequence number of the frame
    %fps The instantaneous frame rate
    %exp The shutter speed used to capture the image, in microseconds
    %ag The analogue gain applied to the image in the sensor
    %dg The digital gain applied to the image by the ISP
    %rg The gain applied to the red component of each pixel
    %bg The gain applied to the blue component of each pixel
    %focus The focus metric for the image, where a larger value implies a sharper image
    %lp The current lens position in dioptres (1 / distance in metres).
    %afstate The autofocus algorithm state (one of idle, scanning, focused or failed).

II. libcamera-jpeg 图像采集测试

libcamera-jpeg -o test.jpg # 获取一张全分辨率的JPG图片
libcamera-jpeg -o test.jpg -t 2000 --width 640 --height 480 # 预览2000ms后在拍照,拍摄VGA照片分辨率为 640*480
libcamera-jpeg -o test.jpg -t 2000 --shutter 20000 --gain 1.5 # 预览2000ms后在拍照,拍摄曝光快门参数为 20ms,增益为1.5x(需要注意的是,当增益在CMOS模拟增益范围内时,该参数控制的是模拟增益,当增益超出模拟增益最大值时,启用数字增益)
libcamera-jpeg --ev -0.5 -o darker.jpg # 配置AEC/AGC 算法参数控制曝光补偿,能够通过设置该参数使得图片明暗变化
libcamera-jpeg --ev 0 -o normal.jpg
libcamera-jpeg --ev 0.5 -o brighter.jpg
  • 关于数字增益Tips:
    • 数字增益实际上是ISP(image Signal Processor)的功能,而不是Sensor本身的功能,数字增益一般都为1除非以下特殊情况
    • 使用 --gain 参数项配置的增益值超出了Sensor自身能够提供的模拟增益最大值的情况,数字增益ISP提供超出部分的增益功能
    • 色彩增益也是数字增益的功能之一,对除了绿色通道以外的其他两个通道 RB 通道进行 \(1 / min(red_{gain}, blue_{gain})\) 增益,从而归一化色彩信息
    • 当 AEC/AGC 参数发生变化时,数字增益将会发生变化以保证波动的平滑

III. libcamera-still 图像获取测试

libcamera-still -o test.jpg # 获取一张全分辨率jpg图像
libcamera-still -e png -o test.png # 编码功能:输出PNG格式图片 -e ~ --encoding,如果未设定图片输出格式,将按照文件名称自动确认
libcamera-still -e bmp -o test.bmp # 编码功能:输出bmp格式图片
libcamera-still -e rgb -o test.data # 二进制数据直接输出功能:输出rgb RAW图
libcamera-still -e yuv420 -o test.data # 二进制数据直接输出功能:输出 yuv420 RAW图
# RAW图可以被保存为jpg,dng格式,而其存储格式为 DNG(Adobe Digital Negative) 格式,能够兼容多种软件: dcraw or RawTherapee
libcamera-still -r -o test.jpg # Raw Image Capture 相机原始RAW图像捕获输出 libcamera-still --raw -o test.jpg
libcamera-still -o long_exposure.jpg --shutter 100000000 --gain 1 --awbgains 1,1 --immediate # 100s超长时间曝光,在使用超长时曝光功能之前,需要停止使能 AEC/AGC 和 AWB 的功能,这是由于这两个功能将会强制等待若干帧图像数据
  • DNG file Tips
    • DNG文件信息中包括了图像捕获过程中的原始信息,包括了黑点平数据,白平衡信息,CCM颜色矫正矩阵信息等ISP需要使用的参数,这样将大大方便后期人员手动进行RAW图处理流程的实施
    • 使用 exiftool 工具读取 DNG 文件中的原始数据信息如下:
    File Name                       : test.dng
    Directory                       : .
    File Size                       : 24 MB
    File Modification Date/Time     : 2021:08:17 16:36:18+01:00
    File Access Date/Time           : 2021:08:17 16:36:18+01:00
    File Inode Change Date/Time     : 2021:08:17 16:36:18+01:00
    File Permissions                : rw-r--r--
    File Type                       : DNG
    File Type Extension             : dng
    MIME Type                       : image/x-adobe-dng
    Exif Byte Order                 : Little-endian (Intel, II)
    Make                            : Raspberry Pi
    Camera Model Name               : /base/soc/i2c0mux/i2c@1/imx477@1a
    Orientation                     : Horizontal (normal)
    Software                        : libcamera-still
    Subfile Type                    : Full-resolution Image
    Image Width                     : 4056
    Image Height                    : 3040
    Bits Per Sample                 : 16
    Compression                     : Uncompressed
    Photometric Interpretation      : Color Filter Array
    Samples Per Pixel               : 1
    Planar Configuration            : Chunky
    CFA Repeat Pattern Dim          : 2 2
    CFA Pattern 2                   : 2 1 1 0
    Black Level Repeat Dim          : 2 2
    Black Level                     : 256 256 256 256
    White Level                     : 4095
    DNG Version                     : 1.1.0.0
    DNG Backward Version            : 1.0.0.0
    Unique Camera Model             : /base/soc/i2c0mux/i2c@1/imx477@1a
    Color Matrix 1                  : 0.8545269369 -0.2382823821 -0.09044229197 -0.1890484985 1.063961506 0.1062747385 -0.01334283455 0.1440163847 0.2593136724
    As Shot Neutral                 : 0.4754476844 1 0.413686484
    Calibration Illuminant 1        : D65
    Strip Offsets                   : 0
    Strip Byte Counts               : 0
    Exposure Time                   : 1/20
    ISO                             : 400
    CFA Pattern                     : [Blue,Green][Green,Red]
    Image Size                      : 4056x3040
    Megapixels                      : 12.3
    Shutter Speed                   : 1/20
    

IV. libcamera-vid 视频功能测试

  1. 基本功能测试
    libcamera-vid -t 10000 -o test.h264 # 保存10s的h264格式视频,在不指定格式的情况下,vid默认保存格式也为 h264,该保存的视频可以使用 vlc来播放
    vlc test.h264 # 播放视频
    libcamera-vid -o test.h264 --save-pts timestamps.txt # 输出当前视频对应的 timestamps 时间间隔文件
    mkvmerge -o test.mkv --timecodes 0:timestamps.txt test.h264 # 使用 mkvmerge 工具,通过 timestamps 文件和原始视频转码为其他格式视频数据
    libcamera-vid -t 10000 --codec mjpeg -o test.mjpeg # 视频录制的保存格式设置功能 mjpeg 格式
    libcamera-vid -t 10000 --codec yuv420 -o test.data # 视频录制的保存格式设置功能 yuv420 格式
    libcamera-vid -t 10000 --codec mjpeg --segment 1 -o test%05d.jpeg # 录制 mjpeg 格式的视频,并将该视频按照 1ms 的格式分割为图片保存
    
  2. 网络流功能测试
    # UDP 方式
    libcamera-vid -t 0 --inline -o udp://<ip-addr>:<port> # Server视频流服务端,ip-addr:port 为客户端IP地址:端口号
    vlc udp://@:<port> :demux=h264 # 客户端获取Server端视频流数据
    # TCP 方式,30FPS条件下延时较低,树莓派将等待客户端的链接,然后才启动视频流服务
    libcamera-vid -t 0 --inline --listen -o tcp://0.0.0.0:<port> # Server视频流服务端,ip-addr:port 为客户端IP地址:端口号
    vlc tcp/h264://<ip-addr-of-server>:<port> # 客户端获取Server端视频流数据
    # RTSP 网络广播视频流方式
    libcamera-vid -t 0 --inline -o - | cvlc stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/stream1}' :demux=h264 # Server视频流服务端
    vlc rtsp://<ip-addr-of-server>:8554/stream1 # 客户端获取Server端视频流数据
    
  3. 高帧率获取图像
    • 需要配置 H.264 的功能版本为 --level 4.2
    • ISP软件色彩去噪功能需要关闭,提高CPU能力 --denoise cdn_off
    • 对于超出100FPS的应用需求,需要 -n 选项关闭CPU一些辅助的不必要的资源消耗,从而减少丢帧的情况
    • 需要在 /boot/config.txt 文件中设置 force_turbo=1 功能,保证CPU主频不被限制
    • 配置ISP处理的图像像素尺寸小于等于 --width 1280 --height 720
    • 通过 /boot/config.txt 文件中配置GPU超频功能 gpu_freq=550
    • 1280x720 120fps 视频编码命令样例: libcamera-vid --level 4.2 --framerate 120 --width 1280 --height 720 --save-pts timestamp.pts -o video.264 -t 10000 --denoise cdn_off -n

V. libcamera-raw RAW图功能测试

libcamera-raw -t 2000 -o test.raw # 保存原始的RAW图像到当前目录下,保存过程中不会展示预览视频窗口,运行指令打印了当前保存RAW图像的像素尺寸和Bayer的格式,从而方便用户解析RAW数据
libcamera-raw -t 2000 --segment 1 -o test%05d.raw # 2s时间的图像切片1ms保存一张,在存储条件好的条件下, 例如SSD存储器时,能够在12MP的高清图像以10FPS保存下来
libcamera-raw -t 5000 --width 4056 --height 3040 -o test.raw --framerate 8 # 配置图像保存时间,图像像素宽度&高度,保存的帧率

3. Post-Processing 图像数据流处理

     post-processing 作为一种后处理框架,能够有效地从Camera中获取的数据输送到用户定制化的 图像处理/神经网络 算法流程当中,而具体完成算法的流程及算法当中涉及到的参数都通过 JSON 文件进行了传递,用户可以脱离图像处理算法本身,从而更为便捷地完成图像处理的功能。

a) 将图像进行色彩亮度翻转功能

libcamera-hello --post-process-file /path/to/negate.json # 其中negate.json为图像色彩翻转算法的JSON文件

使用的 JSON 文件内容,由于色彩翻转算法不需要任何的处理参数,所以仅仅需要 negate 即可。

{
    "negate":
    {
    }
}

b)HDR 高动态功能

HDR算法中包括了HDR (high dynamic range) imaging 和 DRC (dynamic range compression)两种算法,HDR 法实际上是基于多帧图像的 DRC 算法。
算法的基本流程如下:

  • 通过边缘保持的平滑滤波器(edge-preserving smoothing filter)获得一个低通图像(LP).
  • 将原始图像与低通图像进行差值获得高通图像(HP).
  • 使用全局色调图除了低通图像数据 LP,并将处理后的结果加在HP数据上,从而保证最终的图像保留了显著的特征

HDR模块控制的参数如下表所示:
image

使用命令
libcamera-still -o test.jpg --post-process-file drc.json

上述处理流程在树莓派4上运行的时间大约为4s@12MP,

{
    "hdr" :
    {
	"num_frames" : 1,
	"lp_filter_strength" : 0.2,
	"lp_filter_threshold" : [ 0, 10.0 , 2048, 205.0, 4095, 205.0 ],
	"global_tonemap_points" :
	[
	    { "q": 0.1, "width": 0.05, "target": 0.15, "max_up": 1.5, "max_down": 0.7 },
	    { "q": 0.5, "width": 0.05, "target": 0.5, "max_up": 1.5, "max_down": 0.7 },
	    { "q": 0.8, "width": 0.05, "target": 0.8, "max_up": 1.5, "max_down": 0.7 }
	],
	"global_tonemap_strength" : 1.0,
	"local_pos_strength" : [ 0, 6.0, 1024, 2.0, 4095, 2.0 ],
	"local_neg_strength" : [ 0, 4.0, 1024, 1.5, 4095, 1.5 ],
	"local_tonemap_strength" : 1.0,
	"local_colour_scale" : 0.9
    }
}

c) 复合的多流程 post-processing 功能

libcamera-hello --post-process-file /path/to/multiple.json # 其中multiple.json为图像Sobel边缘提取 + 色彩翻转算法的JSON文件

multiple.json文件中包括了第一位置的 Sobel 边缘检测算子,其算子的核矩阵大小为 5x5,然后第二步进行了 图像色彩翻转功能

{
    "sobel_cv":
    {
        "ksize": 5
    },
    "negate":
    {
    }
}

d) Opencv Post-Processing

  1. sobel_cv

    {
    	"sobel_cv":
    	{
    		"ksize": 5
    	}
    }
    
  2. face_detect_cv

    {
    	"face_detect_cv":
    	{
    		"cascade_name" : "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml",
    		"scaling_factor" : 1.1,
    		"min_neighbors" : 2,
    		"min_size" : 32,
    		"max_size" : 256,
    		"refresh_rate" : 1,
    		"draw_features" : 1
    	}
    }
    
  3. annotate_cv

    {
    	"annotate_cv" :
    	{
    	"text" : "Frame %frame exp %exp ag %ag dg %dg",
    	"fg" : 255,
    	"bg" : 0,
    	"scale" : 1.0,
    	"thickness" : 2,
    	"alpha" : 0.3
    	}
    }
    

e) Tensorflow Lite Post-Processing

在使用树莓派平台的TensorFlow Lite功能之前,需要对libcamera进行重新编译以使能该功能,下面距离介绍基于TenlsorFlow的中间神经网络处理流程。

  1. pose_estimation_tf
    姿态估计识别框架,使用了 Google MobileNet v1 model posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite 下载
    {
    	"pose_estimation_tf":
    	{
    		"refresh_rate" : 5,
    		"model_file" : "posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite"
    	},
    	"plot_pose_cv" :
    	{
    	"confidence_threshold" : -0.5
    	}
    }
    
    基本命令:libcamera-hello --post-process-file pose_estimation_tf.json --lores-width 258 --lores-height 258
    运行结果:

其他图像中间处理算法 JSON 参考: CVAlgJSONExample.json

Reference

  1. 树莓派RPi FPC Camera (B)教程
  2. 树莓派官方相机使用教程 Camera software