用Qt来加载USB摄像头解码,主要就三种方案,一种是Qt自带的,一种是ffmpeg来处理,一种是v4l2框架,每种方案都各自有优缺点和对应的应用场景,比如Qt自带的就非常适合windows下的只需要显示摄像头的场景,代码简单Qt内置使用方便,如果是需要拿到每张图片自己还要做分析处理比如人脸识别啥的,用ffmpeg是最好的,速度快资源占用低,可以自己GPU绘制,爽得很,如果是嵌入式linux的话,那用v4l2框架处理是最适合的,原生的通用api框架。
QCamera方案处理流程:
1. 实例化QCamera对象,绑定stateChanged信号用于调整尺寸大小。

2. 实例化QCameraViewfinder画布,将QCamera对象设置画布。默认采用类似句柄的形式显示画面,被系统接管绘制。
3. 实例化QCameraImageCapture对象用来抓图,如果有需要的话。
## 二、功能特点1. 同时支持windows、linux、嵌入式linux上的USB摄像头实时采集。
2. 支持多路USB摄像头多线程实时采集。
3. 在嵌入式linux设备上,自动查找USB设备文件并加载。
4. 可手动设置设备文件名称,手动设置后按照手动设置的设备文件加载。
5. 在嵌入式linux设备上支持人脸识别接口,实时绘制人脸框。
6. 具有打开、暂停、继续、关闭、截图等常规功能。
7. 可设置两路OSD标签,分别设置文本、颜色、字号、位置等。
8. 可作为视频监控系统使用。
## 三、效果图## 四、相关站点
1. 国内站点:[https://gitee.com/feiyangqingyun/QWidgetDemo](https://gitee.com/feiyangqingyun/QWidgetDemo)
2. 国际站点:[https://github.com/feiyangqingyun/QWidgetDemo](https://github.com/feiyangqingyun/QWidgetDemo)
3. 个人主页:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun)
4. 知乎主页:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/)
5. 体验地址:[https://blog.csdn.net/feiyangqingyun/article/details/97565652](https://blog.csdn.net/feiyangqingyun/article/details/97565652)
## 五、核心代码//widget版本static void getCameraInfo(QStringList &deviceNames, QStringList &descriptions){#ifndef __arm__#if (QT_VERSION > QT_VERSION_CHECK(5,5,0)) deviceNames.clear(); descriptions.clear(); QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); if (cameras.count() == 0) { qDebug() << TIMEMS << "not find USBCamera"; } else { foreach (QCameraInfo camera, cameras) { deviceNames << camera.deviceName(); descriptions << camera.description(); } }#endif#endif}void CameraThread::stateChanged(){#ifdef __arm__#else#if (QT_VERSION > QT_VERSION_CHECK(5,5,0)) if (camera->state() == QCamera::ActiveState) { //输出当前设备支持的分辨率 QList<QSize> sizes = camera->supportedViewfinderResolutions(); emit resolutions(sizes); //重新设置分辨率 QCameraViewfinderSettings set; set.setResolution(cameraWidth, cameraHeight); camera->setViewfinderSettings(set); }#endif#endif}bool CameraThread::init(){#ifdef __arm__ #else#if (QT_VERSION > QT_VERSION_CHECK(5,5,0)) QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); if (cameras.count() == 0) { qDebug() << TIMEMS << "not find USBCamera"; return false; } else { QWidget frm = (QWidget )parent(); camera = new QCamera(frm); connect(camera, SIGNAL(stateChanged(QCamera::State)), this, SLOT(stateChanged())); viewfinder = new QCameraViewfinder(frm); viewfinder->installEventFilter(this); camera->setViewfinder(viewfinder); QRect rect = frm->rect(); viewfinder->setAspectRatioMode(fillImage ? Qt::IgnoreAspectRatio : Qt::KeepAspectRatio); int offset = borderWidth 1 + 0; viewfinder->setGeometry(offset / 2, offset / 2, rect.width() - offset, rect.height() - offset); viewfinder->setVisible(true); imageCapture = new QCameraImageCapture(camera); connect(imageCapture, SIGNAL(imageCaptured(int, QImage)), this, SLOT(displayImage(int, QImage))); return true; }#endif#endif}//qml版本import QtQuick 2.0import QtMultimedia 5.6Item { signal receiveImage(); Video { id: video anchors.fill: parent //source: "rtsp://192.168.1.247:554/av0_0" source: "g:/mp4/1.mp4" MouseArea { anchors.fill: parent onClicked: { video.play() } } focus: true Keys.onSpacePressed: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play() Keys.onLeftPressed: video.seek(video.position - 5000) Keys.onRightPressed: video.seek(video.position + 5000) }}