如何直接读取QCamera的一帧数据

前言

参考文章请看How to grab video frames directly from QCamera 感谢这位大神的指引.
为了方便我转发过来了详情请看转发博文

参考资料

The QCamera class provides interface for system camera devices.
QCamera can be used with QCameraViewfinder for viewfinder display, QMediaRecorder for video recording and QCameraImageCapture for image taking.

依上理解:

  • QCameraViewfinder:用于显示
  • QMediaRecorder::用于录像
  • QCameraImageCapture:用于采集图像

我这里只想获取数据所以使用QCameraImageCapture,查看qt例程如下:

 camera = new QCamera;

  //viewfinder = new QCameraViewfinder();
  //viewfinder->show();

  //camera->setViewfinder(viewfinder);

  imageCapture = new QCameraImageCapture(camera);

  camera->setCaptureMode(QCamera::CaptureStillImage);
  camera->start();
  //on half pressed shutter button
  camera->searchAndLock();

  //on shutter button pressed
  imageCapture->capture();

  //on shutter button released
  camera->unlock();

注:viewfinder是我注释掉的,不影响capture,你也可以直接查看camera例程
这里关键是capture这个方法,看说明:

[slot] int QCameraImageCapture::capture(const QString &file = QString())

Capture the image and save it to file. This operation is asynchronous in majority of cases, followed by signals QCameraImageCapture::imageExposed(), QCameraImageCapture::imageCaptured(), QCameraImageCapture::imageSaved() or QCameraImageCapture::error().

If an empty file is passed, the camera backend choses the default location and naming scheme for photos on the system, if only file name without full path is specified, the image will be saved to the default directory, with a full path reported with imageCaptured() and imageSaved() signals.

QCamera saves all the capture parameters like exposure settings or image processing parameters, so changes to camera parameters after capture() is called do not affect previous capture requests.

QCameraImageCapture::capture returns the capture Id parameter, used with imageExposed(), imageCaptured() and imageSaved() signals.
See also isReadyForCapture().

简单说就是capture是用来获取图像并保存(无论你是否写路径,它都会自动保存,这在快速处理数据时就要喊蛋蛋了.),而且它之后还紧跟随着4个信号发射--采集完毕,保存完毕,曝光完毕,发生错误,例程里的处理就是使用的QCameraImageCapture::imageCaptured()这个信号,如下:

void Camera::setCamera(const QCameraInfo &cameraInfo)
{
    ...  
       imageCapture = new QCameraImageCapture(camera);
    ...
      connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this, SLOT(processCapturedImage(int,QImage)));
    ...
}
void Camera::processCapturedImage(int requestId, const QImage& img)
{
    Q_UNUSED(requestId);
    QImage scaledImage = img.scaled(ui->viewfinder->size(),
                                    Qt::KeepAspectRatio,
                                    Qt::SmoothTransformation);

    ui->lastImagePreviewLabel->setPixmap(QPixmap::fromImage(scaledImage));

    // Display captured image for 4 seconds.
    displayCapturedImage();
    QTimer::singleShot(4000, this, SLOT(displayViewfinder()));
}
问题

如前所述,我只想采集摄像头数据处理,用这方法就烦了,总是给我自动保存,不知道qt怎么想的.

解决

博文中的大神的方法经我测试在window下也是可行的,网上还有个方法如下,可惜window下不支持CaptureToBuffer这个属性.

  1. Make sure that the buffer destination is supported:

    imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer) 
  2. If so, set the buffer destination, and buffer format and resolution, etc.

  3. Finally, receive the captured frames in a slot connected to the imageAvailable(int, const QVideoFrame &) signal.
code 片段
void CCamWorker::setCamera(const QByteArray &device_name)
{
    delete imageCapture;
    delete camera;

    if(device_name.isEmpty())
        camera = new QCamera(QCameraInfo::defaultCamera());
    else
        camera = new QCamera(device_name);

    connect(camera, SIGNAL(error(QCamera::Error)), this, SLOT(displayCameraError()));

    _cameraFrameGrabber = new CameraFrameGrabber();
    camera->setViewfinder(_cameraFrameGrabber);
    connect(_cameraFrameGrabber, SIGNAL(frameAvailable(int,QImage)), this, SLOT(processCapturedImage(int,QImage)));

    if(camera->isCaptureModeSupported(QCamera::CaptureStillImage))
        camera->setCaptureMode(QCamera::CaptureStillImage);
    camera->start();
}
void CCamWorker::processCapturedImage(int requestId, const QImage &img)
{
    Q_UNUSED(requestId);
    QImage tmpimage = img.copy();
    if(!isGettingImage)
        preview_image = tmpimage;
    if(display_label)
    {
        QPixmap pmap;
        pmap = pmap.fromImage(tmpimage);
        display_label->setPixmap(pmap);
    }
}
void CCamWorker::getImageFile(QImage &image){
    isGettingImage = true;
    image = preview_image;
    isGettingImage = false;
}

注:processCapturedImage中不能直接将img赋给preview_image,不然出错.发现很多情况下QT都是这样的,不能将通过信号发送来的图片直接显示或赋值给另一个对象.不然出莫名其妙的错误(比如在这行,在另一个平台就不行之类的).机理不明.

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值