gpt4 book ai didi

c++ - 如何从相机读取缓冲区信息?

转载 作者:行者123 更新时间:2023-11-28 02:04:50 25 4
gpt4 key购买 nike

我有一个 Qt 应用程序的特定部分,它应该从相机拍摄照片并使用 qzxing 库解码 QR 码。但是,我无法从缓冲区中取出照片!我知道解码工作正常,因为如果我将照片保存到文件然后立即将其重新加载为 QImage,一切正常(当然,除非程序在图像完全保存之前不会阻塞,所以它将尝试解码半图像,然后在第二次尝试时,解码第一张图像。)!

有很多人问这个问题,但似乎没有人有完整的答案。在过去的六个小时里,我一直在研究、猜测和测试。 QCameraImageCapture 的 Qt 文档存在,但根本没有谈论在 QImage 中传递缓冲区或转换。 SO 上有一些答案,其中有一些关于将图像转换为 QImage 的猜测,还有一些关于寻找缓冲区的答案,但没有人有完整的答案。 Qt 示例文档甚至不完整,他们的示例项目(网络上到处都是损坏的链接)没有讨论它在做什么。

下面是一些测试代码的示例,这些代码使用带有名为“pushButton”的按钮和名为“verticalLayout”的垂直布局的 mainwindow.ui 运行和编译。我做错了什么?

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QImage>
#include <QCamera>
#include <QCameraInfo>
#include <QCameraViewfinder>
#include <QCameraImageCapture>
#include <qzxing/QZXing.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:
void cameraReceiver(int f,QVideoFrame u);
void on_pushButton_clicked();

private:
Ui::MainWindow *ui;
QCameraViewfinder *viewfinder;
QCamera *invCam;
QCameraImageCapture *rawImage;
QZXing *decoder;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

//build camera
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
foreach (const QCameraInfo &cameraInfo, cameras) {
if (cameraInfo.deviceName() == "/dev/video0")
invCam = new QCamera(cameraInfo);

}

//build decoder
decoder = new QZXing;
decoder->setDecoder(QZXing::DecoderFormat_QR_CODE);

//build viewfinder and link to camera
viewfinder = new QCameraViewfinder(this);
viewfinder->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
ui->verticalLayout->addWidget(viewfinder);
invCam->setViewfinder(viewfinder);

//build image buffer, set camera mode to capture
rawImage = new QCameraImageCapture(invCam);
invCam->setCaptureMode(QCamera::CaptureStillImage);
invCam->start();
viewfinder->show();

connect(rawImage,SIGNAL(imageAvailable(int,QVideoFrame)),this,SLOT(cameraReceiver(int,QVideoFrame)));
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::cameraReceiver(int f,QVideoFrame u) {

QImage currentImage(u.bits(), u.width(), u.height(), u.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat(u.pixelFormat()));
QString output = decoder->decodeImage(currentImage);
qDebug() << output;

}

void MainWindow::on_pushButton_clicked()
{
rawImage->setCaptureDestination(QCameraImageCapture::CaptureToBuffer);
rawImage->capture();
}

编辑:目前在 Linux 环境中,摄像头是嵌入式的。取景器显示得很好,就像我说的,我可以将图像捕捉到 FILE 没问题 - 相机工作得很好

编辑 2:一旦我在 SO 上发帖,我就找到了答案:

“connect”调用应该使用“imageCaptured”信号:

connect(rawImage,SIGNAL(imageCaptured(int,QImage)),this,SLOT(cameraReceiver(int,QImage)));

然后,缓冲区中就有一个 QImage。

void MainWindow::cameraReceiver(int f,QImage u) {

QString output = decoder->decodeImage(u);
qDebug() << output;
}

最佳答案

我看到你已经找到了自己的解决方案,但如果有人坚持使用它,如果有人需要使用 QVideoFrame,这里有一个重要提示:

问题是QVideoFrame的错误使用。必须先映射框架,然后才能访问它:

void MainWindow::cameraReceiver(int f,QVideoFrame u) {
if (u.isValid()) {
if(u.map(QAbstractVideoBuffer::ReadOnly)) {//map the frame
uchar * data = new uchar[u.mappedBytes()];//copy the buffer for QImage
memcpy(data, u.bits(), u.mappedBytes());
QImage image(data,
u.width(),
u.height(),
u.bytesPerLine(),
QVideoFrame::imageFormatFromPixelFormat(u.pixelFormat()),
simpleCleanupHandler,//handles the buffer cleanup
data);//required for the cleanup
u.unmap();//unmap the frame

QString output = decoder->decodeImage(currentImage);
qDebug() << output;
}
}
}

因为 QImage 不会复制缓冲区,所以你必须自己做。 simpleImageCleanupHandler 如下所示:

static void simpleCleanupHandler(void *info)
{
delete[] (uchar*)info;
}

关于c++ - 如何从相机读取缓冲区信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37933476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com