通常,如果你只是想打开UVC(web camera)并显示数据的话,那最简单的方式就是使用类似下面的代码,
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr):
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
mCamera = new QCamera(this);
mCameraViewfinder = new QCameraViewfinder(this);
mCameraImageCapture = new QCameraImageCapture(mCamera, this);
mLayout = new QVBoxLayout;
mCamera->setViewfinder(mCameraViewfinder);
mLayout->addWidget(mCameraViewfinder);
mLayout->setMargin(0);
ui->scrollArea->setLayout(mLayout);
}
~Widget(){...};
private slots:
void on_captureButton_clicked(){...};
void on_stopButton_clicked(){...};
void on_playButton_clicked(){...};
private:
Ui::Widget *ui;
QCamera *mCamera;
QCameraViewfinder *mCameraViewfinder;
QCameraImageCapture *mCameraImageCapture;
QVBoxLayout *mLayout;
};
如果使用QGraphicsView和QGraphicsScene的方式,则通常用QGraphicsVideoItem会更合适,
和前面的代码类似,
QGraphicsView* gView = NULL;
QGraphicsScene* gScene = NULL;
QGraphicsVideoItem* gVideoItem = NULL;
mCamera = new QCamera(this);
gScene = new QGraphicsScene(0, 0, 800, 600);
gView = new QGraphicsView;
gView->setScene(gScene);
ui->gridLayout->addWidget(gView); //setCentralWidget(view);
gVideoItem = new GraphVideoItem;
mCamera->setViewfinder(gVideoItem);
gVideoItem->setSize(QSizeF(800, 600));
gVideoItem->setPos(0, 0);
gScene->addItem(gVideoItem);
以上的问题是,如果我们 需要把每一帧数据收集起来,例如压缩成mp4,或者通过网络发送出去,或者需要对他进行视觉图形处理(这在机器视觉中是必须的),那就必须想办法把每一帧图像转变成QImage才行。
这里我就不讲理论了,我把这个写成了一个简单易用的头文件,除了QT之外,没有任何其他依赖。如果想看完整的demo,请参考链接:
https://github.com/SpaceView/WebCamera_to_QImage_for_Qt
如果只想用到这个类,可以直接看下面的源码(源码是参考了附录【1】的源码并进行了一些修改,同时也修复了一些不同版本引发的BUG),如下,
#ifndef WEBCAME_H
#define WEBCAME_H
#include
#include
#include
#include
#include
#include
#include
#include
struct CameraInfo
{
QString identify; /* Identify of device (maybe a device path) */
QString description; /* For display */
QList resolutionList;
QStringList formatList;
};
enum FormatType {
MJPEG,
YUYV
};
struct Format {
int w;
int h;
FormatType imageFormat;
int frameRate;
};
static QImage imageFromVideoFrame(const QVideoFrame& buffer)
{
QImage img;
QVideoFrame frame(buffer); // make a copy we can call map (non-const) on
frame.map(QAbstractVideoBuffer::ReadOnly);
QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(
frame.pixelFormat());
// BUT the frame.pixelFormat() is QVideoFrame::Format_Jpeg, and this is
// mapped to QImage::Format_Invalid by
// QVideoFrame::imageFormatFromPixelFormat
if (imageFormat != QImage::Format_Invalid) {
img = QImage(frame.bits(),
frame.width(),
frame.height(),
// frame.bytesPerLine(),
imageFormat);
} else {
// e.g. JPEG
int nbytes = frame.mappedBytes();
img = QImage::fromData(frame.bits(), nbytes);
}
frame.unmap();
return img;
}
class WebCameraCapture : public QAbstractVideoSurface
{
Q_OBJECT
public:
enum PixelFormat {
Format_Invalid,
Format_ARGB32,
Format_ARGB32_Premultiplied,
Format_RGB32,
Format_RGB24,
Format_RGB565,
Format_RGB555,
Format_ARGB8565_Premultiplied,
Format_BGRA32,
Format_BGRA32_Premultiplied,
Format_BGR32,
Format_BGR24,
Format_BGR565,
Format_BGR555,
Format_BGRA5658_Premultiplied,
Format_AYUV444,
Format_AYUV444_Premultiplied,
Format_YUV444,
Format_YUV420P,
Format_YV12,
Format_UYVY,
Format_YUYV,
Format_NV12,
Format_NV21,
Format_IMC1,
Format_IMC2,
Format_IMC3,
Format_IMC4,
Format_Y8,
Format_Y16,
Format_Jpeg,
Format_CameraRaw,
Format_AdobeDng,
#ifndef Q_QDOC
NPixelFormats,
#endif
Format_User = 1000
};
Q_ENUM(PixelFormat)
explicit WebCameraCapture(QObject *parent = 0) : QAbstractVideoSurface(parent)
{
}
QList supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const override
{
Q_UNUSED(handleType);
return QList()
关注
打赏
热门博文
- 对CSDN网站关于抄袭的投诉的处理建议
- Tesseract OCR训练时碰到的问题和解决方案
- VSCODE在Jetson Nano上打不上断点,无法调试python源码
- ROS2进阶:在windows10上用vs2019编译rviz2
- ROS2 ERROR: OpenGL 1.5 is not supported in GLRenderSystem::initialiseContext at C:\ci\ws\build...
- ROS2 error: can‘t find examples_rclcpp_minimal_subscriber/Release/wait_set_subscriber_library.lib
- 在windows上安装 chocolatey.1.1.0.nupkg
- Qt开发高级进阶:如何在显示时适合视窗宽度和高度(fitWidth+fitHeight)
- PySpark ERROR: Python in worker has different version 3.9 than that in driver 3.8
- cv2.imshow error: The function is not implemented. Rebuild the library with Windows...