外观
UVC 摄像头
2025-09-22
本文将详细介绍如何通过 RT-Thread 操作系统使用 UVC(USB VIDEO Camera,USB 摄像头)模块,实现拍照 MJPEG. YUV 格式图片功能。该示例以 RK3506 平台的 OV5693 为基础,帮助用户掌握 UVC 模块的典型拍照应用流程。
UVC
OV5693 是 OmniVision(豪威科技)推出的一款高性能500万像素(5MP)CMOS 摄像头,本文示例采用得是USB 接口得 Camera,支持输出格式MJPEG,YUV, 支持自动对焦AF控制, 视场角为120度
UVC 拍照实验
本实验展示如何使用 UVC 拍摄一张YUV,MJPEG格式得图片保存在 SD 卡里。系统通过设置用户定义的回调函数,当 UVC 设置启动流得时候触发回调函数,在回调中打开创建好的YUV,MJPEG图片,将一帧图片数据保存在 SD 卡里,从而方便用户查看YUV,MJPEG图片
创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化设备树

固化 APP

核心示例代码
UVC 示例相关代码
rt_device_init(device): 初始化 UVC 设备rt_device_open(device, RT_DEVICE_FLAG_RDWR):以可读可写的方式打开 UVC 设备;rt_device_control(device, RT_UVC_CTRL_SET_CALLBACK, (void *)my_callback):设置 UVC 的回调函数rt_device_control(device, RT_UVC_CTRL_START_STREAM, &type):启动 UVC 取流rt_device_control(device, RT_UVC_CTRL_STOP_STREAM, NULL):停止 UVC 取流
- 初始化和操作 UVC
uvc_capture.c
static int uvc_capture(int argc, char *argv[])
{
uint8_t type;
struct rt_device *device = rt_device_find("uvc");
if (!device)
{
rt_kprintf("Can't find device uvc\n");
return (-RT_ERROR);
}
if (argc < 3)
{
rt_kprintf("please input correct command: usbh_uvc_start type to file_path\n");
rt_kprintf("type 0:yuyv, type 1:mjpeg\n");
return (-RT_ERROR);
}
type = atoi(argv[1]);
// 选择拍照yuyv还是mjpeg格式图片
if (type == 0)
{
rt_kprintf("uvc capture yuyv type picture\n");
}
else if (type == 1)
{
rt_kprintf("uvc capture mjpeg type picture\n");
}
else
{
rt_kprintf("uvc capture type is unsupport!\n");
return (-RT_ERROR);
}
// 拍照存储路径(检查路径有效性)
if (access(argv[2], F_OK) == 0) // F_OK检查文件是否存在
{
rt_kprintf("file path exist\n");
}
else
{
rt_kprintf("file path does not exist\n");
return (-RT_ERROR); // 路径无效
}
snprintf(file_path, sizeof(file_path), "%s", argv[2]);
// 回调函数指向用户定义的函数
frame_callback_t my_callback = my_function;
rt_sem_init(&sem_lock, "lock", 0, RT_IPC_FLAG_PRIO);
// 初始化UVC设备
rt_device_init(device);
rt_device_open(device, RT_DEVICE_FLAG_RDWR);
// 设置回调函数并启动UVC取流
rt_device_control(device, RT_UVC_CTRL_SET_CALLBACK, (void *)my_callback);
rt_device_control(device, RT_UVC_CTRL_START_STREAM, &type);
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
// 停止UVC取流
rt_device_control(device, RT_UVC_CTRL_STOP_STREAM, NULL);
return RT_EOK;
}- 回调函数保存 YUV/MPJEG 图片
uvc_capture.c
frame_callback_t my_function(struct usbh_videoframe *frame) {
int fd = -1;
flag = true;
if (frame->frame_format == 0 && flag) {
flag = false;
// 处理 YUV 格式
char *file = "output.yuv";
strncat(file_path, file, sizeof(file_path) - strlen(file_path) - 1);
fd = open(file_path, O_RDWR | O_CREAT); // 打开 output.yuv 文件
rt_kprintf("YUV data saved to %s\r\n", file_path);
} else if (frame->frame_format == 1 && flag) {
flag = false;
// 处理 MJPEG 格式
char *file = "output.jpg";
strncat(file_path, file, sizeof(file_path) - strlen(file_path) - 1);
fd = open(file_path, O_RDWR | O_CREAT); // 打开 output.jpg 文件
rt_kprintf("MJPEG data saved to %s\r\n", file_path);
}
if (!fd) {
rt_kprintf("failed to open file %s\r\n", file_path);
return RT_NULL;
}
rt_sem_release(&sem_lock);
rt_kprintf("frame buf:%p,frame_len:%d\r\n", frame->frame_buf, frame->frame_size);
write(fd, frame->frame_buf, frame->frame_size); // 把一帧图片数据写到文件里
close(fd);
}运行程序
连接开发板,在 RuiChing Studio IDE 中启动调试,
如果要抓取一帧 yuv 图片,保存在 SD 卡里,就在终端输入 uvc_capture 0 /sdmmc/ 命令,结果如下:
msh />uvc_capture 0 /sdmmc/
file path exist
[T/USB] open oflag = 3
[T/USB] uvc_contrl cmd = 0
[T/USB] uvc_control cmd = 1
[I/usb_video] Ep=81 Attr=05 Mps=1024 Interval=01 Mult=02
[I/usb_video] Open video and select formatidx:2, frameidx:2, altsetting:7
[I/USB] uvc mps: 3072
[I/USB] start uvc stream...
YUV data saved to /sdmmc/output.yuv
frame buf:0x0102caa0,frame_len:614400
[T/USB] uvc_control cmd = 2
[I/usb_video] close video device
msh />如果要抓取一帧 mjpeg 图片,保存在 SD 卡里,就在终端输入 uvc_capture 1 /sdmmc/ 命令,结果如下:
msh />uvc_capture 1 /sdmmc/
uvc capture mjpeg type picture
file path exist
[I/USB] open oflag = 3
[I/USB] uvc_control cmd = 0
[I/USB] uvc_control cmd = 1
[I/usb_video] Ep=81 Att=05 Mps=1024 Interval=01 Mult=02
[I/usb_video] Open video and select formatidx:1, frameidx:1, altsetting:7
[I/USB] uvc mps: 3072
[I/USB] start uvc stream...
MJPEG data saved to /sdmmc/output.jpg
frame buf:0x0162caa0,frame len:23072
[I/USB] uvc_control cmd = 2
[I/usb_video] close video device
[E/USB] uvc abort2
msh />