Results 1 to 6 of 6

Thread: 10 - 12 bit grayscale QImage format display

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2020
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Question 10 - 12 bit grayscale QImage format display

    Greetings,

    Some scientific camera capture grayscale images at 10, 12 and 16 bits in addition to the common 8 bit format.
    Such formats are little-endian and encode each pixels into 2 Bytes - the unused bits are set to zero.
    Of course the 8bit grayscale pixel only requires 1 Byte.

    The problem is that even with the newly introduced Grayscale 16 QImage format (>=Qt5.14), 10 and 12 bits per pixels grayscale images can't be properly displayed within QPainter without first processing the whole image.

    The 8bit image is displayed just fine:
    Qt Code:
    1. painter->drawImage(
    2. transformedRect,
    3. (const unsigned char*) _image.memory,
    4. _image.width,
    5. _image.height,
    6. QImage::Format_Grayscale8));
    To copy to clipboard, switch view to plain text mode 

    Even the 16bit shows no problems, decoding the char memory 2 Bytes per pixel:
    Qt Code:
    1. painter->drawImage(
    2. transformedRect,
    3. (const unsigned char*) _image.memory,
    4. _image.width,
    5. _image.height,
    6. QImage::Format_Grayscale16));
    To copy to clipboard, switch view to plain text mode 

    However I have no solution for what is in between. As expected, the Grayscale16 format loads the QImage just fine, but since the expected maximum brightness value of 2^16 is much higher than 2^12 and more so than 2^10, the displayed image is very dark.
    Working on the image pixels is not an option because it is more time consuming than the Grayscale16 format.

    The QImage pixelColor method clearly shows how this decoding is done (but it is highly unlikely that this is the exact method used by QPainter as it is not optimized at all):
    Qt Code:
    1. QColor QImage::pixelColor(int x, int y) const
    2. {
    3. if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
    4. qWarning("QImage::pixelColor: coordinate (%d,%d) out of range", x, y);
    5. return QColor();
    6. }
    7. QRgba64 c;
    8. const uchar * s = constScanLine(y);
    9. switch (d->format) {
    10. case Format_BGR30:
    11. case Format_A2BGR30_Premultiplied:
    12. c = qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
    13. break;
    14. case Format_RGB30:
    15. case Format_A2RGB30_Premultiplied:
    16. c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
    17. break;
    18. case Format_RGBX64:
    19. case Format_RGBA64:
    20. case Format_RGBA64_Premultiplied:
    21. c = reinterpret_cast<const QRgba64 *>(s)[x];
    22. break;
    23. case Format_Grayscale16: {
    24. quint16 v = reinterpret_cast<const quint16 *>(s)[x];
    25. return QColor(qRgba64(v, v, v, 0xffff));
    26. }
    27. default:
    28. c = QRgba64::fromArgb32(pixel(x, y));
    29. break;
    30. }
    31. // QColor is always unpremultiplied
    32. if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied)
    33. c = c.unpremultiplied();
    34. return QColor(c);
    35. }
    To copy to clipboard, switch view to plain text mode 

    It's just how data is reinterpreted.
    However, I don't really want to tamper with the built-in Qt classes.

    The other idea I had is to alter the on-screen pixel with some sort of QPainter color-space transformation. I have tried composition to enhance brightness and contrast but failed. It was acceptable computationally-wise though, so maybe it is the right path to follow.

    I feel like I'm missing something obvious since 10 and 12bits images are commonly used in medical appliances.
    What should I do to correctly display such images at the same speed as 16bits images?

    Thanks

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,328
    Thanks
    317
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: 10 - 12 bit grayscale QImage format display

    Are these static images or a video stream?

    If they are static, can't you simply shift each 16-bit word by 4 or 6 bits before constructing the QImage? You will still never get to full brightness unless you also set the low-order bits to 1, but then in that case you'd never get full black either. Another option would be to multiply every word by the ratio of 16 / n, where n is 10 or 12. This would expand the word values to cover the full range and you would get both true white and black.

    If you really need speed, this transformation is something you could do in parallel, either through multiple threads that each work on part of the image or using a CUDA transformation on a video card to do the entire array in one operation.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. const char* QImage Format?
    By grabalon in forum Newbie
    Replies: 2
    Last Post: 13th May 2010, 00:44
  2. QImage Non-Standard Format Probem
    By photo_tom in forum Qt Programming
    Replies: 3
    Last Post: 19th February 2010, 08:06
  3. QImage, get file format
    By greenvirag in forum Qt Programming
    Replies: 6
    Last Post: 29th December 2008, 13:13
  4. How to display 16 bit grayscale pictures?
    By reimer in forum Qt Programming
    Replies: 5
    Last Post: 20th August 2008, 19:55
  5. QImage Format Issue
    By vishal.chauhan in forum Qt Programming
    Replies: 7
    Last Post: 9th March 2007, 10:14

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.