Отображение NumPy массивов с Matplotlib внутри WX - PullRequest
1 голос
/ 29 июня 2011

У меня есть огромный нудистский ndarray с формой (M x N x 3) и типом данных float32.Я хочу, чтобы изображение просто отображалось в wx.Frame, к которому прикреплено wx.ScrolledWindow.Я хочу, чтобы изображение было увеличено на 100%, и ОЧЕНЬ важно, чтобы не происходила потеря данных.Это рентгеновские изображения с высоким разрешением, которые ДОЛЖНЫ оставаться в виде значений с плавающей запятой.

Пока что возможности wx.Image не сработали, поскольку они будут принимать только ndarrays с 8-битными целыми числами.не хорошо.

Библиотека обработки изображений PIL также может обрабатывать только 8 бит, этого недостаточно.

Пока единственной библиотекой, которую я нахожу достаточной, является matplotlib, но у меня возникают проблемы с отображением matplotlib так, как я хочу.Это приближает меня:

class View(wx.Frame):  
    def __init__(self):
        wx.Frame.__init__(self,  
                          parent=None,  
                          title="DICOM Viewer",  
                          size=(1280, 750),  
                          pos=(0,0))  
        self.scroll = wx.ScrolledWindow(self, -1)
        self.figure = plt.Figure()  
        self.canvas = FigureCanvasWxAgg(self.scroll, -1, self.figure)  
        self.axes = Axes(self.figure, [0,1,0,1])       
        self.figure.figimage(ndarray)     
        self.sizer.Add(self.canvas, 1, wx.EXPAND)  
        self.scroll.SetSizer(self.sizer)

Функция figimage не будет отображать ничего, кроме необработанных пикселей, чего я и хочу, но она только заполняет видимую область wxFrame и работает очень медленно.Может быть, это проблема с моими виджетами wx?

Лучшим решением было использовать imshow как таковое:

class View(wx.Frame):  
    def __init__(self):
        wx.Frame.__init__(self,  
                          parent=None,  
                          title="DICOM Viewer",  
                          size=(1280, 750),  
                          pos=(0,0))  
        self.scroll = wx.ScrolledWindow(self, -1)  
        self.figure = plt.Figure()  
        self.canvas = FigureCanvasWxAgg(self.scroll, -1, self.figure)  
        self.axes = Axes(self.figure, [0,1,0,1])  
        self.axes = self.figure.add_subplot(111)  
        self.axes.imshow(ndarray)  
        self.sizer.Add(self.canvas, 1, wx.EXPAND)    
        self.scroll.SetSizer(self.sizer)

Однако, это дает мне много отступов вокруг графика, ненужных осей.и метки, и он автоматически масштабирует изображение, чтобы поместиться в видимой области.Пиксельное качество все еще там, но требует добавления панели инструментов mpl и ручного панорамирования, и вы можете потерять трек изображения, если вы панорамируете слишком далеко.

1 Ответ

1 голос
/ 30 июня 2011

Я нашел решение:

class View(wx.Frame):  
   def __init__(self):
     wx.Frame.__init__(self,  
                      parent=None,  
                      title="DICOM Viewer",  
                      size=(1280, 750),  
                      pos=(0,0))  
     self.scroll = wx.ScrolledWindow(self, -1)
     h, w, r = ndarray.shape
     self.figure = plt.Figure((w/72.0,h/72.0), 72)  #manually determine the figure size in inches
     self.canvas = FigureCanvasWxAgg(self.scroll, -1, self.figure)  
     self.axes = self.figure.add_axes([0.0, 0.0, 1.0, 1.0]) #size of axes to match size of figure
     self.axes.imshow(ndarray) 

Таким образом, ключом было вручную установить размер рисунка, равный полному размеру изображения в дюймах, а затем установить осидля фигуры того же размера.Это не позволило mpl автоматически изменить размер моего изображения в видимой области.Я также уронил размер, потому что я вручную измерил виртуальную область полосы прокрутки, фигуру и оси.Теперь, если бы я только мог избавиться от отступов фигуры наверху, я был бы готов.

...