I am trying to convert a numpy array (cv2 image) to a wxpython Bitmap and display it properly. I have looked into various solutions on SO and elsewhere, but without success. You can see two of my attempts in the code below.
import wx
import cv2
import numpy as np
def create_wx_bitmap(cv2_image):
# type: (np.ndarray) -> wx.Bitmap
# My Attempt based on https://stackoverflow.com/questions/32995679/converting-wx-bitmap-to-numpy-using-bitmapbufferformat-rgba-python/32995940#32995940
height, width = cv2_image.shape[:2]
array = cv2_image # the OpenCV image
image = wx.Image(width, height)
image.SetData(array.tobytes())
wxBitmap = image.ConvertToBitmap()
return wxBitmap
# My other attempt:
# height, width = cv2_image.shape[:2]
# cv2_image_rgb = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
# return wx.Bitmap.FromBuffer(width, height, cv2_image_rgb)
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title)
cv2_image = cv2.imread("test1.png", cv2.IMREAD_ANYDEPTH | cv2.IMREAD_COLOR) # type: np.ndarray
print(cv2_image.dtype)
bitmap = create_wx_bitmap(cv2_image) # type: wx.Bitmap
wx.StaticBitmap(self, -1, bitmap, (0, 0), self.GetClientSize())
self.SetSize(bitmap.GetSize())
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame(None, "wxPython with OpenCV")
frame.Show()
app.MainLoop()
The code above seems to work for images under 16-bit (24 bit depth). However, an image that has a bit depth of 64 results in banding like the below screenshot. (which was a render from Blender 3D exported with 16 bit depth setting):

I have also tried converting the array datatype, but it didn't seem to make any difference.
Edit (The Final Solution):
The solution to my problem was to convert the array to np.uint8 after normalizing the data as mentioned in this SO answer. Thanks to @PetrBlahos for mentioning that the data needs to be 8bit RGB in his answer.
def create_wx_bitmap(cv2_image):
# type: (np.ndarray) -> wx.Bitmap
height, width = cv2_image.shape[:2]
info = np.iinfo(cv2_image.dtype) # Get the information of the incoming image type
data = cv2_image.astype(np.float64) / info.max # normalize the data to 0 - 1
data = 255 * data # Now scale by 255
cv2_image = data.astype(np.uint8)
cv2_image_rgb = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
return wx.Bitmap.FromBuffer(width, height, cv2_image_rgb)