QT对摄像头支持

Qt从5.0开始支持android摄像头,但是目前还没有做到统一完全跨平台API。还需要根据不同的平台系统来处理。这是因为Qt中QImage支持格式不全,现在不支持YUV格式。

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

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

先从QAbstractVideoSurface派生子类:

class MyVideoSurface : public QAbstractVideoSurface
{
    QList<QVideoFrame::PixelFormat> supportedPixelFormats(
            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const
    {
        Q_UNUSED(handleType);

        // 返回你将处理的格式
       return QList<QVideoFrame::PixelFormat>()
                << QVideoFrame::Format_RGB32  //windows 平台、linux 平台默认都支持 RGB32 格式  
                << QVideoFrame::Format_RGB24
                << QVideoFrame::Format_ARGB32
                << QVideoFrame::Format_ARGB32_Premultiplied
                << QVideoFrame::Format_RGB565
                << QVideoFrame::Format_RGB555
                //android支持的格式   
                << QVideoFrame::Format_NV21
                << QVideoFrame::Format_YV12
                << QVideoFrame::Format_RGB565
                << QVideoFrame::Format_YUV420P
                << QVideoFrame::Format_YUYV
                << QVideoFrame::Format_AYUV444
                << QVideoFrame::Format_Jpeg
                ;
    }    

    bool present(const QVideoFrame &frame)   
    { 
       Q_UNUSED(frame);        // 处理捕获的帧     
       return true;    
    }
};


MyVideoSurface surface;
QCamera m_Camera;
m_Camera.setCaptureMode(QCamera::CaptureMode::CaptureVideo);
m_Camera.setViewfinder(&surface);

 


二、用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支持格式为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 <QCamera>

class CCaptureVideoFrame : public QAbstractVideoSurface
{
    Q_OBJECT
public:
    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);

};

#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);
    return QList<QVideoFrame::PixelFormat>()
                << QVideoFrame::Format_RGB32  //windows 平台、linux 平台默认都支持 RGB32 格式  
                << QVideoFrame::Format_RGB24
                << QVideoFrame::Format_ARGB32
                << QVideoFrame::Format_ARGB32_Premultiplied
                << QVideoFrame::Format_RGB565
                << QVideoFrame::Format_RGB555
                //android支持的格式   
                << QVideoFrame::Format_NV21
                << QVideoFrame::Format_YV12
                << QVideoFrame::Format_RGB565
                << QVideoFrame::Format_YUV420P
                << QVideoFrame::Format_YUYV
                << QVideoFrame::Format_AYUV444
                << QVideoFrame::Format_Jpeg
                ;
}

//捕获视频帧。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;
    //捕获视频 
   pCamera->setViewfinder(this);
   return ret;
}

             

 

 

源码:https://github.com/KangLin/FaceRecognizer/blob/master/Src/CameraQtCaptureVideoFrame.h

或者:https://github.com/KangLin/RabbitIm/tree/master/Media/Camera

 

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;
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值