2015-01-07 12 views
6

ich alle Bilder aus einem QMediaPlayer und wandeln es in QImage (oder cv::Mat)konvertieren QVideoFrame zu QImage

so habe ich videoFrameProbed Signal von QVideoProbe erhalten möchten:

connect(&video_probe_, &QVideoProbe::videoFrameProbed, 
     [this](const QVideoFrame& currentFrame){ 
    //QImage img = ?? 
} 

Aber ich finde nicht Jede Möglichkeit, QImage von QVideoFrame zu bekommen!

Wie kann ich QVideoFrame in QImage konvertieren?!

+0

Das hängt von dem Format des QVideoFrame ab. QImage kann nur [ein paar RGB-basierte Formate] akzeptieren (http://qt-project.org/doc/qt-4.8/qimage.html#image-formats). Es gibt verschiedene Bibliotheken, die zwischen verschiedenen YUV- und RGB-Formaten konvertieren können. Aber wenn du kannst, empfehle ich dir, deine Videoframes direkt mit OpenCV zu lesen. – tux3

+0

Haben Sie das gelöst? – aviit

Antwort

8

können Sie QImage Konstruktor verwenden:

QImage img(currentFrame.bits(), 
      currentFrame.width(), 
      currentFrame.height(), 
      currentFrame.bytesPerLine(), 
      imageFormat); 

Wo Sie imageFormat von pixelFormat des QVideoFrame bekommen:

QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(currentFrame.pixelFormat()); 
+0

obwohl das Video wahrscheinlich im YUV-Format ist (imageFormatFromPixelFormat wird fehlschlagen). Nicht sicher, ob Qt Yuv Umwandlung eingebaut hat .. alternativ könnte libyuv verwenden. – Pete

+1

Ich denke, dass Qt auf zugrunde liegenden MediaFramework für Konvertierungen beruht. Unter Linux ist das gstreamer, das viele Conversions unterstützt. Als unterstützende Tatsache, in benutzerdefinierten Implementierungen von QAbstractVideoSurface sind Sie gezwungen, rein virtuelle unterstütztePixelFormats zu implementieren, und wenn ich BGR24 als das einzige Format, das ist das Format, das ich erhielt. –

+2

Bitte lesen Sie auch Anforderungen hier: http://doc.qt.io/qt-5/qvideoframe.html#details für QVideoFrame, um map() vor dem Aufrufen von Bits() aufzurufen –

4

Für QCamera Ausgang, ist diese Methode nicht immer. Insbesondere gibt QVideoFrame :: imageFormatFromPixelFormat() QImage :: Format_Invalid zurück, wenn QVideoFrame :: Format_Jpeg angegeben wird, was aus meiner QCamera kommt. Aber das funktioniert:

QImage Camera::imageFromVideoFrame(const QVideoFrame& buffer) const 
{ 
    QImage img; 
    QVideoFrame frame(buffer); // make a copy we can call map (non-const) on 
    frame.map(QAbstractVideoBuffer::ReadOnly); 
    QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(
       frame.pixelFormat()); 
    // BUT the frame.pixelFormat() is QVideoFrame::Format_Jpeg, and this is 
    // mapped to QImage::Format_Invalid by 
    // QVideoFrame::imageFormatFromPixelFormat 
    if (imageFormat != QImage::Format_Invalid) { 
     img = QImage(frame.bits(), 
        frame.width(), 
        frame.height(), 
        // frame.bytesPerLine(), 
        imageFormat); 
    } else { 
     // e.g. JPEG 
     int nbytes = frame.mappedBytes(); 
     img = QImage::fromData(frame.bits(), nbytes); 
    } 
    frame.unmap(); 
    return img; 
}