QT对摄像头支持

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

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

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class MyVideoSurface : public QAbstractVideoSurface  
  2. {  
  3.     QList<QVideoFrame::PixelFormat> supportedPixelFormats(  
  4.             QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const  
  5.     {  
  6.         Q_UNUSED(handleType);  
  7.   
  8.         // 返回你将处理的格式  
  9.         return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32;  
  10.     }  
  11.   
  12.     bool present(const QVideoFrame &frame)  
  13.     {  
  14.         Q_UNUSED(frame);  
  15.         // 处理捕获的帧  
  16.         return true;  
  17.     }  
  18. };  


二、用QVideoProbe

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. camera = new QCamera;  
  2. viewfinder = new QCameraViewfinder();  
  3. camera->setViewfinder(viewfinder);  
  4.   
  5. camera->setCaptureMode(QCamera::CaptureVideo);  
  6.   
  7. videoProbe = new QVideoProbe(this);  
  8.   
  9. if (videoProbe->setSource(camera)) {  
  10.     // Probing succeeded, videoProbe->isValid() should be true.  
  11.     connect(videoProbe, SIGNAL(videoFrameProbed(QVideoFrame)),  
  12.             this, SLOT(detectBarcodes(QVideoFrame)));  
  13. }  
  14.   
  15. camera->start();  
  16. // Viewfinder frames should now also be emitted by  
  17. // the video probe, even in still image capture mode.  
  18. // Another alternative is to install the probe on a  
  19. // QMediaRecorder connected to the camera to get the  
  20. // recorded frames, if they are different from the  
  21. // viewfinder frames.  


 

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

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

 

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

CaptureVideoFrame.h

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * 作者:康林(msn、email: kl222@126.com) 
  3.  * 
  4.  * 从摄像头(QCarmera)或者(Player)中捕获视频帧。 
  5.  * 注意:android后景摄像头捕获的视频翻转-90度,前景摄像头翻转90度。 
  6.  * 用法: 
  7.  *      QCamera m_Camera; 
  8.  *      m_Camera.setCaptureMode(QCamera::CaptureVideo); 
  9.  *      CCaptureVideoFrame videoFrame; 
  10.  *      videoFrame.setSource(&m_Camera); 
  11.  * 注册SLOT: 
  12.  *      connect(&videoFrame, SIGNAL(CaptureFrame(const QVideoFrame&)), 
  13.  *           SLOT(CaptureVideoFrame(const QVideoFrame&))); 
  14.  * 在SLOT 中 CaptureVideoFrame(const QVideoFrame&) 处理捕获到的视频帧。 
  15.  * 
  16.  * 示例代码: 
  17.  *   QList<QByteArray> device = QCamera::availableDevices(); 
  18.  *   QList<QByteArray>::iterator it; 
  19.  *   for(it = device.begin(); it != device.end(); it++) 
  20.  *   { 
  21.  *       qDebug("Camera:%s", qPrintable(QCamera::deviceDescription(*it))); 
  22.  *   } 
  23.  * 
  24.  *   QCamera camera(QCamera::availableDevices().at(1)); 
  25.  *   camera.setCaptureMode(QCamera::CaptureVideo); 
  26.  *   CFrmPlayer player; 
  27.  *   CCaptureVideoFrame captureVideoFrame; 
  28.  *   if(captureVideoFrame.setSource(&camera)) 
  29.  *   { 
  30.  *       qDebug("probe.setSource is ok"); 
  31.  *       player.connect(&captureVideoFrame, SIGNAL(CaptureFrame(QVideoFrame)), 
  32.  *                      SLOT(present(QVideoFrame))); 
  33.  *   } 
  34.  * 
  35.  *   player.show(); 
  36.  *   player.activateWindow(); 
  37.  *   camera.start(); 
  38.  */  
  39.   
  40. #ifndef CAPTUREVIDEOFRAME_H  
  41. #define CAPTUREVIDEOFRAME_H  
  42.   
  43. #include <QAbstractVideoSurface>  
  44. #include <QVideoProbe>  
  45. #include <QCamera>  
  46.   
  47. class CCaptureVideoFrame : public QAbstractVideoSurface  
  48. {  
  49.     Q_OBJECT  
  50. public:  
  51.     explicit CCaptureVideoFrame(QObject *parent = 0);  
  52.   
  53.     virtual QList<QVideoFrame::PixelFormat> supportedPixelFormats(  
  54.             QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;  
  55.   
  56.     bool setSource(QCamera *pCamera);  
  57.   
  58. signals:  
  59.     //视频帧捕获信号  
  60.     void CaptureFrame(const QVideoFrame &frame);  
  61.   
  62. private slots:  
  63.     virtual bool present(const QVideoFrame &frame);  
  64.   
  65. private:  
  66.      QVideoProbe m_Probe;//android下,目前只能用probe捕获视频  
  67.   
  68. };  
  69.   
  70. #endif // CAPTUREVIDEOFRAME_H  


CaptureVideoFrame.cpp

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 作者:康林(msn、email: kl222@126.com)*/  
  2. #include "CaptureVideoFrame.h"  
  3. #include <QCamera>  
  4.   
  5. CCaptureVideoFrame::CCaptureVideoFrame(QObject *parent) :  
  6.     QAbstractVideoSurface(parent)  
  7. {  
  8. }  
  9.   
  10. QList<QVideoFrame::PixelFormat> CCaptureVideoFrame::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const  
  11. {  
  12.     Q_UNUSED(handleType);  
  13.     QList<QVideoFrame::PixelFormat> lst;  
  14.   
  15.     //lst.push_back(QVideoFrame::Format_YUYV);//Qt现在不支持此格式,因为Qt内部用了QImage来处理视频帧。  
  16.     lst.push_back(QVideoFrame::Format_RGB32);  
  17.     lst.push_back(QVideoFrame::Format_BGR32);  
  18.   
  19.     return lst;  
  20. }  
  21.   
  22. //捕获视频帧。windows下格式是RGB32;android下是NV21  
  23. bool CCaptureVideoFrame::present(const QVideoFrame &frame)  
  24. {  
  25.     qDebug("CCaptureVideoFrame::present format:%d", frame.pixelFormat());  
  26.     emit CaptureFrame(frame);  
  27.   
  28.     return true;  
  29. }  
  30.   
  31. //根据不同的平台,设置捕获方式  
  32. bool CCaptureVideoFrame::setSource(QCamera *pCamera)  
  33. {  
  34.     bool ret = true;  
  35. #ifdef ANDROID  
  36.     //android下,目前只能用probe捕获视频  
  37.     ret = m_Probe.setSource(pCamera);  
  38.     if(ret)  
  39.     {  
  40.         connect(&m_Probe, SIGNAL(videoFrameProbed(QVideoFrame)),  
  41.                           SLOT(present(QVideoFrame)));  
  42.     }  
  43. #else  
  44.     //windows下,只能用下面方式捕获视频  
  45.     pCamera->setViewfinder(this);  
  46. #endif  
  47.     return ret;  
  48. }  


 

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

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

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

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void CFrmVideo::on_cmbCamera_currentIndexChanged(int index)  
  2. {  
  3.     LOG_MODEL_DEBUG("Video""CFrmVideo::on_cmbCamera_currentIndexChanged");  
  4.   
  5.     m_CameraPostition = QCamera::availableDevices().at(index);  
  6.   
  7.     OpenCamera();  
  8.     LOG_MODEL_DEBUG("Video""CFrmVideo::on_cmbCamera_currentIndexChanged end");  
  9. }  
  10.   
  11. int CFrmVideo::OpenCamera()  
  12. {  
  13.     if(!m_pCall)  
  14.     {  
  15.         LOG_MODEL_ERROR("Video""CFrmVideo::OpenCamera m_pCall is null");  
  16.         return -1;  
  17.     }  
  18.   
  19.     if(m_pCamera)  
  20.     {  
  21.         CloseCamera();  
  22.     }  
  23.   
  24.     m_pCamera = new QCamera(m_CameraPostition);  
  25.     if(!m_pCamera)  
  26.     {  
  27.         LOG_MODEL_WARNING("Video""Open carmera fail");  
  28.         return -1;  
  29.     }  
  30.   
  31.     m_pCamera->setCaptureMode(QCamera::CaptureVideo);  
  32.     m_CaptureVideoFrame.setSource(m_pCamera);  
  33.   
  34.     //m_pCamera->load();  
  35.     m_pCamera->start();  
  36.     return 0;  
  37. }  
  38.   
  39. int CFrmVideo::CloseCamera()  
  40. {  
  41.     if(m_pCamera)  
  42.     {  
  43.         m_pCamera->stop();  
  44.         //m_pCamera->unload();  
  45.         delete m_pCamera;  
  46.         m_pCamera = NULL;  
  47.     }  
  48.     return 0;  
  49. }  
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值