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.

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Tabasco
  • 35
  • 6
  • Does this answer your question? [Opencv Python display raw image](https://stackoverflow.com/questions/18682830/opencv-python-display-raw-image) – YScharf Jul 31 '22 at 11:50
  • this has everything to do with Qt and numpy, but nothing to do with OpenCV. I've adjusted the tags. – Christoph Rackwitz Jul 31 '22 at 12:53

1 Answers1

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
bzu
  • 1,242
  • 1
  • 8
  • 14
  • there is no such format as Format_Grayscale16 unfortunately :( – Tabasco Aug 01 '22 at 02:39
  • According to the docs, it was added in Qt 5.13. Which version are you using? – bzu Aug 01 '22 at 15:21
  • @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. – bzu Aug 02 '22 at 17:04