Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to get ROI of QVideoFrame?
Forum Updated to NodeBB v4.3 + New Features

How to get ROI of QVideoFrame?

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 5 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MHermann
    wrote on last edited by
    #1

    Hi all,

    I have a QVideoFrame (640x480).
    How can I extract a ROI of this frame?
    Look at this example. How can I get a new QVideoFrame of ROI?

    roi.png

    Pl45m4P 1 Reply Last reply
    0
    • JoeCFDJ Offline
      JoeCFDJ Offline
      JoeCFD
      wrote on last edited by
      #2

      call image() to get its image first and extract ROI from the image?
      and QVideoFrame new_video_frame( ROI_image ).

      1 Reply Last reply
      2
      • M MHermann

        Hi all,

        I have a QVideoFrame (640x480).
        How can I extract a ROI of this frame?
        Look at this example. How can I get a new QVideoFrame of ROI?

        roi.png

        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by
        #3

        @MHermann

        Convert QVideoFrame to QImage then access/grab the region of choice.
        (mind the correct pixel format and buffer size)


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        1 Reply Last reply
        1
        • M Offline
          M Offline
          MHermann
          wrote on last edited by MHermann
          #4

          Thanks for the replies.
          I tried the following:

          • Convert frame to image => OK
          • Get ROI-image => OK (I checked by saving and looking at the image)
          • Convert ROI-image to ROI-frame => NOK (In GUI no image is shown, it is black. If I don't edit *input, than the image is shown correctly in GUI.)

          I have to change the input frame so that the ROI-frame is shown in the GUI.
          How can I do this?

          QVideoFrame MyVideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
          {
             ...
          
             m_filter->m_frame.copyData(*input);
          
             QImage img((const uchar*)(m_filter->m_frame.data.data()), m_filter->m_frame.size.width(), m_filter->m_frame.size.height(), m_filter->m_frame.bytesPerLine, QImage::Format_RGB444);
          
             QImage imgRoi = img.copy(x, y, width, height);
             QVideoFrame frameRoi(imgRoi);
          
             *input = QVideoFrame();
             *input = frameRoi;
              
             return *input;
          
          jsulmJ 2 Replies Last reply
          0
          • M MHermann

            Thanks for the replies.
            I tried the following:

            • Convert frame to image => OK
            • Get ROI-image => OK (I checked by saving and looking at the image)
            • Convert ROI-image to ROI-frame => NOK (In GUI no image is shown, it is black. If I don't edit *input, than the image is shown correctly in GUI.)

            I have to change the input frame so that the ROI-frame is shown in the GUI.
            How can I do this?

            QVideoFrame MyVideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
            {
               ...
            
               m_filter->m_frame.copyData(*input);
            
               QImage img((const uchar*)(m_filter->m_frame.data.data()), m_filter->m_frame.size.width(), m_filter->m_frame.size.height(), m_filter->m_frame.bytesPerLine, QImage::Format_RGB444);
            
               QImage imgRoi = img.copy(x, y, width, height);
               QVideoFrame frameRoi(imgRoi);
            
               *input = QVideoFrame();
               *input = frameRoi;
                
               return *input;
            
            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @MHermann said in How to get ROI of QVideoFrame?:

            Convert ROI-image to ROI-frame => NOK

            In what way it is NOK?

            "I have to change the input frame so that the ROI-frame is shown in the GUI." - what do you have to change exactly?

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            M 1 Reply Last reply
            0
            • jsulmJ jsulm

              @MHermann said in How to get ROI of QVideoFrame?:

              Convert ROI-image to ROI-frame => NOK

              In what way it is NOK?

              "I have to change the input frame so that the ROI-frame is shown in the GUI." - what do you have to change exactly?

              M Offline
              M Offline
              MHermann
              wrote on last edited by
              #6

              @jsulm:
              No image is shown in qml. It is black.
              If I don't edit *input, than the image is shown correctly.

              1 Reply Last reply
              0
              • M MHermann

                Thanks for the replies.
                I tried the following:

                • Convert frame to image => OK
                • Get ROI-image => OK (I checked by saving and looking at the image)
                • Convert ROI-image to ROI-frame => NOK (In GUI no image is shown, it is black. If I don't edit *input, than the image is shown correctly in GUI.)

                I have to change the input frame so that the ROI-frame is shown in the GUI.
                How can I do this?

                QVideoFrame MyVideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
                {
                   ...
                
                   m_filter->m_frame.copyData(*input);
                
                   QImage img((const uchar*)(m_filter->m_frame.data.data()), m_filter->m_frame.size.width(), m_filter->m_frame.size.height(), m_filter->m_frame.bytesPerLine, QImage::Format_RGB444);
                
                   QImage imgRoi = img.copy(x, y, width, height);
                   QVideoFrame frameRoi(imgRoi);
                
                   *input = QVideoFrame();
                   *input = frameRoi;
                    
                   return *input;
                
                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by jsulm
                #7

                @MHermann said in How to get ROI of QVideoFrame?:

                *input = QVideoFrame();
                *input = frameRoi;

                1. The first line above is not needed (why do you create a new QVideoFrame, assign it to input and then assign frameRoi to input?). The input has to point to QVideoFrame instance already anyway if you want to assign another QVideoFrame to it.
                2. Did you check whether the created QImage(s) are valid?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                M 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @MHermann said in How to get ROI of QVideoFrame?:

                  *input = QVideoFrame();
                  *input = frameRoi;

                  1. The first line above is not needed (why do you create a new QVideoFrame, assign it to input and then assign frameRoi to input?). The input has to point to QVideoFrame instance already anyway if you want to assign another QVideoFrame to it.
                  2. Did you check whether the created QImage(s) are valid?
                  M Offline
                  M Offline
                  MHermann
                  wrote on last edited by
                  #8

                  @jsulm

                  Yes, I checked the imges. The images are correct.

                  jsulmJ 1 Reply Last reply
                  0
                  • M MHermann

                    @jsulm

                    Yes, I checked the imges. The images are correct.

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @MHermann What does https://doc.qt.io/qt-6/qvideoframe.html#isValid return?
                    It could also be that the QImage has to be converted to a supported video format first.

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    M 1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @MHermann What does https://doc.qt.io/qt-6/qvideoframe.html#isValid return?
                      It could also be that the QImage has to be converted to a supported video format first.

                      M Offline
                      M Offline
                      MHermann
                      wrote on last edited by MHermann
                      #10

                      @jsulm
                      The edited QVideoFrame is invalid ...

                      Any suggestions how I convert the QImage correctly to QVideoFrame?

                      jsulmJ 1 Reply Last reply
                      0
                      • M MHermann

                        @jsulm
                        The edited QVideoFrame is invalid ...

                        Any suggestions how I convert the QImage correctly to QVideoFrame?

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @MHermann You should check which formats QVideoFrame supports and what format you have in your QImage. Could be an issue converting different formats.
                        See the documentation (https://doc.qt.io/qt-6/qvideoframe.html#QVideoFrame-2):
                        "Otherwise, if the QImage::Format matches none of video formats, the image is first converted to a supported (A)RGB format using QImage::convertedTo() with the Qt::AutoColor flag."

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Why not just return frameRoi; ?

                          As @jsulm wrote, mutating the input frame does not make sense and is not how the video filter works AFAIK.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          M 1 Reply Last reply
                          1
                          • SGaistS SGaist

                            Why not just return frameRoi; ?

                            As @jsulm wrote, mutating the input frame does not make sense and is not how the video filter works AFAIK.

                            M Offline
                            M Offline
                            MHermann
                            wrote on last edited by
                            #13

                            @SGaist :
                            I tried that, but then it had no effect on the shown images in the GUI.
                            Thats why I think I have to do the changes on the input frame.

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              Which version of Qt are you using ?

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              M 1 Reply Last reply
                              0
                              • SGaistS SGaist

                                Which version of Qt are you using ?

                                M Offline
                                M Offline
                                MHermann
                                wrote on last edited by
                                #15

                                @SGaist: I am using Qt 5.12.7

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  There's an example application here that might help you get further.

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    MHermann
                                    wrote on last edited by MHermann
                                    #17

                                    If somebody is interested in the soultion:

                                    #include <QObject>
                                    #include <QAbstractVideoFilter>
                                    #include <QVideoFilterRunnable>
                                    #include <QAbstractVideoFilter>
                                    #include <QVideoFrame>
                                    #include <QDebug>
                                    #include <QThread>
                                    #include <QFuture>
                                    #include <QtConcurrent/QtConcurrent>
                                    #include <QOpenGLContext>
                                    #include <QOpenGLFunctions>
                                    #include <QQmlContext>
                                    #include "private/qvideoframe_p.h"
                                    
                                    ...
                                    
                                    QImage MyVideoFilterRunnable::QVideoFrameToQImage(const QVideoFrame& videoFrame)
                                    {
                                        if ( videoFrame.handleType() == QAbstractVideoBuffer::NoHandle )
                                        {
                                            QImage image = qt_imageFromVideoFrame( videoFrame );
                                            if ( image.isNull() )
                                            {
                                                return QImage();
                                            }
                                    
                                            if ( image.format() != QImage::Format_ARGB32 )
                                            {
                                                image = image.convertToFormat( QImage::Format_ARGB32 );
                                            }
                                    
                                            return image;
                                        }
                                    
                                        if ( videoFrame.handleType() == QAbstractVideoBuffer::GLTextureHandle )
                                        {
                                            QImage image( videoFrame.width(), videoFrame.height(), QImage::Format_ARGB32 );
                                            GLuint textureId = static_cast<GLuint>( videoFrame.handle().toInt() );
                                            QOpenGLContext* ctx = QOpenGLContext::currentContext();
                                            QOpenGLFunctions* f = ctx->functions();
                                            GLuint fbo;
                                            f->glGenFramebuffers( 1, &fbo );
                                            GLint prevFbo;
                                            f->glGetIntegerv( GL_FRAMEBUFFER_BINDING, &prevFbo );
                                            f->glBindFramebuffer( GL_FRAMEBUFFER, fbo );
                                            f->glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0 );
                                            f->glReadPixels( 0, 0,  videoFrame.width(),  videoFrame.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.bits() );
                                            f->glBindFramebuffer( GL_FRAMEBUFFER, static_cast<GLuint>( prevFbo ) );
                                            return image.rgbSwapped();
                                        }
                                    
                                        return QImage();
                                    }
                                    
                                    QVideoFrame MyVideoFilterRunnable::run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
                                    {
                                       ...
                                    
                                       m_filter->m_frame.copyData(*input);
                                    
                                       QImage img = QVideoFrameToQImage( *input );
                                    
                                       QImage imgRoi = img.copy(xMin, yMin, width, height);
                                       QVideoFrame frameRoi = QVideoFrame(imgRoi);
                                    
                                       *input = frameRoi;
                                    
                                        m_filter->m_processThread = QtConcurrent::run(this, &MyVideoFilterRunnable::processVideoFrame, m_filter->m_frame);
                                    
                                        return *input;
                                    }
                                    
                                    1 Reply Last reply
                                    0
                                    • M MHermann has marked this topic as solved on

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved