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. Get RGB value of pixel
Forum Updated to NodeBB v4.3 + New Features

Get RGB value of pixel

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 4 Posters 13.7k 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.
  • M Offline
    M Offline
    MHermann
    wrote on last edited by MHermann
    #1

    Hi all!

    I have a QImage with Format_Indexed8.
    I want to get the rgb values of each pixel.

    But at the moment I receive always a value for blue, but red and green are always 0.
    Obviously I am doing something wrong. But I don't know what ...

    for (int r=0; r<=255; r++)
        for (int g=0; g<=255; g++)
            for (int b=0; b<=255; b++)
                m_colorTable.append(qRgb(r, g, b));
    
    QImage img(vidFrame.bits(), vidFrame.width(), vidFrame.height(), vidFrame.bytesPerLine(), QImage::Format_Indexed8);
    img.setColorTable(m_colorTable);
    
    int maxRed = 0; 
    int maxGreen = 0;
    int maxBlue = 0;
    for (int row=0; row<img.height(); row++) {
    for (int col=0; col<img.width(); col++) {
        int pixIdx = img.pixelIndex(col, row);
        QRgb pixColor = img.color(pixIdx);
        int red   = qRed(pixColor);
        int green = qGreen(pixColor);
        int blue  = qBlue(pixColor);
      }
    }
    

    I also tried to convert the image to Format_RGB32.
    But this also doesn't work.

    Any ideas?

    Kind regards,
    MHermann

    J.HilkJ 1 Reply Last reply
    0
    • M MHermann

      Hi all!

      I have a QImage with Format_Indexed8.
      I want to get the rgb values of each pixel.

      But at the moment I receive always a value for blue, but red and green are always 0.
      Obviously I am doing something wrong. But I don't know what ...

      for (int r=0; r<=255; r++)
          for (int g=0; g<=255; g++)
              for (int b=0; b<=255; b++)
                  m_colorTable.append(qRgb(r, g, b));
      
      QImage img(vidFrame.bits(), vidFrame.width(), vidFrame.height(), vidFrame.bytesPerLine(), QImage::Format_Indexed8);
      img.setColorTable(m_colorTable);
      
      int maxRed = 0; 
      int maxGreen = 0;
      int maxBlue = 0;
      for (int row=0; row<img.height(); row++) {
      for (int col=0; col<img.width(); col++) {
          int pixIdx = img.pixelIndex(col, row);
          QRgb pixColor = img.color(pixIdx);
          int red   = qRed(pixColor);
          int green = qGreen(pixColor);
          int blue  = qBlue(pixColor);
        }
      }
      

      I also tried to convert the image to Format_RGB32.
      But this also doesn't work.

      Any ideas?

      Kind regards,
      MHermann

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      hi @MHermann ,
      have you taken a look in the Documentation yet?

      http://doc.qt.io/qt-5/qimage.html#pixel

      This link should help you.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      M 1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        hi @MHermann ,
        have you taken a look in the Documentation yet?

        http://doc.qt.io/qt-5/qimage.html#pixel

        This link should help you.

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

        @J.Hilk : Yes. Of course, I read the documentation of QImage. But nevertheless I am not able to get the correct values.

        J.HilkJ 1 Reply Last reply
        0
        • M MHermann

          @J.Hilk : Yes. Of course, I read the documentation of QImage. But nevertheless I am not able to get the correct values.

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by J.Hilk
          #4

          @MHermann

          for (int row=0; row<img.height(); row++) {
          for (int col=0; col<img.width(); col++) {
               QRgb pixColor = img.pixel(row, col);
               qDebug() << "red" << qRed(pixColor) << endl
                                 << "green" <<qGreen(pixColor) << endl
                                 << "blue" << qBlue(pixColor);
            }
          }
          

          however, QImage::pixel is slow the docu recommends constBits() or constScanLine()


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          M 1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @MHermann

            for (int row=0; row<img.height(); row++) {
            for (int col=0; col<img.width(); col++) {
                 QRgb pixColor = img.pixel(row, col);
                 qDebug() << "red" << qRed(pixColor) << endl
                                   << "green" <<qGreen(pixColor) << endl
                                   << "blue" << qBlue(pixColor);
              }
            }
            

            however, QImage::pixel is slow the docu recommends constBits() or constScanLine()

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

            @J.Hilk : Thanks for your answers.
            But this also gives me the same results.
            I thought maybe the weird results are because of the image format and/or the color table.

            If I am using Indexed8 format, I also set the greated color table. Then I receive one value for blue. But red and green are always 0.
            If I am using Rgb32 format, I do not set the color table. Then I receive the same values for red, green and blue.

            1 Reply Last reply
            0
            • mranger90M Offline
              mranger90M Offline
              mranger90
              wrote on last edited by
              #6

              I think the problem is your color table. The color table should be something like:

                for (int i = 0; i < 256; i++) {
                      QRgb color(qRgba(i,i,i,0xFF));
                      m_colors.append(color);
                  }
              

              My example sets up a 255 entry gray scale table. You may want something different.
              The point is, there should only be 255 entries.

              M 1 Reply Last reply
              1
              • mranger90M mranger90

                I think the problem is your color table. The color table should be something like:

                  for (int i = 0; i < 256; i++) {
                        QRgb color(qRgba(i,i,i,0xFF));
                        m_colors.append(color);
                    }
                

                My example sets up a 255 entry gray scale table. You may want something different.
                The point is, there should only be 255 entries.

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

                @mranger90 : Thanks for your answer.
                I want to detect red pixels in the QImage.
                How does the color have to look like if I want to detect also colors, not only different gray values?

                If I am using a Indexed8 image I can only detect gray values so I have to convert the image to RGB32, right?

                1 Reply Last reply
                0
                • mranger90M Offline
                  mranger90M Offline
                  mranger90
                  wrote on last edited by
                  #8

                  By using an indexed-8 format you are creating an image based on 8 bit data. That means there are only 256 possible values for the pixel. By setting up a color table your are telling QImage how to map those 8 bit values to the RGB values. It may or may not be gray scale. You could set up a table in which the values map to color based RGB values.
                  The point is, you are setting up an enormous table (256256256) and that cant be correct.
                  Once the table is correct, you should be able extract the color for a given pixel as mentioned by @J-Hilk

                  M 2 Replies Last reply
                  5
                  • mranger90M mranger90

                    By using an indexed-8 format you are creating an image based on 8 bit data. That means there are only 256 possible values for the pixel. By setting up a color table your are telling QImage how to map those 8 bit values to the RGB values. It may or may not be gray scale. You could set up a table in which the values map to color based RGB values.
                    The point is, you are setting up an enormous table (256256256) and that cant be correct.
                    Once the table is correct, you should be able extract the color for a given pixel as mentioned by @J-Hilk

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

                    @mranger90 : Thanks for your hints.
                    Now i set up a color table with 256 entries with different colors.
                    Now it seems to work.

                    1 Reply Last reply
                    0
                    • mranger90M mranger90

                      By using an indexed-8 format you are creating an image based on 8 bit data. That means there are only 256 possible values for the pixel. By setting up a color table your are telling QImage how to map those 8 bit values to the RGB values. It may or may not be gray scale. You could set up a table in which the values map to color based RGB values.
                      The point is, you are setting up an enormous table (256256256) and that cant be correct.
                      Once the table is correct, you should be able extract the color for a given pixel as mentioned by @J-Hilk

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

                      @mranger90 : After some testing I think it is not working correctly...
                      I get some values. But theses values are not representing the real colors of my image.

                      I built up the color table with 256 color values, like this:

                         for (int colCnt=2, cnt=0; cnt<41; cnt++) {
                              m_colorTable.append(qRgba(   174, colCnt,      0, 0xFF)); // Rot  -> Gelb
                              m_colorTable.append(qRgba(colCnt,    174,      0, 0xFF)); // Grün -> Gelb
                              m_colorTable.append(qRgba(     0,    174, colCnt, 0xFF)); // Grün -> Türkis
                              m_colorTable.append(qRgba(colCnt,      0,    174, 0xFF)); // Blau -> Magenta
                              m_colorTable.append(qRgba(     0, colCnt,    174, 0xFF)); // Blau -> Türkis
                              m_colorTable.append(qRgba(   174,      0, colCnt, 0xFF)); // Rot  -> Magenta
                              colCnt+=2;
                          }
                      
                          m_colorTable.append(qRgba(255,   0,   0, 0xFF)); // Rot
                          m_colorTable.append(qRgba(255, 255,   0, 0xFF)); // Gelb
                          m_colorTable.append(qRgba(255,   0, 255, 0xFF)); // Magenta
                          m_colorTable.append(qRgba(  0, 255,   0, 0xFF)); // Grün
                          m_colorTable.append(qRgba(  0, 255, 255, 0xFF)); // Türkis
                          m_colorTable.append(qRgba(  0,   0, 255, 0xFF)); // Blau
                          m_colorTable.append(qRgba(100, 100, 100, 0xFF)); // Dunkelgrau
                          m_colorTable.append(qRgba(150, 150, 150, 0xFF)); // Hellgrau
                          m_colorTable.append(qRgba(255, 255, 255, 0xFF)); // Weiss
                          m_colorTable.append(qRgba(  0,   0,   0, 0xFF)); // Schwarz
                      

                      What colors do I have to use in the color table? Is there a rule that I can follow?
                      At the moment I searched for color tables with 256 values in the internet and found the values I used in the code above. But these values seem not to work ...
                      Can anyone explain me how I can know which colors I have to add to the color table?

                      Btw.: My goal is to detect red color in this image.

                      1 Reply Last reply
                      0
                      • O Offline
                        O Offline
                        ollarch
                        wrote on last edited by
                        #11

                        Hi,

                        Why are you using a 8 bit Indexed image? You can use the RGB Image format instead. The 8 bit Indexed image can only represent 256 color values and may not be the values you want.

                        "If I am using Rgb32 format, I do not set the color table. Then I receive the same values for red, green and blue."

                        This is the way to go.

                        M 1 Reply Last reply
                        0
                        • O ollarch

                          Hi,

                          Why are you using a 8 bit Indexed image? You can use the RGB Image format instead. The 8 bit Indexed image can only represent 256 color values and may not be the values you want.

                          "If I am using Rgb32 format, I do not set the color table. Then I receive the same values for red, green and blue."

                          This is the way to go.

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

                          @ollarch : Thanks for your answer.
                          In meanwhile I found out that the QVideoFrame comes in format YUV420P.
                          I think I have to convert this frame to a RGB image.
                          But at the moment this is not yet working properly...

                          1 Reply Last reply
                          0
                          • O Offline
                            O Offline
                            ollarch
                            wrote on last edited by
                            #13

                            @MHermann said in Get RGB value of pixel:

                            YUV420P

                            Well, if you want to get the pixel value on some position in the image you could get the pointer to the image bits "uchar* imageBits()" to get the bits of the internal data and then do the YUV to RGB conversion. This will be faster instead of converting the entire image to RGB, so it depends on what you want to achieve.

                            M 1 Reply Last reply
                            1
                            • O ollarch

                              @MHermann said in Get RGB value of pixel:

                              YUV420P

                              Well, if you want to get the pixel value on some position in the image you could get the pointer to the image bits "uchar* imageBits()" to get the bits of the internal data and then do the YUV to RGB conversion. This will be faster instead of converting the entire image to RGB, so it depends on what you want to achieve.

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

                              @ollarch : Thanks.
                              But at the moment I have the problem that I don't have a valid image.
                              I get a QVideoFrame in format QVideoFrame::Format_YUV420P.
                              I think I first have to convert this QVideoFrame to a QImage. And after that I want to search for red pixels in this image.
                              What is your advice? Can you tell me how I can get a RGB image? Or is it possible to get a YUV image and then search there for the red pixels?

                              O 1 Reply Last reply
                              0
                              • M MHermann

                                @ollarch : Thanks.
                                But at the moment I have the problem that I don't have a valid image.
                                I get a QVideoFrame in format QVideoFrame::Format_YUV420P.
                                I think I first have to convert this QVideoFrame to a QImage. And after that I want to search for red pixels in this image.
                                What is your advice? Can you tell me how I can get a RGB image? Or is it possible to get a YUV image and then search there for the red pixels?

                                O Offline
                                O Offline
                                ollarch
                                wrote on last edited by
                                #15

                                @MHermann The easiest way to search for red pixels would be to convert the image to RGB first. I don't know how to do the conversion but you can search for this conversion on your search engine. It will not be so difficult to get the RGB pixels from a YUV pixels. You also can look how OpenCV does the conversion.

                                Finally, for searching the red pixels, do you want only the pixels with R=255,G=0,B=0 ?

                                M 1 Reply Last reply
                                0
                                • O ollarch

                                  @MHermann The easiest way to search for red pixels would be to convert the image to RGB first. I don't know how to do the conversion but you can search for this conversion on your search engine. It will not be so difficult to get the RGB pixels from a YUV pixels. You also can look how OpenCV does the conversion.

                                  Finally, for searching the red pixels, do you want only the pixels with R=255,G=0,B=0 ?

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

                                  @ollarch : Ok. At the moment I try to do the conversion correctly.
                                  I am not sure if I want to search only for 255,0,0. Does this matter? Or do you mean that I can use V component of YUV then?

                                  O 1 Reply Last reply
                                  0
                                  • M MHermann

                                    @ollarch : Ok. At the moment I try to do the conversion correctly.
                                    I am not sure if I want to search only for 255,0,0. Does this matter? Or do you mean that I can use V component of YUV then?

                                    O Offline
                                    O Offline
                                    ollarch
                                    wrote on last edited by
                                    #17

                                    @MHermann I was only asking. I don't know how to work directly with the YUV components. I was thinking that getting only the (255,0,0) values on a real image will get you 0 pixels as you will not get a perfect red pixels on an image(could be but it will be strange).

                                    M 1 Reply Last reply
                                    0
                                    • O ollarch

                                      @MHermann I was only asking. I don't know how to work directly with the YUV components. I was thinking that getting only the (255,0,0) values on a real image will get you 0 pixels as you will not get a perfect red pixels on an image(could be but it will be strange).

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

                                      @ollarch : Ok. Now it works. I am doing the conversion from YUV to RGB. And then I am able to get the RGB values of each pixel.

                                      O 1 Reply Last reply
                                      0
                                      • M MHermann

                                        @ollarch : Ok. Now it works. I am doing the conversion from YUV to RGB. And then I am able to get the RGB values of each pixel.

                                        O Offline
                                        O Offline
                                        ollarch
                                        wrote on last edited by
                                        #19

                                        @MHermann now that you have a solution would be great to share your solution with other people to help them if they need to implement the same.

                                        M 1 Reply Last reply
                                        1
                                        • O ollarch

                                          @MHermann now that you have a solution would be great to share your solution with other people to help them if they need to implement the same.

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

                                          @ollarch : Of course. Maybe someone is interested in this:

                                          QImage convertFrameYUV420ToImageRGB888(QVideoFrame vidFrame)
                                          {
                                              vidFrame.map(QAbstractVideoBuffer::ReadOnly);
                                          
                                              unsigned char* pData = (unsigned char *) vidFrame.bits();
                                              unsigned char pDataRgb[vidFrame.width()*vidFrame.height()*3];
                                          
                                              int bytesPerLine = vidFrame.bytesPerLine();
                                              int numYBytes = vidFrame.width()*vidFrame.height();
                                              int numUBytes = numYBytes / 4;
                                              int idxY = 0;
                                              int idxU = numYBytes;
                                              int idxV = numYBytes+numUBytes;
                                              int dstIdx=0;
                                              for (int h=0; h<vidFrame.height(); h++) {
                                                  for (int w=0; w<vidFrame.width(); w++) {
                                          
                                                      idxY = h*bytesPerLine+w;
                                                      int y = pData[idxY];
                                          
                                                      idxU = (int)(numYBytes+(h/2)*(bytesPerLine/2)+w/2);
                                                      int u = pData[idxU];
                                          
                                                      idxV = (int)(numYBytes*1.25 + (h/2)*(bytesPerLine/2)+w/2);
                                                      int v = pData[idxV];
                                          
                                                      pDataRgb[dstIdx++] = y + 1.402 * (v-128);                   // r
                                                      pDataRgb[dstIdx++] = y - 0.344 * (u-128) - 0.714 * (v-128); // g
                                                      pDataRgb[dstIdx++] = y + 1.772 * (u-128);                   // b
                                                  }
                                              }
                                          
                                              vidFrame.unmap();
                                          
                                              QImage imgRgb (pDataRgb, vidFrame.width(), vidFrame.height(), QImage::Format_RGB888);
                                              return imgRgb;
                                          }
                                          

                                          And after that conversion go over all pixels in the image and access them via QImage::PixelColor().

                                          O 1 Reply Last reply
                                          0

                                          • Login

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