QT对摄像头支持

来源:互联网 发布:淘宝黑卡什么意思 编辑:程序博客网 时间:2024/05/10 05:20
Qt从5.0开始支持android摄像头,但是目前还没有做到统一完全跨平台API。还需要根据不同的平台系统来处理。这是因为Qt中QImage支持格式不全,现在不支持YUV格式。

Qt中捕获视频流用两种方式:

一、用QCamera::setViewfinder(QAbstractVideoSurface *surface)

class MyVideoSurface : public QAbstractVideoSurface{    QList<QVideoFrame::PixelFormat> supportedPixelFormats(            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const    {        Q_UNUSED(handleType);        // 返回你将处理的格式        return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32;    }    bool present(const QVideoFrame &frame)    {        Q_UNUSED(frame);        // 处理捕获的帧        return true;    }};


二、用QVideoProbe

camera = new QCamera;viewfinder = new QCameraViewfinder();camera->setViewfinder(viewfinder);camera->setCaptureMode(QCamera::CaptureVideo);videoProbe = new QVideoProbe(this);if (videoProbe->setSource(camera)) {    // Probing succeeded, videoProbe->isValid() should be true.    connect(videoProbe, SIGNAL(videoFrameProbed(QVideoFrame)),            this, SLOT(detectBarcodes(QVideoFrame)));}camera->start();// Viewfinder frames should now also be emitted by// the video probe, even in still image capture mode.// Another alternative is to install the probe on a// QMediaRecorder connected to the camera to get the// recorded frames, if they are different from the// viewfinder frames.


 

windows实现了第一种方式,android实现了第二种方式。

windows支持格式为RGB24、RGB32;android支持格式为NV21

 

下面我对捕获和显示进行了封装:

CaptureVideoFrame.h

/* * 作者:康林(msn、email: kl222@126.com) * * 从摄像头(QCarmera)或者(Player)中捕获视频帧。 * 注意:android后景摄像头捕获的视频翻转-90度,前景摄像头翻转90度。 * 用法: *      QCamera m_Camera; *      m_Camera.setCaptureMode(QCamera::CaptureVideo); *      CCaptureVideoFrame videoFrame; *      videoFrame.setSource(&m_Camera); * 注册SLOT: *      connect(&videoFrame, SIGNAL(CaptureFrame(const QVideoFrame&)), *           SLOT(CaptureVideoFrame(const QVideoFrame&))); * 在SLOT 中 CaptureVideoFrame(const QVideoFrame&) 处理捕获到的视频帧。 * * 示例代码: *   QList<QByteArray> device = QCamera::availableDevices(); *   QList<QByteArray>::iterator it; *   for(it = device.begin(); it != device.end(); it++) *   { *       qDebug("Camera:%s", qPrintable(QCamera::deviceDescription(*it))); *   } * *   QCamera camera(QCamera::availableDevices().at(1)); *   camera.setCaptureMode(QCamera::CaptureVideo); *   CFrmPlayer player; *   CCaptureVideoFrame captureVideoFrame; *   if(captureVideoFrame.setSource(&camera)) *   { *       qDebug("probe.setSource is ok"); *       player.connect(&captureVideoFrame, SIGNAL(CaptureFrame(QVideoFrame)), *                      SLOT(present(QVideoFrame))); *   } * *   player.show(); *   player.activateWindow(); *   camera.start(); */#ifndef CAPTUREVIDEOFRAME_H#define CAPTUREVIDEOFRAME_H#include <QAbstractVideoSurface>#include <QVideoProbe>#include <QCamera>class CCaptureVideoFrame : public QAbstractVideoSurface{    Q_OBJECTpublic:    explicit CCaptureVideoFrame(QObject *parent = 0);    virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;    bool setSource(QCamera *pCamera);signals:    //视频帧捕获信号    void CaptureFrame(const QVideoFrame &frame);private slots:    virtual bool present(const QVideoFrame &frame);private:     QVideoProbe m_Probe;//android下,目前只能用probe捕获视频};#endif // CAPTUREVIDEOFRAME_H


CaptureVideoFrame.cpp

/** 作者:康林(msn、email: kl222@126.com)*/#include "CaptureVideoFrame.h"#include <QCamera>CCaptureVideoFrame::CCaptureVideoFrame(QObject *parent) :    QAbstractVideoSurface(parent){}QList<QVideoFrame::PixelFormat> CCaptureVideoFrame::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const{    Q_UNUSED(handleType);    QList<QVideoFrame::PixelFormat> lst;    //lst.push_back(QVideoFrame::Format_YUYV);//Qt现在不支持此格式,因为Qt内部用了QImage来处理视频帧。    lst.push_back(QVideoFrame::Format_RGB32);    lst.push_back(QVideoFrame::Format_BGR32);    return lst;}//捕获视频帧。windows下格式是RGB32;android下是NV21bool CCaptureVideoFrame::present(const QVideoFrame &frame){    qDebug("CCaptureVideoFrame::present format:%d", frame.pixelFormat());    emit CaptureFrame(frame);    return true;}//根据不同的平台,设置捕获方式bool CCaptureVideoFrame::setSource(QCamera *pCamera){    bool ret = true;#ifdef ANDROID    //android下,目前只能用probe捕获视频    ret = m_Probe.setSource(pCamera);    if(ret)    {        connect(&m_Probe, SIGNAL(videoFrameProbed(QVideoFrame)),                          SLOT(present(QVideoFrame)));    }#else    //windows下,只能用下面方式捕获视频    pCamera->setViewfinder(this);#endif    return ret;}


 注意:android使用时需要定义 ANDROID 宏

 

QT对摄像头的支持存在的一些问题:

QT得到到捕获帧相关的参数

QT 在windows、linux下捕获视频只有5帧/秒左右,在我的电脑上用时 240ms 左右。在Android手机上可达到15帧/s(60ms左右)。

QT 在 windows、linux下多个摄像头切换正常,但在 android 手机上,前后摄像头不能切换。代码如下:

void CFrmVideo::on_cmbCamera_currentIndexChanged(int index){    LOG_MODEL_DEBUG("Video", "CFrmVideo::on_cmbCamera_currentIndexChanged");    m_CameraPostition = QCamera::availableDevices().at(index);    OpenCamera();    LOG_MODEL_DEBUG("Video", "CFrmVideo::on_cmbCamera_currentIndexChanged end");}int CFrmVideo::OpenCamera(){    if(!m_pCall)    {        LOG_MODEL_ERROR("Video", "CFrmVideo::OpenCamera m_pCall is null");        return -1;    }    if(m_pCamera)    {        CloseCamera();    }    m_pCamera = new QCamera(m_CameraPostition);    if(!m_pCamera)    {        LOG_MODEL_WARNING("Video", "Open carmera fail");        return -1;    }    m_pCamera->setCaptureMode(QCamera::CaptureVideo);    m_CaptureVideoFrame.setSource(m_pCamera);    //m_pCamera->load();    m_pCamera->start();    return 0;}int CFrmVideo::CloseCamera(){    if(m_pCamera)    {        m_pCamera->stop();        //m_pCamera->unload();        delete m_pCamera;        m_pCamera = NULL;    }    return 0;}
3 0
原创粉丝点击