0

I'm new to Python and have sorta c++ style coding background.

In short:

  • tring to display 16 bit grayscale images in my GUI(pyqt6)
  • have the stored the image data in bytearray, that is, 1024 by 768 (the total size of the byte array would be 1024 x 768 x 2 since it's 16 bit).
  • having difficulties with using this data = bytearray(1572864) for displaying.

The following code is what I have used for displaying the same image (but downscaled to 8-bit). What I'm now trying to do is use the 16-bit data and have it converted to QPixmap in order to display.

The code for displaying 8-bit raw image is ( I have used rawpy for this, please feel free to get rid of the rawpy section if you could come up with a better way to do this)

raw = np.array( binary data read from file)
src = raw.postprocess()
buf = src.data.tobytes()
h, w, ch = src.shape
bytesperline = ch * w
image = QImage(buf, 1024, 768, bytesperline, QImage.Format_RGB888)
self.DisplayRect.setPixmap(QPixmap.fromImage(image))
self.DisplayRect.show()

Hope I explained my question without causing any confusion. In summary:

  • trying to use data in bytearray(1572864) to display in my GUI
  • in need of help with manipulating the binary data from/to different data structures

What I would have done if it were c++:

//declare a Mat with 16UC1 format
//easily memcpy(mat.data, source, size);
//stretchDiBits(dc, where_to_draw_imgs, mat.data);

Thank you very much in advance.

2
  • Does this answer your question? Opencv Python display raw image Commented Jul 31, 2022 at 11:50
  • this has everything to do with Qt and numpy, but nothing to do with OpenCV. I've adjusted the tags. Commented Jul 31, 2022 at 12:53

1 Answer 1

0

Versions of Qt >= 5.13 include QImage.Format_Grayscale16:

# load 8-bit image with size w x h
raw8 = Path('image8.raw').read_bytes()  
image8 = QImage(raw8, w, h, w, QImage.Format_Grayscale8)

# load 16-bit image, note 2 * w bytes per line!
raw16 = Path('image16.raw').read_bytes()  
image16 = QImage(raw16, w, h, 2 * w, QImage.Format_Grayscale16)

For conversion and scaling between formats, you can use:

scale = lambda b, r1, r2: int((2 ** r2 - 1) * b / (2 ** r1 - 1))

data8 = bytes([0, 64, 128, 255])
data16 = b''.join(scale(b, 8, 16).to_bytes(2, 'little') for b in data8)
data8_restored = bytes(scale(int.from_bytes(data16[i:i + 2], 'little'), 16, 8) for i in range(0, len(data16), 2))
# change 'little' to 'big' if needed
Sign up to request clarification or add additional context in comments.

3 Comments

there is no such format as Format_Grayscale16 unfortunately :(
According to the docs, it was added in Qt 5.13. Which version are you using?
@Tabasco I tested this on PyQt 5.15.7 and works OK (the images look the same). I added also an example how to scale from 8 to 16-bit in case you want to try to transform data yourself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.