在处理大型图像堆栈时,我陷入了wxAssertionError问题(如下所示)。让我举例说明。
我已经使用只有面板,按钮和量规的wxPython制作了一个界面。
用户单击按钮后,代码将读取一堆8位二进制图像(1500 x 100 x 50),在面板上显示第一张图像并开始处理该堆栈。处理步骤意味着一个循环,在该循环中,将来自堆栈的每个图像标记并绘制在图中(不在面板中)。该图将保存并在每次迭代中关闭。代码如下所示:
# Label and save big image stack
import wx
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
class CanvasPanelA1(wx.Panel):
def __init__(self,parent,ID):
wx.Panel.__init__(self,ID,style=wx.SUNKEN_BORDER)
self.figure = Figure()
self.figure.set_facecolor("BLACK")
self.canvas = FigureCanvas(self,-1,self.figure)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas,1,wx.LEFT | wx.TOP | wx.EXPAND)
self.SetSizer(self.sizer)
self.Fit()
def OnPlot(self,event):
self.frame = frame
from numpy import amin,amax
self.vmin = amin(frame.video)
self.vmax = amax(frame.video)
self.nframes = frame.video.shape[0]
self.axes = self.figure.add_subplot(111)
self.axes.imshow(frame.video[0],cmap='gray',vmin=self.vmin,vmax=self.vmax)
self.axes.axis('off')
self.canvas.draw()
self.SetSizer(self.sizer)
frame.Layout()
class MyFrame(wx.Frame):
def __init__(self,title):
wx.Frame.__init__(self,title)
self.panel = CanvasPanelA1(self,wx.ID_ANY)
self.panel.SetMinSize((200,200))
self.button_RUN = wx.Button(self,label="Run")
self.gauge = wx.Gauge(self,range = 100,size = (250,25),style = wx.GA_HORIZONTAL)
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(self.panel,3,wx.EXPAND)
mainSizer.Add(self.button_RUN,flag=wx.CENTER|wx.ALL)
mainSizer.Add(self.gauge,flag=wx.CENTER|wx.EXPAND)
self.button_RUN.Bind(wx.EVT_BUTTON,self.OnRun)
self.SetSizer(mainSizer)
self.SetautoLayout(True)
self.Layout()
def OnRun(self,event):
from skimage.color import label2rgb
from skimage.measure import label
import matplotlib as mpl
import matplotlib.pyplot as plt
from skimage import io
from skimage.util import img_as_ubyte
#read video
video_name = './video1.tif'
self.video = io.imread(video_name,as_gray=False,plugin='tifffile')
self.video = img_as_ubyte(self.video)
self.nframes = self.video.shape[0]
self.gauge.SetRange(self.nframes-1)
#show one image on panel
self.panel.OnPlot(wx.EVT_DISPLAY_CHANGED)
self.panel.Refresh()
plt.ioff()
for fr in range(self.nframes):
print('frame=',fr)
label_image = label(self.video[fr],background=0)
image_label_overlay = label2rgb(label_image,bg_label=0)
fig,ax = plt.subplots(figsize=(10,6))
ax.imshow(image_label_overlay)
plt.axis('off')
imname = 'imgout'+str(fr).zfill(len(str(self.nframes)))+'.tif'
output_path = './Outputs/'+imname
plt.savefig(output_path,bbox_inches='tight',facecolor='black',edgecolor='none')
plt.close(fig)
self.gauge.Setvalue(fr)
plt.ion()
app = wx.App()
frame = MyFrame(None,"Label videos")
frame.Show()
app.MainLoop()
到目前为止,此代码在较小的堆栈上仍然有效,但是一旦我提供的图像堆栈大于〜1250帧,就会出现以下错误:
File "C:\Users\...\lib\site-packages\matplotlib\backends\backend_wx.py",line 1413,in _init_toolbar
self.Realize()
**wxAssertionError**: C++ assertion "Assert failure" failed at ..\..\src\msw\toolbar.cpp(938) in wxToolBar::Realize(): Could not add bitmap to toolbar
由于此错误似乎与工具栏有关,因此我不使用它,因此我尝试使用mpl.rcParams['toolbar'] = 'None'
来禁用它,并将其放在循环之前,但是随后出现另一个AssertionError:
File "C:\Users\...\lib\site-packages\matplotlib\backends\backend_wx.py",line 1585,in __init__
self.setfieldsCount(2)
**wxAssertionError**: C++ assertion "m_hdc" failed at ..\..\src\msw\textmeasure.cpp(64) in wxTextMeasure::Beginmeasuring(): Must not be used with non-native wxDCs
我还尝试使用wx.CallAfter(self.gauge.Setvalue,fr)
来避免在绘制和保存图像时更新主界面,但是效果不佳。
有人知道是什么原因造成的吗?
以下是我的软件包版本:
康达4.4.1
python 3.6.8
wxPython 4.0.6
间谍3.3.6
scikit-image 0.15.0
matplotlib 3.1.1
numpy 1.16.4