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. QImage and OpenCV Mat problem

QImage and OpenCV Mat problem

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 6 Posters 2.2k Views
  • 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.
  • S Offline
    S Offline
    stvokr
    wrote on 7 Apr 2020, 09:44 last edited by
    #1

    Hi all.

    I'm using Windows 10 and Linux 18.04 with Qt 5.12 and OpenCV 4.0.1.
    I have a problem when loading a QImage and then converting it to an OpenCV Mat.
    It seems that QImage has more data in its array than the Mat.

    Properties:
    Qimage: width=1001px, height=1001px, type=QImage::Format_Grayscale, bytesPerLine=1004
    Mat: width=1001px, height=1001px, type=CV_8UC1, bytesPerLine=1001

    This problem does only occur when the image width is odd.

    Does anyone know why and how to solve it?

    The result images are confusing. The pixels are shifted.

    711e428e-4798-47e1-bd81-7c5969e274bb-grafik.png

    fe6c9da0-67c7-4e2e-ba19-d0e352090a63-grafik.png

    Regards,
    Oliver

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 7 Apr 2020, 11:09 last edited by
      #2

      Hi,

      IIRC, it will depend on the image format and size. There can be padding involved.

      In any case, it's usually done the other way around: load image with OpenCV, apply processing and move then to QImage.

      What are you currently doing ?

      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
      1
      • S Offline
        S Offline
        stvokr
        wrote on 7 Apr 2020, 11:57 last edited by
        #3

        Hi,

        currently I am loading a QImage from a file.
        Then I encode it to Base64-Format and insert the Base64-String into an xml-structure.

        This xml is sended through tcp/ip to a server where the server is decoding the Base64-String back to an image. And then I am processing the image with OpenCV.

        My current workaround is to save the QImage to hard disk and load again it with OpenCV. That works.

        Regards,
        Oliver

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 7 Apr 2020, 12:13 last edited by
          #4

          That might be a silly question but why not directly encode the file content ?

          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
          • B Offline
            B Offline
            beecksche
            wrote on 7 Apr 2020, 13:47 last edited by
            #5

            @stvokr
            QImage uses a 32-bit alignment, I also had some issues with the bytes: https://forum.qt.io/topic/105321/different-bytes-count-of-qimage

            1 Reply Last reply
            2
            • S Offline
              S Offline
              stvokr
              wrote on 7 Apr 2020, 15:51 last edited by
              #6

              @SGaist
              I will try that, but I need that QImage object directly. It should be possible to display the base64 string directly in a web browser as HTML content.

              @beecksche
              Thanks for that.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SGaist
                Lifetime Qt Champion
                wrote on 7 Apr 2020, 18:16 last edited by
                #7

                There's no problem with that but you didn't gave much information about your application so it's not easy to provide recommendations.

                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
                • S Offline
                  S Offline
                  stvokr
                  wrote on 8 Apr 2020, 05:31 last edited by
                  #8

                  @SGaist
                  I figured out that the main problem is not transferring the image but loading the image with QImage. Even when I just load the image from harddisk the bytesPerLine is 1004 for an 8 bit pixel image with 1001px width. So as already mentioned from @beecksche the 32-bit alignment will prevent the correct direct conversion from QImage to cv::Mat.

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on 8 Apr 2020, 07:33 last edited by
                    #9

                    Afaics OpenCV::Mat also supports padding. Images are always padded so it would be better to teach OpenCV::Mat about it.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    B 1 Reply Last reply 10 Jun 2023, 09:03
                    1
                    • C Christian Ehrlicher
                      8 Apr 2020, 07:33

                      Afaics OpenCV::Mat also supports padding. Images are always padded so it would be better to teach OpenCV::Mat about it.

                      B Offline
                      B Offline
                      bigrom
                      wrote on 10 Jun 2023, 09:03 last edited by
                      #10

                      QImage Mat2QImage(cv::Mat const& src)
                      {
                      cv::Mat temp; // make the same cv::Mat
                      cvtColor(source, temp,CV_BGR2RGB); // cvtColor Makes a copt, that what i need
                      QImage dest((const uchar *) temp.data, temp.cols, temp.rows, temp.step, QImage::Format_RGB888);
                      dest.bits(); // enforce deep copy, see documentation
                      // of QImage::QImage ( const uchar * data, int width, int height, Format format )
                      return dest;
                      }
                      // work with QT5.15.0 and OpenCv 4.7.0

                      1 Reply Last reply
                      0
                      • W Offline
                        W Offline
                        wrosecrans
                        wrote on 10 Jun 2023, 17:53 last edited by
                        #11

                        The decision to always have 4byte aligned scanlines is definitely one of the weirdest things about interoperating QImage with other API's. Most in-memory image formats for other API's are densely packed (at least by default). And it's something you only really notice with odd widths. (And RGBA format is 4 bytes per pixel so it's scanlines are always 4 byte aligned without padding, even for odd-width images.)

                        If you don't know the quirk, it's annoyingly easy to have a large test suite of different image sizes and formats, and still completely miss the combination of odd width and odd bytes per pixel.

                        C 1 Reply Last reply 10 Jun 2023, 18:44
                        0
                        • W wrosecrans
                          10 Jun 2023, 17:53

                          The decision to always have 4byte aligned scanlines is definitely one of the weirdest things about interoperating QImage with other API's. Most in-memory image formats for other API's are densely packed (at least by default). And it's something you only really notice with odd widths. (And RGBA format is 4 bytes per pixel so it's scanlines are always 4 byte aligned without padding, even for odd-width images.)

                          If you don't know the quirk, it's annoyingly easy to have a large test suite of different image sizes and formats, and still completely miss the combination of odd width and odd bytes per pixel.

                          C Offline
                          C Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 10 Jun 2023, 18:44 last edited by Christian Ehrlicher 6 Oct 2023, 18:45
                          #12

                          @wrosecrans said in QImage and OpenCV Mat problem:

                          Most in-memory image formats for other API's are densely packed (at least by default).

                          Then you should never decode a video stream with ffmpeg...
                          Images in video streams are normally 32 byte aligned nowadays to perfectly match to cpu vector instructions and caches.
                          The only thing I miss in QImage is to be able to specify this alignment in the ctor like e.g. av_image_alloc() allows.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          1 Reply Last reply
                          1

                          • Login

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