如何通过PiCamera2获取树莓派HQ摄像头的标准YUV格式数组?
如何用PiCamera2在树莓派3B+Bullseye上捕获正确规格的YUV图像(适配ArduCam HQ用于植被分析)
一、解决YUV格式与分辨率匹配问题
你当前得到的(4560, 4096)数组是YUV420平面格式的原始缓冲区(Y平面+UV交错平面,总尺寸为宽×(高×1.5)),并非期望的3通道交错格式。按以下步骤配置与解析:
1. 指定原生分辨率与YUV格式
ArduCam HQ摄像头原生分辨率为4056×3040,需在PiCamera2配置中锁定该参数并指定YUV格式,示例代码:
from picamera2 import Picamera2 import numpy as np picam2 = Picamera2() # 创建静态捕获配置,指定分辨率与YUV420格式 config = picam2.create_still_configuration(main={"size": (4056, 3040), "format": "YUV420"}) picam2.configure(config) picam2.start() buffer = picam2.capture_buffer() picam2.stop() # 解析YUV420平面数据为3通道数组 # Y平面:4056×3040;U/V平面:各为2028×1520(Y尺寸的1/4) y = buffer[:4056*3040].reshape((3040, 4056)) u = buffer[4056*3040 : 4056*3040 + (4056//2)*(3040//2)].reshape((3040//2, 4056//2)) v = buffer[4056*3040 + (4056//2)*(3040//2) : ].reshape((3040//2, 4056//2)) # 将U/V上采样至Y的尺寸,拼接为3通道YUV数组 u_up = np.repeat(np.repeat(u, 2, axis=0), 2, axis=1) v_up = np.repeat(np.repeat(v, 2, axis=0), 2, axis=1) yuv_3channel = np.stack((y, u_up, v_up), axis=-1) # 此时yuv_3channel形状为(3040, 4056, 3),符合需求
2. 消除图像伪影
伪影通常由格式解析错误或自动参数干扰导致:
- 确保严格按上述方式解析平面YUV数据,避免将原始缓冲区直接当成单通道数组处理;
- 关闭自动曝光/白平衡,固定参数以适配植被分析需求:
# 在configure之后、start之前添加控制参数 picam2.set_controls({ "ExposureTime": 10000, # 单位微秒,根据实际光照调整 "AnalogueGain": 1.0, "AwbEnable": False, "ColourGains": (1.0, 1.0) # 固定白平衡增益 })
二、Legacy模式picamera报错的处理
Bullseye默认禁用legacy摄像头栈,启用步骤:
- 运行
sudo raspi-config,进入Interface Options -> Legacy Camera选择启用; - 重启树莓派;
- 安装picamera库:
pip install picamera
注意:部分ArduCam型号在legacy模式下需修改/boot/config.txt添加对应驱动overlay(如dtoverlay=arducam),但更推荐使用PiCamera2以避免兼容问题。
三、适配IR-cut与近红外拍摄的额外建议
用于植被分析时,需切换IR-cut滤镜:
- 若ArduCam支持软件控制,可通过GPIO切换(引脚参考设备说明书):
import RPi.GPIO as GPIO IR_CUT_PIN = 17 # 示例引脚,根据实际调整 GPIO.setmode(GPIO.BCM) GPIO.setup(IR_CUT_PIN, GPIO.OUT) # 切换至红外模式(关闭IR-cut) GPIO.output(IR_CUT_PIN, GPIO.HIGH) # 切换至可见光模式(打开IR-cut) GPIO.output(IR_CUT_PIN, GPIO.LOW)
- 拍摄近红外图像时,建议使用单色格式(配置
format='SBGGR10_CSI2P'),直接获取全波段传感器数据,更适合植被光谱分析。
内容的提问来源于stack exchange,提问作者saltysaguaro
相关产品推荐
相关产品推荐

