首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正确显示wxpython中的numpy数组cv2图像

正确显示wxpython中的numpy数组cv2图像
EN

Stack Overflow用户
提问于 2020-12-14 04:26:42
回答 1查看 931关注 0票数 2

我正在尝试将numpy数组(cv2图像)转换为wxpython,并正确地显示它。我研究过各种解决办法,但都没有成功。您可以在下面的代码中看到我的两次尝试。

代码语言:javascript
运行
复制
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()

上面的代码似乎适用于16位以下的图像(24位深度).然而,有64位深度的图像会导致像下面的屏幕截图一样的显带。(这是一个来自Blender 3D的渲染,有16位深度设置):

我也尝试过转换数组数据类型,但这似乎没有什么区别。

编辑(最终解决方案):

解决我的问题的方法是,在规范了np.uint8中提到的数据之后,将数组转换为this SO answer。感谢@PetrBlahos在他的回答中提到数据需要8位RGB。

代码语言:javascript
运行
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-14 07:21:15

我使用

代码语言:javascript
运行
复制
dc.DrawBitmap(wx.Bitmap.FromBuffer(iw, ih, cv_image), 0, 0)

但是cv_image必须是rgb值的numpy字节数组。因此,无论您做什么,都必须将数据转换为8位RGB (或者可能是RGBA,使用FromBufferRGBA)。我不太明白你的数据是如何组织的。64位意味着您有4个通道(RGBA),每个通道是16b整数?

我认为您可以使用cv2.convertScaleAbs,或者使用convertTo。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65283588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档