树莓派基于OPENCV处理视频后通过USB/TRRS模拟摄像头输出需求
树莓派USB模拟UVC摄像头+实时视频处理方案
一、配置树莓派USB Gadget UVC模式
树莓派的USB OTG端口可模拟为UVC设备,需先启用gadget功能:
- 编辑
/boot/config.txt,添加:dtoverlay=dwc2 - 编辑
/etc/modules,添加:dwc2 libcomposite - 重启树莓派:
sudo reboot - 创建UVC gadget配置脚本(命名为
uvc_gadget_setup.sh):
给脚本加执行权限:#!/bin/bash # 清理现有配置 sudo modprobe -r g_uvc sudo rm -rf /sys/kernel/config/usb_gadget/pi_uvc # 创建gadget目录 sudo mkdir -p /sys/kernel/config/usb_gadget/pi_uvc cd /sys/kernel/config/usb_gadget/pi_uvc # 设置设备ID参数 sudo echo 0x1d6b > idVendor # Linux Foundation sudo echo 0x0104 > idProduct # 复合设备ID sudo echo 0x0100 > bcdDevice sudo echo 0x0200 > bcdUSB # 设置设备描述字符串 sudo mkdir -p strings/0x409 sudo echo "Pi Virtual Cam" > strings/0x409/manufacturer sudo echo "UVC Video Gadget" > strings/0x409/product sudo echo "0123456789ABCDEF" > strings/0x409/serialnumber # 创建配置项 sudo mkdir -p configs/c.1/strings/0x409 sudo echo "UVC Configuration" > configs/c.1/strings/0x409/configuration sudo echo 250 > configs/c.1/MaxPower # 配置UVC视频参数(MJPG格式,640x480@30fps) sudo mkdir -p functions/uvc.usb0 sudo echo 640 > functions/uvc.usb0/streaming/mjpeg/width/value sudo echo 480 > functions/uvc.usb0/streaming/mjpeg/height/value sudo echo 333333 > functions/uvc.usb0/streaming/mjpeg/dwFrameInterval/value # 绑定功能到配置 sudo ln -s functions/uvc.usb0 configs/c.1/ # 绑定到USB控制器 sudo ls /sys/class/udc/ > UDCsudo chmod +x uvc_gadget_setup.sh,运行生效:sudo ./uvc_gadget_setup.sh
二、安装v4l2loopback桥接视频流
用v4l2loopback创建虚拟视频设备,用于承接处理后的视频:
- 安装依赖:
sudo apt update && sudo apt install v4l2loopback-dkms v4l-utils -y - 加载模块并创建虚拟设备:
sudo modprobe v4l2loopback video_nr=2 exclusive_caps=1exclusive_caps=1确保设备被识别为摄像头而非视频输出设备。
三、视频采集与处理代码(Python/OpenCV示例)
以下代码实现物理摄像头采集、自定义处理后写入虚拟设备:
import cv2 # 打开物理摄像头(默认/dev/video0,可根据实际调整) cap = cv2.VideoCapture(0) if not cap.isOpened(): print("无法打开物理摄像头") exit() # 获取摄像头基础参数 width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = int(cap.get(cv2.CAP_PROP_FPS)) # 打开虚拟设备,格式匹配MJPG fourcc = cv2.VideoWriter_fourcc(*'MJPG') out = cv2.VideoWriter('/dev/video2', fourcc, fps, (width, height)) if not out.isOpened(): print("无法打开虚拟摄像头设备") cap.release() exit() try: while True: ret, frame = cap.read() if not ret: print("读取帧失败") break # 自定义视频处理逻辑:示例为边缘检测 gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) processed_frame = cv2.Canny(gray_frame, 50, 150) # 转换为3通道BGR,适配虚拟设备的彩色输出要求 processed_frame = cv2.cvtColor(processed_frame, cv2.COLOR_GRAY2BGR) # 写入虚拟设备 out.write(processed_frame) # 按Q键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break finally: # 释放所有资源 cap.release() out.release() cv2.destroyAllWindows()
注:处理逻辑可自行替换(如人脸检测、滤镜等),需保证输出帧的尺寸、通道数与虚拟设备匹配。
四、桥接虚拟设备到UVC Gadget
用ffmpeg将虚拟设备的视频流推送到UVC gadget的视频节点:
ffmpeg -f v4l2 -i /dev/video2 -f v4l2 /dev/video3
可通过v4l2-ctl --list-devices查看UVC gadget对应的实际设备号,替换上述命令中的/dev/video3。
五、验证连接
将树莓派的USB OTG端口(如树莓派4的USB-C口,需单独供电,不要用该端口供电)通过USB线连接目标板,目标板会识别到名为Pi Virtual Cam的USB摄像头,采集到的即为树莓派处理后的视频流。
注意事项
- 树莓派性能有限,复杂处理逻辑需适当降低分辨率或帧率,避免卡顿。
- 若UVC gadget配置失败,可检查
/sys/class/udc/下的控制器名称,调整脚本中绑定步骤的参数。
内容的提问来源于stack exchange,提问作者Mike Arkl
相关产品推荐
相关产品推荐

