首页 > 原创文章 > 技术应用 > 查看文章

如何在Linux上开发Webcam摄像程序?

所属分类:技术应用 来源: 丁老师原创 更新时间:2025-07-25 08:37 浏览: 2561 IP属地: 深圳

有一个需求,需要在Linux客户机上,实现调用摄像头(webcam)来捕捉图像。经过研究,可以使用V4L(Video for Linux2)来实现,一个在Linux下通用的视频驱动框架,支持绝大多数的摄像头(外置和内置摄像头都支持),目前有很多基于linux的网络摄像头和图像采集卡都在使用此框架程序。

如果需要更高级的应用开发,可以选择使用Libcamera,基于V4L开发,是作为V4L的上层扩展,解决了V4L接口的复杂性问题,大幅降低了开发难度,为开发者提供更高级、更建议的摄像头开发框架。

V4L
定位:内核驱动接口(用户空间通过ioctl调用)。
架构层级:底层接口,可以直接操作硬件。
目标场景:高性能、低延迟的应用场景(如工业摄像头、实时处理)
依赖关系:仅需内核支持(大部分Linux系统都已内置)

用法范例

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define DEVICE "/dev/video0"
#define WIDTH 640
#define HEIGHT 480
#define FILENAME "capture.jpg"

int main(){
int fd=open(DEVICE, O_RDWR);
if(fd<0){
    perror("无法打开设备");
    return -1;
}

//查询设备能力
struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
    perror("查询设备能力失败");
    close(fd);
    return -1;
}

//设置视频格式
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = WIDTH;
fmt.fmt.pix.height = HEIGHT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; // 直接捕获JPEG格式
if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {
    perror("设置格式失败");
    close(fd);
    return -1;
}

//请求缓冲区
struct v4l2_requestbuffers req;
memset(&req, 0, sizeof(req));
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) {
    perror("请求缓冲区失败");
    close(fd);
    return -1;
}

//查询缓冲区并映射
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {
    perror("查询缓冲区失败");
    close(fd);
    return -1;
}

unsigned char* buffer_start = mmap(NULL, buf.length, 
 PROT_READ | PROT_WRITE, 
 MAP_SHARED, fd, buf.offset);
if(buffer_start == MAP_FAILED){
    perror("内存映射失败");
    close(fd);
    return -1;
}

//将缓冲区放入队列
if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) {
    perror("将缓冲区放入队列失败");
    munmap(buffer_start, buf.length);
    close(fd);
    return -1;
}

//开始捕获
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) {
    perror("开始捕获失败");
    munmap(buffer_start, buf.length);
    close(fd);
    return -1;
}

//等待帧就绪(这里简化处理,实际应用中可能需要循环等待)
fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {0};
tv.tv_sec = 2;
int r = select(fd + 1, &fds, NULL, NULL, &tv);
if (r < 0) {
    perror("select出错");
    munmap(buffer_start, buf.length);
    close(fd);
    return -1;
}
else if (r == 0) {
    fprintf(stderr, "捕获超时\n");
    munmap(buffer_start, buf.length);
    close(fd);
    return -1;
}

//从队列中取出缓冲区
if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) {
    perror("从队列中取出缓冲区失败");
    munmap(buffer_start, buf.length);
    close(fd);
    return -1;
}

//保存图像到文件
FILE* file = fopen(FILENAME, "wb");
if (!file) {
    perror("无法创建文件");
    munmap(buffer_start, buf.length);
    close(fd);
    return -1;
}
fwrite(buffer_start, buf.bytesused, 1, file);
fclose(file);

//停止捕获并释放资源
if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) {
    perror("停止捕获失败");
}
munmap(buffer_start, buf.length);
close(fd);

printf("图像已保存为: %s\n", FILENAME);
    return 0;
}


Libcamera
定位:基于V4L的更高级框架。
架构层级:高层扩展,提供统一的API和设备管理
目标场景:通用场景(如Linxu桌面应用、APP应用)
依赖关系:需要额外安装libcamera库和相关工具

用法范例

import time
from picamera2 import Picamera2

picam2 = Picamera2()
config = picam2.create_still_configuration(main={"size": (1920, 1080)})
picam2.configure(config)

picam2.start()
#等待相机稳定
time.sleep(2)
picam2.capture_file("image.jpg")
picam2.stop()

相关文章

phpMyAdmin导入sql文件提示500...

phpmyadmin使用正常,但是在sql文件时,提示500 internal Server error/nginx,查看了下nginx的日志,提示"open() "/usr/local/nginx/client_b...

OpenClaw(原Clawdbot/Mol...

在上一篇文章中,我们对OpenClaw进行了介绍《OpenClaw(原Clawdbot/Moltbot)是什么?能实现什么功能?》,在本篇文章中,我们将就如何安装OpenClaw,对OpenClaw的具体安装方法进行说明。OpenCla...

jquery tablesorter fil...

在使用前端jquery插件,tablesorter做表格排序和搜索时,遇到了一个问题,就是已经加载了jquery.tablesorter.js和jquery.tablesorter.widgets.js,但是在表格中的input输入关键...

网站/小程序如何结合AI大模型实现自动识别简...

最近有客户提出需求,要开发一个智能人才招聘系统,包含PC端网站、微信小程序、手机APP,想实现的功能是求职者登录注册后,上传自己的PDF简历,系统就能自动帮他匹配关联和推荐的职位。求助丁老师,这种系统该怎么实现,原理和步骤是什么呢?今天...

推荐文章

AI工具大全:好用的AI工具推荐(持续更新中...

这几年AI技术的发展已经达到新的高度,从提高个人生产力到企业操作效率的各个方面,AI都扮演着不可或缺的角色。无论是进行语言交流、内容创作、或是任务管理,都有相应的AI工具可以帮助我们更加轻松地完成工作。以下是丁老师觉得不错的AI工具推荐,希...

制作抖音小程序所需要的资料以及费用是多少?

开发抖音小程序所需资料及费用概览随着短视频平台抖音(TikTok)在全球范围内的迅速崛起,越来越多的企业和个人开始意识到在抖音平台上开发小程序的重要性。抖音小程序不仅可以增强品牌曝光率,还能为用户提供更加便捷的服务体验。那么问题来了,开发一...

国产信创项目操作系统要求用什么?web中间件...

从事技术开发的同学都知道,不管是做网站也好,开发各种业务系统也好,目前大多数企业部署的web环境是-操作系统:Linux,数据库:Mysql/MariaDB/PostgreSQL/MongoDB,Web容器:Nginx/Tomcat/Apa...

APP和小程序如何集成AI实现机器人客服?

有同学咨询丁老师,他们公司的小程序和APP,是属于C端的客户服务类APP,提供会员注册、下单、发货、订单查询、业务办理进度查看等模块。其中有一个功能是在线咨询,之前是对接的人工在线客服坐席咨询,在用户量大的时候,峰值可能同时需要5-8个客服...