我在 wxPython 面板中有一个图像,我想通过选择 Matplotlib 来编辑它RectangleSelector
。我有一个Image_Viewer
绘制图像的类。我有一个Editor
类,RectangleSelector
功能所在的位置。Editor
继承自Image_Viewer
。最后,控制面板包含文件选择器按钮。该程序从通过Image_Viewer
绘图函数加载的默认图像开始。我可以RectangleSelector
很好地使用。但是当我加载一个新图像时,它也通过Image_Viewer
绘图功能加载,所有连接都RectangleSelector
消失了。
我试图尽可能地减少代码,但整个代码是多标签笔记本的一部分,因此存在wx.lib.agw.aui
其他可能的特质。
import os
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import wx
import wx.lib.agw.aui as aui
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
from matplotlib.patches import Rectangle
# ------------------variables-------------------
# Base path
pth = os.path.dirname(os.path.abspath('__file__'))
# folder for gui graphics
gui_graphics = pth + '/gui_graphics'
# temp file for initial image handling
img_pth = os.path.join(pth, "tmp_img.png")
# Folders, subfolders for processed images
all_cats = pth + '/Cats'
new_cats = all_cats + '/new_cats'
min_img_wndw = 295 # min size of top panels
img_y, img_x = 64, 64 # raw cat size
class Image_Viewer(wx.Panel):
def __init__(self, parent):
super(Image_Viewer, self).__init__(parent)
#load image
im_pth = new_cats + '/av_cat'
files = os.listdir(im_pth)
im_pths = [os.path.join(im_pth, im_name) for im_name in files]
try:
self.img = max(im_pths, key=os.path.getctime)
self.image = cv.imread(self.img)
except:
self.image = np.zeros((img_x, img_y), np.uint8)
self.figure = Figure()
self.draw(self.image)
def draw(self, image):
plt.close(self.figure)
self.figure.clf()
self.axes = self.figure.add_axes([0, 0, 1, 1])
self.axes.axis('off')
self.canvas = FigureCanvas(self, -1, self.figure)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self.axes.imshow(image, cmap='gray', vmin=0, vmax=255)
self.canvas.draw()
class Editor(Image_Viewer):
def __init__(self, parent):
super(Editor, self).__init__(parent)
self.RS = RectangleSelector(self.axes, self.on_click,
drawtype='box', useblit=True,
button=[1, 3], # don't use middle button
minspanx=5, minspany=5,
spancoords='pixels',
interactive=True)
#self.canvas.draw()
cid = self.canvas.mpl_connect('MouseEvent', self.on_click)
print(cid)
def on_click(self, eclick, erelease):
print("You clicked")
'eclick and erelease are the press and release events'
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
w = int(x2-x1)
h = int(y2 - y1)
class control_Panel(wx.Panel):
def __init__(self, parent, image_panel): #, image_panel, terminal_panel
wx.Panel.__init__(self, parent=parent)
#self.panel = wx.Panel(self, -1, size=(580, 180))
self.screen = image_panel
self.pth = os.path.dirname(os.path.abspath('__file__'))
fileDlgBtn = wx.Button(self, label="Get Cats")
fileDlgBtn.Bind(wx.EVT_BUTTON, self.OnOpen)
def OnOpen(self, event):
with wx.FileDialog(self, "Open image file", wildcard="PNG files (*.png)|*.png",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind
# Proceed loading the file chosen by the user
pathname = fileDialog.GetPath()
image = cv.imread(pathname)
self.screen.draw(image)
class explorer_panel(wx.Panel):
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
bSplitter = wx.SplitterWindow(self)
image_panel = Editor(bSplitter)
panelThree = control_Panel(bSplitter, image_panel)
bSplitter.SplitHorizontally(image_panel, panelThree)
bSplitter.SetSashGravity(0.5)
bSplitter.SetMinimumPaneSize(min_img_wndw)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(bSplitter, 1, wx.EXPAND)
self.SetSizer(sizer)
class Main(wx.Frame):
def __init__(self):
wx.Frame.__init__(
self,
parent = None,
title = "Borges Infinite Image",
size = (600,550)
)
self.SetIcon(wx.Icon(gui_graphics + '/Abe.png'))
panel = wx.Panel(self)
notebook = aui.AuiNotebook(panel)
explorer = explorer_panel(notebook)
notebook.AddPage(explorer, 'Explorer')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
panel.SetSizer(sizer)
if __name__ == "__main__":
app = wx.App()
frame = Main()
frame.Show()
app.MainLoop()