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. RAW8 pixel format to QImage. A little problem...
QtWS25 Last Chance

RAW8 pixel format to QImage. A little problem...

Scheduled Pinned Locked Moved General and Desktop
qimageraw images
17 Posts 3 Posters 8.4k 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.
  • I Offline
    I Offline
    Insidious_Snot
    wrote on 26 Sept 2015, 13:00 last edited by Insidious_Snot
    #1

    Hi folks,

    I have a return image from a Camera device that I use. The type format is Image (it doesn't matter) and it's pixel format is RAW8.
    This is the only way to take full resolution from this camera (4096x2160) and also have some color there. In RGB format I have lower resolution and bad (really very bad -8fps) frame rate.
    So I want a good code advice to make it happen.

    Here is some code from my implementation;

    //Image thing just to show you the Format I get
     Image newImg;
        error = rawImage.Convert( PIXEL_FORMAT_RAW8, &newImg );
        if (error != PGRERROR_OK)
        {
            error.PrintErrorTrace();
            return false;
        }
    
    
    //This is the way I tried (but failed) to take the capture image
    QImage tmpImg( (uchar *)newImg.GetData(), width, height, width, QImage::Format_Indexed8);
     (*grabedFrame) = tmpImg.copy();
    
    
    //I also tried this way but the image I took was in gray-scale, with low frame rate and bad grey
    // lines (horizontal and vertical)
    static QVector<QRgb> colorTable;
              for (int i=0; i<256; i++)
                    colorTable.push_back(qRgb(i,i,i));
            
    // Create QImage with same dimensions as input image
            QImage tmpImg( (uchar *)newImg.GetData(), width, height, width, QImage::Format_Indexed8);
            tmpImg.setColorTable(colorTable);
            (*grabedFrame) = tmpImg.copy();
    
    //with .GetData I take the Image location in memory
    
    1 Reply Last reply
    0
    • C Offline
      C Offline
      codebit
      wrote on 27 Sept 2015, 01:35 last edited by codebit
      #2

      Make sure PIXEL_FORMAT_RAW8 is the same as indexed 8-bit format - write a for loop through the values of newImg.GetData() and see what are the max and min values. The values should be between 0 and 255.

      1 Reply Last reply
      0
      • I Offline
        I Offline
        Insidious_Snot
        wrote on 27 Sept 2015, 16:17 last edited by Insidious_Snot
        #3

        @codebit thanks for your answer!

        It is already in a loop and I've check it before. Each pixel is 8 bit long and (of course) it's values are from 0 to 255 (also checked before).

        The QImage class says in http://doc.qt.io/qt-4.8/qimage.html under the "Member Type Documentation" that "Note: Drawing into a QImage with QImage::Format_Indexed8 is not supported" and I think that this is responsible for our problem.

        C 1 Reply Last reply 27 Sept 2015, 17:58
        0
        • L Offline
          L Offline
          Leonardo
          wrote on 27 Sept 2015, 17:21 last edited by
          #4

          I'd say the problem is that data must be 32bit aligned, even if it's a 8bit format. See the constructor:

          http://doc.qt.io/qt-4.8/qimage.html#QImage-4

          You should align your raw data before passing it to QImage.

          1 Reply Last reply
          0
          • I Insidious_Snot
            27 Sept 2015, 16:17

            @codebit thanks for your answer!

            It is already in a loop and I've check it before. Each pixel is 8 bit long and (of course) it's values are from 0 to 255 (also checked before).

            The QImage class says in http://doc.qt.io/qt-4.8/qimage.html under the "Member Type Documentation" that "Note: Drawing into a QImage with QImage::Format_Indexed8 is not supported" and I think that this is responsible for our problem.

            C Offline
            C Offline
            codebit
            wrote on 27 Sept 2015, 17:58 last edited by
            #5

            @Insidious_Snot Your QImage is gray-scaled because you're creating a gray-scale palette in your colorTable. I'm not sure about your original Image class - does it have a palette info you can fetch and use instead of making your own gray-scale one?

            1 Reply Last reply
            0
            • I Offline
              I Offline
              Insidious_Snot
              wrote on 27 Sept 2015, 19:24 last edited by Insidious_Snot
              #6

              @Leonardo you are right. But how I do that? Make a QPalette for this and then get the Data. I'm a little confused (and also new in Qt so keep calm with my questions ;)...)

              @codebit you think that the way to have a solution is that I said to @Leonardo ?

              I think that its to much processing for live image and the fps will slow down :(.

              C 1 Reply Last reply 27 Sept 2015, 21:30
              0
              • L Offline
                L Offline
                Leonardo
                wrote on 27 Sept 2015, 20:30 last edited by
                #7

                @Insidious_Snot, you just need to pad your pixels, so each of them takes 4 bytes. Once I needed to use 24bit RGB data with QImage. Here's what I did:

                uchar* output = (uchar*) malloc(width*height*4);
                int in_size = width*height*3;
                
                for(int i = 0 , j = 0 ; i < in_size ; i += 3, j+= 4){
                
                	output[j] = input[i];
                	output[j+1] = input[i+1];
                	output[j+2] = input[i+2];
                	output[j+3] = 0;
                
                }
                
                QImage img(output, width, height, QImage::Format_RGB32, free, output);
                

                If you're doing live processing, maybe you should consider working on the raw data yourself, instead of relying on QImage. Or maybe you could use some more specialized library, like OpenCV.

                1 Reply Last reply
                0
                • I Insidious_Snot
                  27 Sept 2015, 19:24

                  @Leonardo you are right. But how I do that? Make a QPalette for this and then get the Data. I'm a little confused (and also new in Qt so keep calm with my questions ;)...)

                  @codebit you think that the way to have a solution is that I said to @Leonardo ?

                  I think that its to much processing for live image and the fps will slow down :(.

                  C Offline
                  C Offline
                  codebit
                  wrote on 27 Sept 2015, 21:30 last edited by
                  #8

                  @Insidious_Snot No, QPalette is for the window system. What I'm saying you should look at the documentation of Image::Convert( PIXEL_FORMAT_RAW8, &newImg ) and figure what it creates. Chances are it creates a gray-scaled 8-bit indexed image (in this case your code is right) or it creates a colored 8-bit indexed image in which case it should provide you with the palette that is being used.
                  We have no clue where this Image class comes from :)

                  1 Reply Last reply
                  0
                  • I Offline
                    I Offline
                    Insidious_Snot
                    wrote on 28 Sept 2015, 08:51 last edited by Insidious_Snot
                    #9

                    @codebit the reference for PIXEL_FORMAT_RAW8 at camera's API is;

                    PIXEL_FORMAT_RAW8 = 0x00400000, /**< 8 bit raw data output of sensor. */

                    Also full description for Image::Convert(...) is;

                             * Converts the current image buffer to the specified output format and
                             * stores the result in the specified image. The destination image 
                             * does not need to be configured in any way before the call is made.
                             *
                             * @param format Output format of the converted image.
                             * @param pDestImage Destination image.
                             *
                             * @return An Error indicating the success or failure of the function.
                             */ 
                            virtual Error Convert( 
                                PixelFormat format, 
                                Image*      pDestImage ) const;
                    

                    The camera constructor makes clear that I can use it's full resolution only with that pixel format. As I see in the test program that come with the device, the pix format is RAW8 and I have color image.

                    Forthwith I tried to make the conversion to RGB format (RGB for Camera's API 24bit and RGB888 for Qt) and I have the live image in resolution I want but in very low frame rate which caused by data processing and not from camera setting.

                    @Leonardo thanks for your help and your code ;). Unfortunately it doesn't works. It appears the image above:

                    http://bit.ly/1Vie335

                    Of course I didn't use your code block unchanged but I made the suitable mods in order to work correctly with the rest code. Take a look here;

                        uchar* output = (uchar*) malloc(width*height*4);
                        int in_size = width*height*3;
                        int j;
                        for(int i = 0 , j = 0 ; i < in_size ; i += 3, j+= 4)
                        {
                            output[j] = (uchar)newImg[i];
                            output[j+1] = (uchar)newImg[i+1];
                            output[j+2] = (uchar)newImg[i+2];
                            output[j+3] = 0;
                        }
                        (*grabedFrame) = img.copy();```
                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      Leonardo
                      wrote on 28 Sept 2015, 13:31 last edited by
                      #10

                      Hi. Show your code, please.

                      I 1 Reply Last reply 28 Sept 2015, 13:42
                      0
                      • L Leonardo
                        28 Sept 2015, 13:31

                        Hi. Show your code, please.

                        I Offline
                        I Offline
                        Insidious_Snot
                        wrote on 28 Sept 2015, 13:42 last edited by
                        #11

                        @Leonardo I 've mod my previews answer. See there!

                        1 Reply Last reply
                        0
                        • L Offline
                          L Offline
                          Leonardo
                          wrote on 28 Sept 2015, 13:53 last edited by
                          #12

                          Hi. Since you're using a 8bit image, your input is 1 byte per pixel. So:

                          uchar* output = (uchar*) malloc(width*height*4);
                          int in_size = width*height;
                          int j;
                          for(int i = 0 , j = 0 ; i < in_size ; i++, j+= 4)
                          {
                              output[j] = (uchar)newImg[i];
                              output[j+1] = 0;
                              output[j+2] = 0;
                              output[j+3] = 0;
                          }
                          
                          I 1 Reply Last reply 28 Sept 2015, 14:05
                          0
                          • L Leonardo
                            28 Sept 2015, 13:53

                            Hi. Since you're using a 8bit image, your input is 1 byte per pixel. So:

                            uchar* output = (uchar*) malloc(width*height*4);
                            int in_size = width*height;
                            int j;
                            for(int i = 0 , j = 0 ; i < in_size ; i++, j+= 4)
                            {
                                output[j] = (uchar)newImg[i];
                                output[j+1] = 0;
                                output[j+2] = 0;
                                output[j+3] = 0;
                            }
                            
                            I Offline
                            I Offline
                            Insidious_Snot
                            wrote on 28 Sept 2015, 14:05 last edited by Insidious_Snot
                            #13

                            @Leonardo it returns me that now ;
                            http://bit.ly/1LJPXIo

                                uchar* output = (uchar*) malloc(width*height*4);
                                int in_size = width*height;
                                int j;
                                for(int i = 0 , j = 0 ; i < in_size ; i++, j+= 4)
                                {
                                    output[j] = (uchar)newImg[i];
                                    output[j+1] = 0;
                                    output[j+2] = 0;
                                    output[j+3] = 0;
                                }
                                QImage img(output, width, height, QImage::Format_RGB32, free, output);
                                (*grabedFrame) = img.copy();
                            
                            1 Reply Last reply
                            0
                            • L Offline
                              L Offline
                              Leonardo
                              wrote on 28 Sept 2015, 14:17 last edited by
                              #14

                              Oh, I see the constructors available for Qt 4.8 are different. The one in my code is for Qt 5.5. I didn't know this one in which you can specify the number of bytes per line. You were right from the start. Your first code should work, according to the documentation.

                                       QImage tmpImg( (uchar *)newImg.GetData(), width, height, width, QImage::Format_Indexed8);
                              

                              I'm interested in this issue. Would you mind dumping your raw data to a file and posting it here? I'd like to try it later.

                              I 1 Reply Last reply 28 Sept 2015, 15:28
                              0
                              • I Offline
                                I Offline
                                Insidious_Snot
                                wrote on 28 Sept 2015, 14:21 last edited by Insidious_Snot
                                #15
                                    uchar* output = (uchar*) malloc(width*height*4);
                                    int in_size = width*height;
                                    int j;
                                    for(int i = 0 , j = 0 ; i < in_size ; i++, j+= 4)
                                    {
                                        output[j] = (uchar)newImg[i];
                                        output[j+1] = 0;
                                        output[j+2] = 0;
                                        output[j+3] = 0;
                                    }
                                    QImage img(output, width, height, width, QImage::Format_RGB32, free, output);
                                    (*grabedFrame) = img.copy();
                                

                                And returns me that : http://bit.ly/1L0fHzz

                                Of course! I would try to get it now...

                                1 Reply Last reply
                                0
                                • L Leonardo
                                  28 Sept 2015, 14:17

                                  Oh, I see the constructors available for Qt 4.8 are different. The one in my code is for Qt 5.5. I didn't know this one in which you can specify the number of bytes per line. You were right from the start. Your first code should work, according to the documentation.

                                           QImage tmpImg( (uchar *)newImg.GetData(), width, height, width, QImage::Format_Indexed8);
                                  

                                  I'm interested in this issue. Would you mind dumping your raw data to a file and posting it here? I'd like to try it later.

                                  I Offline
                                  I Offline
                                  Insidious_Snot
                                  wrote on 28 Sept 2015, 15:28 last edited by
                                  #16

                                  @Leonardo here is the Raw8 data : http://bit.ly/1WtnXMg

                                  I have put spaces and lines in order to make it easier to read. Each line has length == columns/2 (cause the spaces I put).

                                  1 Reply Last reply
                                  0
                                  • L Offline
                                    L Offline
                                    Leonardo
                                    wrote on 28 Sept 2015, 21:34 last edited by
                                    #17

                                    Hi. Well, it's working. Here's what I've done:

                                    QFile f("D:/img.bin");
                                    
                                    if(f.open(QIODevice::ReadOnly)){
                                    
                                        QByteArray b = f.readAll();
                                    
                                        QImage img((const uchar*) b.constData(), 4096, 2160, 4096, QImage::Format_Indexed8);
                                    
                                        QVector<QRgb> colorTable;
                                        for (int i = 0; i < 256; i++){
                                            colorTable.push_back(qRgb(i,i,i));
                                        }
                                    
                                        img.setColorTable(colorTable);
                                    
                                        img.save("D:/img.png");
                                    
                                        f.close();
                                    
                                    }
                                    

                                    And here's what I got:

                                    1 Reply Last reply
                                    0

                                    1/17

                                    26 Sept 2015, 13:00

                                    • Login

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