2011-06-29 3 views
1

У меня есть огромный nump ndarray с формой (M x N x 3) и datatype float32. Я хочу, чтобы изображение просто отображалось в wx.Frame с прикрепленным wx.ScrolledWindow. Я хочу, чтобы изображение было на 100% увеличено, и ОЧЕНЬ важно, чтобы потери данных не происходили. Это супер-hi-res-рентгеновские изображения, которые NEED должны оставаться значениями с плавающей запятой.Отображение массивов numpy с matplotlib внутри wx

До сих пор возможности 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

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

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 от автоматического изменения размера изображения до области видимости. Я также сбросил sizer, потому что я вручную определял виртуальную область прокрутки, фигуру и оси. Теперь, если бы я мог избавиться от отступов фигуры наверху, все было бы готово.

Смежные вопросы