记录一次树莓派在较新版本官方系统使用CSI摄像头时出现的问题及解决办法

最近在试图使用树莓派4B基于OpenCV做人脸识别门禁项目,发现树莓派的新版本系统对于摄像头驱动有不少改动(改用了libcamera),折腾了半天,记录一下遇到的问题和解决方案

注:在系统安装过程中发现最新版本系统是基于debian 12,代号为bookworm,并且相对于旧系统少了一小部分功能。暂不知晓换源是否需要考虑代号问题(因为换源链接中包含有代号,网络上的旧教程用的都是以前的代号)

刚开始我安装了最新的树莓派官方系统,在按照网络上各位前辈的教学进行配置时发现raspi-config内没有camera选项,加上一些对于新版本小功能缺失的不满故用官方烧录软件重新安装了烧录软件内最老的legacy系统(基于debian 11,也并没有特别老。虽然事实证明这个版本也已经删除了旧版本的摄像头相关驱动和库,改用libcamera作为官方的摄像头自带命令)

一、libcamera-hello命令出现“no cameras available”报错

在烧录了官方legacy系统后我在raspi-config内找到了类似的camera选项(enable camera (legacy)),并启用了它。(推测如果要使用libcamera则此选项不应该被启用,不过使用opencv需要启用他)使用以前教程的命令(如rpicam-hello)无法调用摄像头,发现官方已经改用libcamera驱动,应该使用libcamera-hello进行测试。然而出现了“error: XDG_RUNTIME_DIR not set in the environment.”“ERROR: *** no cameras available”等报错。(在最新系统使用此命令未出现报错)使用sudo vcgencmd get_camera指令能够得到:

supported=1 detected=1, libcamera interfaces=0

说明摄像头是成功连接的。经过寻找后找到树莓派论坛中一个英文帖子(原帖链接),提及boot/config.txt相关问题。使用指令打开文档比对

sudo nano  /boot/config.txt

我原先的config.txt中有此内容:

# Automatically load overlays for detected cameras
start_x=1

似乎是因为这个命令会强制使用旧驱动,而非自动检测摄像头。于是将其改为:

# Automatically load overlays for detected cameras
#start_x=1
camera_auto_detect=1

再次执行libcamera-hello,摄像头正常运行。推测就是因为在config中开启了legacy camera相关内容导致的。有趣的是,现在执行sudo vcgencmd get_camera会得到结果

supported=0 detected=0, libcamera interfaces=0

不过libcamera-hello能正常使用。不知道是不是因为这条命令也是针对于旧驱动的。但是我当时没有想到,如果要使用opencv,则不能这样修改,反而需要原来那个start_x=1。后文会提及。

二、libcamera-jpeg命令出现“failed to allocate capture buffers”

在执行libcamera-jpeg命令(libcamera-jpeg -o test.jpg)进行拍照测试时,最后一行出现了以下报错

ERROR V4L2 v4l2_videodevice.cpp:1241 /dev/video14[18:cap]: Unable to request 1 buffers: Cannot allocate memory ERROR: 
*** failed to allocate capture buffers ***

在网络上查询到帖子,称“您可能希望减少分配给 GPU 的内存。当您使用 libcamera 应用程序时,它们会使用 CPU 的内存,而不是 GPU,因此,如果为 GPU 提供过多内存,则会限制分配相机缓冲区的能力。”我想到之前我给GPU分配的内存是512MB,可能是因为大了,所以进入raspi-config修改GPU内存。(原帖链接

第一种方法:图形化界面里点左下角logo打开菜单》首选项》Raspberry Pi Configuration,找到GPU Memory修改。

第二种方法:终端中进入raspi-config,找到GPM Memory(新系统在Interface Options里面,似乎与旧系统位置有差别)修改(记得重启树莓派)

我的树莓派4B为4G内存版本,想着给GPU内存多分配点应该还是够用,故我将GPU内存512MB修改为256,再次运行libcamera-jpeg命令,成功执行无报错。

三、在OpenCV中调用出错

之后在使用OpenCV时发现使用.read   imshow等指令时发现会报错,返回的值为None。查阅资料发现OpenCV似乎需要旧的驱动,在重新去config开启摄像头的legacy后成功解决(原理同上文重新改为start_x=1)。树莓派官方真有你的......看来要想使用opencv就得抛弃libcamera。折腾了那么久最终还是绕回来了。

本文写于2023.11.26

### 解决方案概述 对于 Raspberry Pi 4B 上通过 CSI 摄像头接口使用 OpenCV 进行图像捕获和处理的问题,存在多种方法来实现这一目标。主要依赖于软件配置以及特定库的支持。 #### 方法一:基于 libcamera 的解决方案 为了使树莓派原装CSI摄像头IMX219能够被OpenCV正常读取,在较新的操作系统版本中推荐采用libcamera作为底层支持工具[^1]。这涉及到更新系统的包管理器并安装必要的组件: ```bash sudo apt-get update && sudo apt-get upgrade -y sudo apt install python3-opencv libatlas-base-dev libhdf5-dev libjasper-dev libqtgui4 libqt4-test ``` 接着确保已启用Camera模块,并重启设备让更改生效。之后可以通过Python脚本利用`cv2.VideoCapture()`函数指定视频源参数为`'libcamerasrc ! video/x-raw,format=BGR,width=640,height=480,framerate=30/1 ! appsink'`(GStreamer管道字符串),从而完成对CSI相机的数据流访问。 #### 方法二:UV4L 驱动方式 另一种常见做法是在Raspberry Pi 4B (32位系统)上安装uv4l驱动程序以解决OpenCV无法获取CSI摄像头图像的情况[^2]。此过程同样需要先确认硬件连接无误且基本功能可用(比如能执行命令行拍照)。具体操作如下所示: 1. 安装最新版的uv4l及相关插件; 2. 修改配置文件使得服务开机自启; 3. 编写简单的测试代码验证效果。 下面给出一段用于捕捉静态画面的例子: ```python import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret or cv2.waitKey(1)&0xFF==ord('q'): break # 显示实预览窗口 cv2.imshow('frame', frame) key=cv2.waitKey(1) if key & 0xFF == ord('c'): # 当按'C'键保存当前帧至/home/pi/Pictures/ img_name="/home/pi/Pictures/your_image_{:04d}.jpg".format(int(time.time())) cv2.imwrite(img_name,frame) print(f"Image saved as {img_name}") cap.release() cv2.destroyAllWindows() ``` 上述代码片段展示了如何创建一个循环不断抓拍新帧直至用户主动终止程序运行或者按下'C'按键触发截图动作[^3]。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值