> > 4. On the removal of QAbstractVideoFilter AND QVideoProbe: Disappointed to 
> > hear this. I previously used this for read-only frames for analysis, i.e. 
> > Barcode reading and object detection. How do we do that now?
> 
> You can get full access to the video data from a QVideoSink through the 
> newVideoFrame() signal and mapping the video frame (or converting it to a 
> QImage). With that you should have the access to the data that you need. (A 
> small detail that’s still missing right now but that I hope to have in place 
> for 6.2 is the ability to connect several sinks to a media player or capture 
> session, but it’s not really required as you can connect several slots to the 
> signal). If you feel like to need more than that, let me know what it is.

So the most common case I need supported is getting the video frame for 
processing while maintaining the full-speed live preview. Is this the 
multi-sink scenario?
Typically, With Camera connected o a VideoOutput, I use QVideoProbe to throw 
the frame (pixel data as QByteArray, because the library doesn't care) to a 
thread for multicore async processing. A typical 1 megapixel image on 
RaspberryPi4 takes ~150ms using ZBar or ZXing (I find ZXing is more like 
100ms), so this gets about 6 processed frames a second, which seems responsive 
enough to the user because they are looking at the live display.

Since you asked for actual code, attached is the code I use to do this. It may 
not be perfect code (long story made short, I just rewrote this from memory) 
but it is what I whipped up, and works reasonably well for now.  I've used this 
approach for barcodes and OpenCV.

If it matters: I disclaim any copyright for the attached files.

Attachment: barcodevideoprobe.cpp
Description: Binary data

#ifndef BARCODEVIDEOPROBE_H
#define BARCODEVIDEOPROBE_H

#include <QObject>
#include <QThread>
#include <QtQml>

#ifndef Q_OS_WASM
#include <QVideoProbe>
#include "zbar.h"
#include <QVideoFrame>
#include <QCamera>

#endif



class BarcodeVideoProbe : public QObject
{
        Q_OBJECT

        Q_PROPERTY(QObject* qmlCamera READ qmlCamera WRITE setQmlCamera NOTIFY 
qmlCameraChanged)
        Q_PROPERTY(QString barcodeFormat READ barcodeFormat WRITE 
setBarcodeFormat NOTIFY barcodeFormatChanged)
        Q_PROPERTY(QString barcode READ barcode WRITE setBarcode NOTIFY 
barcodeChanged)
        Q_PROPERTY(bool workerProcessing READ workerProcessing WRITE 
setWorkerProcessing NOTIFY workerProcessingChanged)
        Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)

        QThread m_workerThread;

        QObject *m_qmlCamera = nullptr;
        bool m_workerProcessing = false;
        bool m_active = true;

        QString m_barcode, m_barcodeFormat;

#ifndef Q_OS_WASM
        QCamera *m_camera = nullptr;
        QVideoProbe m_probe;

        QByteArray extractYChannel(const QVideoFrame &frame);
#endif

        QML_ELEMENT
public:
        explicit BarcodeVideoProbe(QObject * parent=nullptr);
        ~BarcodeVideoProbe();

        QString barcode() const;
        QString barcodeFormat() const;
        bool workerProcessing() const;

        bool active() const;

signals:
        void process(const QByteArray &pixelData, const QSize& size);
        void barcodeFound(QString barcode, QString format);

        void barcodeChanged(QString barcode);
        void barcodeFormatChanged(QString barcodeFormat);
        void workerProcessingChanged(bool workerProcessing);
        void qmlCameraChanged();

        void activeChanged(bool active);

public slots:
        QObject* qmlCamera() const;
        void setQmlCamera(QObject*qmlCamera);
#ifndef Q_OS_WASM
        void processFrame(QVideoFrame);
#endif
        void setBarcode(QString barcode);
        void setBarcodeFormat(QString barcodeFormat);
        void setWorkerProcessing(bool workerProcessing);

        // handle worker signals
        void handleBarcode(QString barcode, QString format);
        void handleProcessingComplete();

        void setActive(bool active);
};

class BarcodeDecodeWorker : public QObject
{
        Q_OBJECT
#ifndef Q_OS_WASM
        zbar::ImageScanner scanner;
#endif

public slots:
        void process(const QByteArray &pixelData, const QSize& size);

signals:
        void barcode(const QString &result, const QString &format); // this may 
be emitted multiple times
        void processingComplete();
};
#endif // BARCODEVIDEOPROBE_H
_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to