class smileiQtPlot(QWidget): scalarDict = dict() fieldDict = dict() phaseDict = dict() fieldFile = None phaseFile = None nplots = 0 ax = {} dirName = None someCheckBoxChanged = False pauseSignal = pyqtSignal() shiftPressed = False title = '' def __init__(self, parent, dirName): super(smileiQtPlot, self).__init__() self.setParent(parent) uiFile = os.path.dirname( os.path.realpath(__file__)) + '/smileiQtPlot.ui' self.ui = uic.loadUi(uiFile, self) self.dirName = dirName self.parent = parent self.parent.timer.timeout.connect(self.next) self.parent.ui.next.released.connect(self.next) self.parent.ui.previous.released.connect(self.previous) self.parent.ui.first.released.connect(self.first) self.parent.ui.last.released.connect(self.last) self.pauseSignal.connect(self.parent.pause) self.setWindowFlags(Qt.Window) self.setWindowTitle(dirName) self.step = 0 self.ui.savePoints.setIcon(self.ui.style().standardIcon( QStyle.SP_DialogSaveButton)) self.ui.savePoints.released.connect(self.doSavePoints) self.ui.tabWidget.currentChanged.connect(self.changeTab) self.ui.autoScale.stateChanged.connect(self.doPlots) self.fig = Figure() self.canvas = FigureCanvas(self.fig) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.mpl_connect('motion_notify_event', self.on_movement) self.canvas.mpl_connect('key_press_event', self.on_key_press) self.canvas.mpl_connect('key_release_event', self.on_key_release) self.canvas.mpl_connect('button_press_event', self.on_button_press) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.setFixedHeight(18) self.canvas.setCursor(Qt.CrossCursor) self.ui.plotLayout.addWidget(self.canvas) self.ui.plotLayout.addWidget(self.toolbar) fname = os.path.join(dirName, "scalars.txt") if os.path.isfile(fname): self.scalarData = np.loadtxt(fname) names = [] for line in open(fname): li = line.strip() if li.startswith("#"): list = line.split() names.append(list[-1]) scalars_names = names[1:-2] for i in range(len(scalars_names)): my_button = QCheckBox(scalars_names[i]) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutScalars.addWidget(my_button) self.ui.layoutScalars.addStretch() else: print "Problem reading ", fname # self.deleteLater() self.fieldSteps = [] fname = os.path.join(dirName, "Fields.h5") if os.path.isfile(fname): self.fieldFile = tb.openFile(fname) self.res_space = self.fieldFile.root._v_attrs.res_space[0] self.res_time = self.fieldFile.root._v_attrs.res_time self.sim_length = self.fieldFile.root._v_attrs.sim_length self.fieldEvery = self.fieldFile.root._v_attrs.every first = True for group in self.fieldFile.listNodes("/", classname='Group'): self.fieldSteps.append(group._v_name) if first: first = False for array in group: my_button = QCheckBox(array._v_name) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutFields.addWidget(my_button) self.ui.layoutFields.addStretch() self.ui.slider.setRange(0, len(self.fieldSteps) - 1) else: print "Problem reading ", fname # self.deleteLater() self.ui.spinStep.setSuffix("/" + str(len(self.fieldSteps) - 1)) self.ui.spinStep.setMaximum(len(self.fieldSteps) - 1) fname = os.path.join(dirName, "PhaseSpace.h5") if os.path.isfile(fname): self.phaseFile = tb.openFile(fname) for phaseData in self.phaseFile.walkNodes("/", classname='Array'): my_button = QCheckBox(phaseData._v_pathname) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutPhase.addWidget(my_button) self.ui.layoutPhase.addStretch() else: print "Problem reading ", fname # self.deleteLater() self.load_settings() if sys.platform == "darwin": self.raise_() self.show() def doSavePoints(self): fname = QFileDialog.getSaveFileName(self, 'Save Point logger', self.dirName, selectedFilter='*.txt') if fname: f = open(fname, 'w') f.write(self.ui.logger.toPlainText()) f.close() def checkBoxChanged(self): self.someCheckBoxChanged = True def load_settings(self): settings = QSettings(QFileInfo(__file__).fileName(), "") settings.beginGroup(QDir(self.dirName).dirName()) frames = [self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase]: settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): chkbox.setChecked(settings.value(chkbox.text()).toBool()) settings.endGroup() settings.endGroup() self.ui.tabWidget.setCurrentIndex(0) def save_settings(self): settings = QSettings(QFileInfo(__file__).fileName(), "") settings.beginGroup(QDir(self.dirName).dirName()) frames = [self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase]: settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): settings.setValue(chkbox.text(), chkbox.isChecked()) settings.endGroup() settings.endGroup() def next(self): self.ui.slider.setValue(self.step + 1) def previous(self): self.ui.slider.setValue(self.step - 1) def first(self): self.ui.slider.setValue(0) def last(self): self.ui.slider.setValue(len(self.fieldSteps) - 1) def on_slider_valueChanged(self, step): self.step = step self.doPlots() @pyqtSignature("int") def on_spinStep_valueChanged(self, my_step): self.ui.slider.setValue(my_step) @pyqtSignature("int") def changeTab(self, tabNum): if self.ui.tabWidget.currentIndex() == 0: self.doPlots() else: self.pauseSignal.emit() def preparePlots(self): self.someCheckBoxChanged = False self.scalarDict = dict() self.fieldDict = dict() self.phaseDict = dict() self.nplots = 0 frames = [self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase]: for chkbox in frame.findChildren(QCheckBox): if chkbox.isChecked(): self.nplots += 1 if self.nplots > 0: self.fig.clear() self.title = self.fig.suptitle('') self.ax = {} plot = 0 col = 0 print "preparing scalars" for i in self.ui.scalars.findChildren(QCheckBox): col += 1 if i.isChecked(): name = str(i.text()) if not (name in self.fieldDict): x = self.scalarData[:, 0] y = self.scalarData[:, col] self.scalarDict[name] = (x, y) ax = self.fig.add_subplot(self.nplots, 1, plot + 1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.plot(x, y) ax.set_xlim(x.min(), x.max()) ax.set_ylabel(name) ax.axvline(x=0, c="red", linewidth=2, zorder=0, clip_on=False) self.ax[name] = ax plot += 1 print "preparing fields" for i in self.ui.fields.findChildren(QCheckBox): if i.isChecked(): ax = self.fig.add_subplot(self.nplots, 1, plot + 1) ax.xaxis.grid(True) ax.yaxis.grid(True) data = [] name = str(i.text()) for d in self.fieldFile.root: data.append(d._f_getChild(name)) self.fieldDict[name] = data if len(self.sim_length) == 1: ax.set_xlim(0, self.sim_length) ax.set_ylabel(name) x = np.array(range(len(data[0]))) / self.res_space y = data[0] ax.plot(x, y) self.ax[name] = ax elif len(self.sim_length) == 2: divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) ax.set_ylabel(name) im = ax.imshow([[0]], extent=(0, self.sim_length[0], 0, self.sim_length[1]), aspect='auto', origin='lower') cb = plt.colorbar(im, cax=cax) self.ax[name] = ax plot += 1 print "preparing phase" for i in self.ui.phase.findChildren(QCheckBox): if i.isChecked(): name = str(i.text()) node = self.phaseFile.getNode(name) self.phaseDict[name] = node ax = self.fig.add_subplot(self.nplots, 1, plot + 1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.set_ylabel(name) divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) im = ax.imshow( [[0]], extent=node._v_parent._v_attrs.extents.reshape( 4).tolist(), aspect='auto', origin='lower') cb = plt.colorbar(im, cax=cax) self.ax[name] = ax plot += 1 print "done" self.doPlots() def on_movement(self, event): if not event.inaxes: return msg = "%G %G" % (event.xdata, event.ydata) self.ui.pos.setText(msg) def on_key_press(self, event): if not event.inaxes: return if event.key == 'a': for line in event.inaxes.lines: if line.get_xdata().size > 1: data = line.get_ydata() nonzero = data[np.nonzero(data)] if len(nonzero): mini = np.min(nonzero) maxi = np.max(nonzero) if mini != maxi: event.inaxes.set_ylim(mini, maxi) for image in event.inaxes.images: data = np.array(image.get_array()) nonzero = data[np.nonzero(data)] if len(nonzero): mini = np.min(nonzero) maxi = np.max(nonzero) if mini != maxi: image.set_clim(mini, maxi) self.canvas.draw() elif event.key == 'l': if event.inaxes.lines: scale = 'log' if event.inaxes.get_yaxis().get_scale( ) == 'linear' else 'linear' try: event.inaxes.set_yscale(scale) self.canvas.draw() except ValueError: scale = 'log' if scale == 'linear' else 'linear' event.inaxes.set_yscale(scale) self.canvas.draw() elif event.inaxes.images: for image in event.inaxes.images: mini = np.array(image.get_array()).clip(0).min() if mini > 0: maxi = np.array(image.get_array()).clip(0).max() print ">>>>>>>>", mini, maxi pprint(vars(event.inaxes.images[0].norm)) try: event.inaxes.images[0].set_norm(LogNorm( mini, maxi)) self.canvas.draw() except ValueError: self.canvas.draw() elif event.key == 'shift': self.shiftPressed = True def on_key_release(self, event): if not event.inaxes: return if event.key == 'shift': self.shiftPressed = False def on_button_press(self, event): if not event.inaxes: return if self.shiftPressed == True: self.ui.logger.moveCursor(QTextCursor.End) for i in range(len(self.fig.axes)): if self.fig.axes[i] == event.inaxes: txt = "%d %G %G %G\n" % (i, self.step / self.res_time * self.fieldEvery, event.xdata, event.ydata) QApplication.clipboard().setText(txt) self.ui.logger.insertPlainText(txt) self.ui.logger.moveCursor(QTextCursor.End) def doPlots(self): if len(self.fieldSteps) == 0: return if self.someCheckBoxChanged == True: self.preparePlots() self.step %= len(self.fieldSteps) self.slider.setValue(self.step) self.ui.spinStep.setValue(self.step) time = float(self.step) / self.res_time * self.fieldEvery for name in self.scalarDict: self.ax[name].lines[-1].set_xdata(time) for name in self.fieldDict: data = self.fieldDict[name][self.step] if len(self.sim_length) == 1: self.ax[name].lines[-1].set_ydata(data) if self.ui.autoScale.isChecked(): self.ax[name].set_ylim(min(data), max(data)) elif len(self.sim_length) == 2: im = self.ax[name].images[-1] npData = np.array(data) im.set_data(npData.T) if self.ui.autoScale.isChecked(): im.set_clim(npData.min(), npData.max()) for name in self.phaseDict: data = self.phaseDict[name][self.step].T im = self.ax[name].images[-1] im.set_data(data) if self.ui.autoScale.isChecked(): im.set_clim(data.min(), data.max()) self.title.set_text('Time: %.3f' % time) self.canvas.draw() if self.ui.saveImages.isChecked(): self.fig.savefig(self.dirName + '-%06d.png' % self.step) def closeEvent(self, event): self.save_settings() if self.fieldFile is not None: self.fieldFile.close() if self.phaseFile is not None: self.phaseFile.close() self.parent.plots.remove(self) QApplication.processEvents() self.deleteLater()
class smileiQtPlot(QWidget): scalarDict=dict() fieldDict=dict() phaseDict=dict() nplots=0 ax={} dirName='.' someCheckBoxChanged=True pauseSignal=pyqtSignal() shiftPressed=False title='' def __init__(self,parent,dirName): super(smileiQtPlot, self).__init__() self.setParent(parent) uiFile=os.path.dirname(os.path.realpath(__file__))+'/smileiQtPlot.ui' self.ui=uic.loadUi(uiFile,self) self.dirName=dirName self.smilei=Smilei(self.dirName) self.parent=parent self.parent.timer.timeout.connect(self.next) self.parent.ui.next.released.connect(self.next) self.parent.ui.previous.released.connect(self.previous) self.parent.ui.first.released.connect(self.first) self.parent.ui.last.released.connect(self.last) self.pauseSignal.connect(self.parent.pause) self.setWindowFlags(Qt.Window) self.setWindowTitle(dirName) self.step=0 self.ui.savePoints.setIcon(self.ui.style().standardIcon(QStyle.SP_DialogSaveButton)) self.ui.savePoints.released.connect(self.doSavePoints) self.ui.tabWidget.currentChanged.connect(self.changeTab) self.ui.autoScale.stateChanged.connect(self.doPlots) self.fig = Figure() self.ui.reload.setIcon(self.ui.style().standardIcon(QStyle.SP_BrowserReload)) self.ui.reload.released.connect(self.reloadAll) self.canvas = FigureCanvas(self.fig) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.mpl_connect('motion_notify_event', self.on_movement) self.canvas.mpl_connect('key_press_event', self.on_key_press) self.canvas.mpl_connect('key_release_event', self.on_key_release) self.canvas.mpl_connect('button_press_event', self.on_button_press) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.setFixedHeight(18) self.canvas.setCursor(Qt.CrossCursor) self.ui.plotLayout.addWidget(self.toolbar) self.ui.plotLayout.addWidget(self.canvas) #retrieve stuff from namelist self.cell_length=self.smilei.namelist.Main.cell_length[0] self.timestep=self.smilei.namelist.Main.timestep self.sim_length=self.smilei.namelist.Main.sim_length #scalars scalarSteps=[] for scalar in self.smilei.Scalar().getScalars(): if len(scalarSteps) ==0: scalarSteps=self.smilei.Scalar(scalar).getAvailableTimesteps() else: if not np.array_equal(scalarSteps,self.smilei.Scalar(scalar).getAvailableTimesteps()): log.error("Problem reading scalarSteps %s"%scalar) my_button= QCheckBox(scalar) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutScalars.addWidget(my_button) self.ui.layoutScalars.addStretch() #fields self.fieldSteps=self.smilei.Field().getAvailableTimesteps() if not np.array_equal(scalarSteps,self.fieldSteps): newfieldSteps=[] for i in range(0,min(len(scalarSteps),len(self.fieldSteps))): if scalarSteps[i] == self.fieldSteps[i]: newfieldSteps.append(scalarSteps[i]) else: break self.fieldSteps=newfieldSteps log.warning("Problem reading fieldSteps") for field in self.smilei.Field().getFields(): my_button= QCheckBox(field) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutFields.addWidget(my_button) self.ui.layoutFields.addStretch() self.ui.slider.setRange(0,len(self.fieldSteps)) self.ui.spinStep.setSuffix("/"+str(len(self.fieldSteps))) self.ui.spinStep.setMaximum(len(self.fieldSteps)) #phase spaces i=0 # self.smilei.ParticleDiagnostic(0)._type ... for phase in self.smilei.namelist.DiagParticles: if not np.array_equal(self.fieldSteps,self.smilei.ParticleDiagnostic(i).getAvailableTimesteps()): log.warning("Problem reading phaseSteps") name=str(i)+' ' for ax in phase.axes: name+=ax[0] my_button= QCheckBox(name) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutPhase.addWidget(my_button) i=i+1 self.ui.layoutPhase.addStretch() self.load_settings() if sys.platform == "darwin": self.raise_() self.show() def reloadAll(self): self.smilei=Smilei(self.dirName) self.fieldSteps=self.smilei.Field().getAvailableTimesteps() self.ui.slider.setRange(0,len(self.fieldSteps)) self.ui.spinStep.setSuffix("/"+str(len(self.fieldSteps))) self.ui.spinStep.setMaximum(len(self.fieldSteps)) self.preparePlots() def doSavePoints(self): fname=QFileDialog.getSaveFileName(self, 'Save Point logger', self.dirName, selectedFilter='*.txt') if fname: f = open(fname, 'w') f.write(self.ui.logger.toPlainText()) f.close() def checkBoxChanged(self): self.someCheckBoxChanged=True def load_settings(self): settings=QSettings(QFileInfo(__file__).fileName(),"") log.info("Load settings file: %s"%settings.fileName()) settings.beginGroup(QDir(self.dirName).dirName()) self.restoreGeometry(settings.value("geometry").toByteArray()) frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): chkbox.setChecked(settings.value(chkbox.text())=='true') settings.endGroup() settings.endGroup() self.ui.tabWidget.setCurrentIndex(0) def save_settings(self): settings=QSettings(QFileInfo(__file__).fileName(),"") log.info("Save settings file: %s"%settings.fileName()) settings.beginGroup(QDir(self.dirName).dirName()) settings.setValue("geometry", self.saveGeometry()) frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): settings.setValue(chkbox.text(),chkbox.isChecked()) settings.endGroup() settings.endGroup() def next(self): self.ui.slider.setValue(self.step+1) def previous(self): self.ui.slider.setValue(self.step-1) def first(self): self.ui.slider.setValue(0) def last(self): self.ui.slider.setValue(len(self.fieldSteps)-1) def on_slider_valueChanged(self,step): self.step=step self.doPlots() @pyqtSignature("int") def on_spinStep_valueChanged(self,my_step): self.ui.slider.setValue(my_step) @pyqtSignature("int") def changeTab(self, tabNum): if self.ui.tabWidget.currentIndex()==0: self.doPlots() else: self.pauseSignal.emit() def preparePlots(self): self.someCheckBoxChanged=False self.scalarDict=dict() self.fieldDict=dict() self.phaseDict=dict() self.nplots=0 frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : for chkbox in frame.findChildren(QCheckBox): if chkbox.isChecked() : self.nplots+=1 self.fig.clear() if self.nplots > 0: self.title=self.fig.suptitle('') self.ax={} plot=0 col=0 log.info("preparing scalars") for i in self.ui.scalars.findChildren(QCheckBox): col+=1 if i.isChecked() : name=str(i.text()) x=self.smilei.Scalar(name).getAvailableTimesteps()*self.timestep y=self.smilei.Scalar(name).getData() self.scalarDict[name]=(x,y) ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.plot(x,y) ax.set_xlim(x.min(),x.max()) ax.set_ylabel(name) ax.axvline(x=0,c="red",linewidth=2,zorder=0, clip_on=False) self.ax[name]=ax plot+=1 log.info("preparing fields") for i in self.ui.fields.findChildren(QCheckBox): if i.isChecked() : log.info(i.text()) ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) data=[] name=str(i.text()) log.info("\tField %s"%name) data=self.smilei.Field(name).getData() self.fieldDict[name]=data if len(self.sim_length) == 1 : ax.set_xlim(0,self.sim_length[0]) ax.set_ylabel(name) x=np.array(range(len(data[0])))*self.cell_length y=data[0] ax.plot(x,y) self.ax[name]=ax elif len(self.sim_length) == 2 : divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) ax.set_ylabel(name) im=ax.imshow([[0]],extent=(0,self.sim_length[0],0,self.sim_length[1]), aspect='auto',origin='lower') im.set_interpolation('nearest') cb=self.fig.colorbar(im, cax=cax, ax=ax) self.ax[name]=ax plot+=1 log.info("preparing phase") for i in self.ui.phase.findChildren(QCheckBox): if i.isChecked() : name=str(i.text()) number=int(name.split(' ')[0]) phase=self.smilei.ParticleDiagnostic(number) self.phaseDict[name]=phase.getData() if phase._naxes is not 2: log.error("phasespace len is not 2 : %s"%name) my_extent=[phase._axes[0]['min'],phase._axes[0]['max'],phase._axes[1]['min'],phase._axes[1]['max']] ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.set_ylabel(name) divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) im=ax.imshow([[0]],extent=my_extent,aspect='auto',origin='lower') im.set_interpolation('nearest') cb=self.fig.colorbar(im, cax=cax, ax=ax) self.ax[name]=ax plot+=1 log.info("done") self.doPlots() def on_movement(self, event): if not event.inaxes: return # self.canvas.setCursor(Qt.CrossCursor) msg = "%G %G" % (event.xdata, event.ydata) self.ui.pos.setText(msg) def on_key_press(self,event): if not event.inaxes: return if event.key == 'a': for line in event.inaxes.lines : if line.get_xdata().size > 1: data=line.get_ydata() nonzero=data[np.nonzero(data)] if len(nonzero) : mini=np.min(nonzero) maxi=np.max(nonzero) if mini != maxi : event.inaxes.set_ylim(mini,maxi) for image in event.inaxes.images : data=np.array(image.get_array()) nonzero=data[np.nonzero(data)] if len(nonzero) : mini=np.min(nonzero) maxi=np.max(nonzero) if mini != maxi : image.set_clim(mini,maxi) self.canvas.draw() elif event.key == 'l': if event.inaxes.lines : scale='log' if event.inaxes.get_yaxis().get_scale()== 'linear' else 'linear' try: event.inaxes.set_yscale(scale) self.canvas.draw() except ValueError: scale='log' if scale == 'linear' else 'linear' event.inaxes.set_yscale(scale) self.canvas.draw() elif event.inaxes.images : for image in event.inaxes.images : mini = np.array(image.get_array()).clip(0).min() if mini >0: maxi = np.array(image.get_array()).clip(0).max() pprint (vars(event.inaxes.images[0].norm)) try: event.inaxes.images[0].set_norm(LogNorm(mini,maxi)) self.canvas.draw() except ValueError: self.canvas.draw() elif event.key == 'x': range, ok = QInputDialog.getText(self, 'Ranges', 'Give '+event.key+' range:') if ok: ranges=range.split(' ') event.inaxes.set_xlim(float(ranges[0]),float(ranges[1])) self.canvas.draw() elif event.key == 'y': range, ok = QInputDialog.getText(self, 'Ranges', 'Give '+event.key+' range:') if ok: ranges=range.split(' ') event.inaxes.set_ylim(float(ranges[0]),float(ranges[1])) self.canvas.draw() elif event.key == 'c': range, ok = QInputDialog.getText(self, 'Ranges', 'Give '+event.key+' range:') if ok: ranges=range.split(' ') event.inaxes.images[0].set_clim(float(ranges[0]),float(ranges[1])) self.canvas.draw() elif event.key == 'shift': self.shiftPressed=True def on_key_release(self,event): if not event.inaxes: return if event.key == 'shift': self.shiftPressed=False def on_button_press(self,event): if not event.inaxes: return if self.shiftPressed == True : self.ui.logger.moveCursor (QTextCursor.End) for i in range(len(self.fig.axes)) : if self.fig.axes[i] == event.inaxes: # JDT txt = "%d %G %G %G\n" % (i, self.step/self.timestep*self.fieldEvery, event.xdata, event.ydata) txt = "%d %G %G\n" % (i, event.xdata, event.ydata) QApplication.clipboard().setText(txt) self.ui.logger.insertPlainText(txt) self.ui.logger.moveCursor (QTextCursor.End) def doPlots(self): if len(self.fieldSteps) == 0 : return if self.someCheckBoxChanged==True: self.preparePlots() self.step %= len(self.fieldSteps) self.slider.setValue(self.step) self.ui.spinStep.setValue(self.step) # JDT time=float(self.step)/self.timestep*self.fieldEvery time=self.fieldSteps[self.step]*self.timestep self.fig.suptitle("Time: %g"%time) for name in self.scalarDict: self.ax[name].lines[-1].set_xdata(time) for name in self.fieldDict: data=self.fieldDict[name][self.step] if len(self.sim_length) == 1 : self.ax[name].lines[-1].set_ydata(data) if self.ui.autoScale.isChecked(): self.ax[name].set_ylim(min(data),max(data)) elif len(self.sim_length) == 2 : im=self.ax[name].images[-1] npData=np.array(data) im.set_data(npData.T) if self.ui.autoScale.isChecked(): im.set_clim(npData.min(),npData.max()) for name in self.phaseDict: data=self.phaseDict[name][self.step].T im=self.ax[name].images[-1] im.set_data(data) if self.ui.autoScale.isChecked(): im.set_clim(data.min(),data.max()) self.canvas.draw() if self.ui.saveImages.isChecked(): fname=self.dirName+'/frame-%06d.png' % self.step self.fig.savefig(fname) def closeEvent(self,event): self.save_settings() self.parent.plots.remove(self) QApplication.processEvents() self.deleteLater()
class AppForm(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowTitle('Mandelbrot Set') self.create_menu() self.create_main_frame() self.create_status_bar() # # Initialize textbox values # self.textbox_re_min.setText(str(re_min)) self.textbox_re_max.setText(str(re_max)) self.textbox_im_min.setText(str(im_min)) self.textbox_im_max.setText(str(im_max)) self.textbox_max_iter.setText(str(max_iter)) # # Render mandelbrot set # self.setMinimumWidth(620) self.resize(620, 460) self.draw() def save_plot(self): file_choices = "PNG (*.png)|*.png" path = unicode(QFileDialog.getSaveFileName(self, 'Save file', '', file_choices)) if path: self.canvas.print_figure(path) self.statusBar().showMessage('Saved to %s' % path, 2000) # # Display infos about application # def on_about(self): msg = """Mandelbrot Set Generator: ### Features ### * Click left mouse button and drag to zoom * Enter custom values for ReMin, ReMin, ImMin and ImMax * Show or hide the grid * Save the plot to a file using the File menu * De-/activate continuous color spectrum * De-/activate normalized values ### Used Libraries ### * PyQt4 * Matplotlib ### Author ### Made by Philip Wiese [email protected] 16. Oktober 2016 """ QMessageBox.about(self, "About the demo", msg.strip()) # # Show mouse position in statusbar # def statusbar_coord(self, event): # Show coordinates time in statusbar if event.inaxes is not None: text = "Re(c): % .5f, Im(c) % .5f" % (event.xdata, event.ydata) self.coord_text.setText(text) # # Calculates mandelbrot set and updates mpl plot # def draw(self): """ Redraws the figure """ # Grap values from textboxes re_min = float(unicode(self.textbox_re_min.text())) re_max = float(unicode(self.textbox_re_max.text())) im_min = float(unicode(self.textbox_im_min.text())) im_max = float(unicode(self.textbox_im_max.text())) max_iter = int(unicode(self.textbox_max_iter.text())) # Grap values from checkboxes self.axes.grid(self.grid_cb.isChecked()) cont = self.cont_cb.isChecked() norm = self.norm_cb.isChecked() # Calculate mandelbrot set self.fractal = mandelbrot(re_min, re_max, im_min, im_max, max_betr, max_iter, res, cont) # Normalize Values if norm: self.fractal.data[self.fractal.data > 0] -= self.fractal.min # Show calculation time in statusbar self.status_text.setText("Calculation Time: %0.3fs" % self.fractal.calc_time) # Load data to mpl plot self.axes.imshow(self.fractal.data.T, origin="lower left", cmap='jet', extent=[re_min, re_max, im_min, im_max]) self.axes.set_xlabel("Re(c)", labelpad=20) self.axes.set_ylabel("Im(c)") # Show/hide grid if self.grid_cb.isChecked(): self.axes.grid(linewidth=1, linestyle='-') # Align layout and redraw plot self.canvas.draw_idle() #self.fig.tight_layout() def line_select_callback(self, eclick, erelease): # eclick and erelease are the press and release events x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata # Zoom with left mouse click if eclick.button == 1: # Check for valid coordinates if (x1 != None and y2 != None and x1 != None and y1 != None): self.xmin = min(x1, x2) self.xmax = max(x1, x2) self.ymin = min(y1, y2) self.ymax = max(y1, y2) # Save array with relative values self.xy = [self.xmax - self.xmin, self.ymax - self.ymin] # Calculate precision in decimal digits for v in self.xy: if v <= 1: self.decimals = round(log10(1 / v)) + 2 # Round values with calculated precision re_min = round(self.xmin, int(self.decimals)) re_max = round(self.xmax, int(self.decimals)) im_min = round(self.ymin, int(self.decimals)) im_max = round(self.ymax, int(self.decimals)) # Update textbos values self.textbox_re_min.setText(str(re_min)) self.textbox_re_max.setText(str(re_max)) self.textbox_im_min.setText(str(im_min)) self.textbox_im_max.setText(str(im_max)) # Calculate and draw new mandelbrot set self.draw() # Zoom with right mouse click if eclick.button == 3: # Grap values from textboxes re_min = float(unicode(self.textbox_re_min.text())) re_max = float(unicode(self.textbox_re_max.text())) im_min = float(unicode(self.textbox_im_min.text())) im_max = float(unicode(self.textbox_im_max.text())) self.xy = [ re_max - re_min, im_max - im_min] # Calculate new values re_min = re_min - self.xy[0] / 2 re_max = re_max + self.xy[0] / 2 im_min = im_min - self.xy[1] / 2 im_max = im_max + self.xy[1] / 2 # Calculate precision in decimal digits for v in self.xy: if v <= 1: self.decimals = round(log10(1 / v)) + 2 # Round values with calculated precision re_min = round(re_min, int(self.decimals)) re_max = round(re_max, int(self.decimals)) im_min = round(im_min, int(self.decimals)) im_max = round(im_max, int(self.decimals)) # Update textbos values self.textbox_re_min.setText(str(re_min)) self.textbox_re_max.setText(str(re_max)) self.textbox_im_min.setText(str(im_min)) self.textbox_im_max.setText(str(im_max)) # Calculate and draw new mandelbrot set self.draw() def create_main_frame(self): self.main_frame = QWidget() self.main_frame.setMinimumHeight(280) # Create the Figure and FigCanvas objects self.fig = Figure((5,10), tight_layout=True) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) # Add sublot to figure do formatting self.axes = self.fig.add_subplot(111) self.axes.ticklabel_format(style='sci', scilimits=(0,0), axis='both') # Create zoom event handler self.RS = RectangleSelector(self.axes, self.line_select_callback, drawtype='box', useblit=True, button=[1, 3], # don't use middle button spancoords='data') # Other GUI controls self.textbox_re_min = QLineEdit() self.textbox_re_min_text = QLabel("ReMin: ") self.textbox_re_min.setMinimumWidth(55) self.textbox_re_max = QLineEdit() self.textbox_re_max_text = QLabel("ReMax: ") self.textbox_re_max.setMinimumWidth(55) self.textbox_im_min = QLineEdit() self.textbox_im_min_text = QLabel("ImMin: ") self.textbox_im_min.setMinimumWidth(55) self.textbox_im_max = QLineEdit() self.textbox_im_max_text = QLabel("ImMax: ") self.textbox_im_max.setMinimumWidth(55) self.textbox_max_iter = QLineEdit() self.textbox_max_iter_text = QLabel("Max Iterration: ") self.textbox_max_iter.setMinimumWidth(55) self.grid_cb = QCheckBox("Show Grid") self.grid_cb.setChecked(False) self.cont_cb = QCheckBox("Continuous Coloring") self.cont_cb.setChecked(True) self.norm_cb = QCheckBox("Normalize Values") self.norm_cb.setChecked(True) self.draw_button = QPushButton("Calculate && Draw") self.connect(self.draw_button, SIGNAL('clicked()'), self.draw) # # Layout with box sizers # hbox = QHBoxLayout() grid = QGridLayout() hbox.addWidget(self.canvas, 3) self.canvas.setCursor(Qt.CrossCursor) hbox.addLayout(grid,1) grid.setRowStretch(1,1) grid.addWidget(self.textbox_re_min , 0,1) grid.addWidget(self.textbox_re_min_text , 0,0) grid.addWidget(self.textbox_re_max , 1,1) grid.addWidget(self.textbox_re_max_text , 1,0) grid.addWidget(self.textbox_im_min , 2,1) grid.addWidget(self.textbox_im_min_text , 2,0) grid.addWidget(self.textbox_im_max , 3,1) grid.addWidget(self.textbox_im_max_text , 3,0) grid.addWidget(self.textbox_max_iter , 5,1) grid.addWidget(self.textbox_max_iter_text , 5,0) grid.addWidget(self.grid_cb , 6,0,1,2) grid.addWidget(self.cont_cb , 7,0,1,2) grid.addWidget(self.norm_cb , 8,0,1,2) grid.addWidget(self.draw_button , 9,0,1,2) grid.addWidget(QLabel(""), 10,0,2,2) self.main_frame.setLayout(hbox) self.setCentralWidget(self.main_frame) def create_status_bar(self): self.status_text = QLabel("Ready") self.coord_text = QLabel("Re(c): % 7f, Im(c) % 7f" % (0, 0)) self.canvas.mpl_connect("motion_notify_event", self.statusbar_coord) self.statusBar().addWidget(self.status_text, 1) self.statusBar().addWidget(self.coord_text, -1) def create_menu(self): # -- Menu Structure -- # File # Save plot (Ctrl+S) # Quit (Ctrl+Q) # Help # About (F1) # self.file_menu = self.menuBar().addMenu("&File") load_file_action = self.create_action("&Save plot", shortcut="Ctrl+S", slot=self.save_plot, tip="Save the plot") quit_action = self.create_action("&Quit", slot=self.close, shortcut="Ctrl+Q", tip="Close the application") self.add_actions(self.file_menu, (load_file_action, None, quit_action)) self.help_menu = self.menuBar().addMenu("&Help") about_action = self.create_action("&About", shortcut='F1', slot=self.on_about, tip='About the application') self.add_actions(self.help_menu, (about_action,)) def add_actions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def create_action(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/%s.png" % icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: self.connect(action, SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action
def setGraphCursorShape(self, cursor): cursor = self._QT_CURSORS[cursor] FigureCanvasQTAgg.setCursor(self, qt.QCursor(cursor))
class Window(QtGui.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.hide() # Timestream info self.timestreamLabel = QtGui.QLabel('Time-stream root path:') self.timestreamText = QtGui.QLineEdit('') self.timestreamText.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.timestreamDateLabel = QtGui.QLabel('Start date (yyyy_mm_dd_hh_mm_ss):') self.timestreamDateText = QtGui.QLineEdit('') self.timestreamDateText.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.timestreamTimeLabel = QtGui.QLabel('Time interval (seconds):') self.timestreamTimeText = QtGui.QLineEdit('') self.timestreamTimeText.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.initStreamTimeButton = QtGui.QPushButton('&Initialise timestream by time') self.initStreamTimeButton.clicked.connect(self.initialiseTimestreamByTime) self.initStreamFileButton = QtGui.QPushButton('&Initialise timestream by files') self.initStreamFileButton.clicked.connect(self.initialiseTimestreamByFiles) # Image loading and processing self.loadImageButton = QtGui.QPushButton('&Load (next) image') self.loadImageButton.clicked.connect(self.loadImage) self.rotateImageButton = QtGui.QPushButton('&Rotate 90-deg') self.rotateImageButton.clicked.connect(self.rotateImage90Degrees) self.slider = QtGui.QSlider(QtCore.Qt.Horizontal) self.slider.setFocusPolicy(QtCore.Qt.StrongFocus) self.slider.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) self.slider.setTickPosition(QtGui.QSlider.TicksBothSides) self.slider.setMinimum(-16) self.slider.setMaximum(16) self.slider.setValue(0) self.slider.setTickInterval(4) self.slider.setSingleStep(1) self.slider.valueChanged.connect(self.rotateSmallAngle) self.applySmallRotationButton = QtGui.QPushButton('&Apply') self.applySmallRotationButton.clicked.connect(self.applySmallRotation) self.loadCamCalibButton = QtGui.QPushButton('Load &cam. param.') self.loadCamCalibButton.clicked.connect(self.loadCamCalib) self.colorcardRadioButton = QtGui.QRadioButton('Select color car&d') self.colorcardRadioButton.setChecked(False) self.colorcardRadioButton.clicked.connect(self.selectWhat) self.trayRadioButton = QtGui.QRadioButton('Select &tray') self.trayRadioButton.setChecked(False) self.trayRadioButton.clicked.connect(self.selectWhat) self.trayRoundCheckBox = QtGui.QCheckBox('Round') self.trayRoundCheckBox.setChecked(True) self.potRadioButton = QtGui.QRadioButton('Select &pot') self.potRadioButton.setChecked(False) self.potRadioButton.clicked.connect(self.selectWhat) self.zoomButton = QtGui.QPushButton('&Zoom') self.zoomButton.setCheckable(True) self.zoomButton.clicked.connect(self.zoom) self.panButton = QtGui.QPushButton('&Pan') self.panButton.setCheckable(True) self.panButton.clicked.connect(self.pan) self.homeButton = QtGui.QPushButton('&Home') self.homeButton.clicked.connect(self.home) self.correctColorButton = QtGui.QPushButton('Correct colo&r') self.correctColorButton.clicked.connect(self.correctColor) self.save2PipelineButton = QtGui.QPushButton('&Save as pipeline settings') self.save2PipelineButton.clicked.connect(self.savePipelineSettings) self.testPipelineButton = QtGui.QPushButton('Test &pipeline processing') self.testPipelineButton.clicked.connect(self.testPipeline) self.status = QtGui.QTextEdit('') self.status.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.mousePosition = QtGui.QLabel('') # set the layout layout = QtGui.QHBoxLayout() rightWidget = QtGui.QWidget() buttonlayout = QtGui.QVBoxLayout(rightWidget) buttonlayout.addWidget(self.timestreamLabel) buttonlayout.addWidget(self.timestreamText) buttonlayout.addWidget(self.timestreamDateLabel) buttonlayout.addWidget(self.timestreamDateText) buttonlayout.addWidget(self.timestreamTimeLabel) buttonlayout.addWidget(self.timestreamTimeText) buttonlayout.addWidget(self.initStreamTimeButton) buttonlayout.addWidget(self.initStreamFileButton) buttonlayout.addWidget(self.loadImageButton) buttonlayout.addWidget(self.loadCamCalibButton) buttonlayout.addWidget(self.rotateImageButton) layoutSmallRotation = QtGui.QHBoxLayout() layoutSmallRotation.addWidget(self.slider) layoutSmallRotation.addWidget(self.applySmallRotationButton) buttonlayout.addLayout(layoutSmallRotation) buttonlayout.addWidget(self.colorcardRadioButton) layoutTrayShape = QtGui.QHBoxLayout() layoutTrayShape.addWidget(self.trayRadioButton) layoutTrayShape.addWidget(self.trayRoundCheckBox) buttonlayout.addLayout(layoutTrayShape) buttonlayout.addWidget(self.potRadioButton) buttonlayout.addWidget(self.zoomButton) buttonlayout.addWidget(self.panButton) buttonlayout.addWidget(self.homeButton) buttonlayout.addWidget(self.correctColorButton) buttonlayout.addWidget(self.save2PipelineButton) buttonlayout.addWidget(self.testPipelineButton) buttonlayout.addWidget(self.status) buttonlayout.addWidget(self.mousePosition) rightWidget.setMaximumWidth(250) leftLayout = QtGui.QVBoxLayout() leftLayout.addWidget(self.toolbar) leftLayout.addWidget(self.canvas) layout.addWidget(rightWidget) layout.addLayout(leftLayout) self.setLayout(layout) self.group = QtGui.QButtonGroup() self.group.addButton(self.colorcardRadioButton) self.group.addButton(self.trayRadioButton) self.group.addButton(self.potRadioButton) self.loadPreviousInputs() self.panMode = False self.zoomMode = False self.ts = None self.tsImages = None self.ax = None self.plotRect = None self.plotImg = None self.image = None self.potTemplate = None self.UndistMapX = None self.UndistMapY = None self.trayAspectRatio = 0.835 self.colorcardAspectRatio = 1.5 self.potAspectRatio = 1.0 self.leftClicks = [] self.colorcardParams = None self.scriptPath = os.path.dirname(os.path.realpath(__file__)) self.timestreamRootPath = None self.pl = None # Ouput parameters self.ImageSize = None self.colorcardList = [] self.trayList = [] self.potList = [] self.rotationAngle = 0.0 self.smaleRotationAngle = 0.0 self.CameraMatrix = None self.DistCoefs = None self.isDistortionCorrected = False self.settingFileName = None def selectWhat(self): if self.trayRadioButton.isChecked(): self.status.append('Start selecting tray.') elif self.colorcardRadioButton.isChecked(): self.status.append('Start selecting color bar.') else: self.status.append('Start selecting pot.') def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() if not self.zoomMode: self.zoomMode = True self.panMode = False self.panButton.setChecked(False) else: self.zoomMode = False def pan(self): self.toolbar.pan() if not self.panMode: self.panMode = True self.zoomMode = False self.zoomButton.setChecked(False) else: self.panMode = False def initialiseTimestreamByTime(self): self.timestreamRootPath = str(self.timestreamText.text()) if len(self.timestreamRootPath) > 0: self.status.append('Initialise a timestream at ' + str(self.timestreamRootPath)) self.ts = timestream.TimeStream() self.ts.load(self.timestreamRootPath) self.status.append('Done') startDate = None timeInterval = None date = str(self.timestreamDateText.text()) if len(date) > 0: startDate = timestream.parse.ts_parse_date(date) time = str(self.timestreamTimeText.text()) if len(time) > 0: timeInterval = int(eval(time)) self.tsImages = self.ts.iter_by_timepoints(start = startDate, interval = timeInterval, remove_gaps=False) self.loadImage() else: self.status.append('Please provide timestream root path.') def initialiseTimestreamByFiles(self): self.timestreamRootPath = str(self.timestreamText.text()) if len(self.timestreamRootPath) > 0: self.status.append('Initialise a timestream at ' + str(self.timestreamRootPath)) self.ts = timestream.TimeStream() self.ts.load(self.timestreamRootPath) self.status.append('Done') self.tsImages = self.ts.iter_by_files() self.loadImage() else: self.status.append('Please provide timestream root path.') def loadImage(self): ''' load and show an image''' if self.tsImages != None: try: tsImage = self.tsImages.next() if tsImage.pixels == np.array([]): self.status.append('Missing image.') except: tsImage.pixels == np.array([]) self.status.append('There is no more images.') if tsImage.pixels == np.array([]): self.image = None self.updateFigure() return self.image = tsImage.pixels fname = tsImage.path else: fname = QtGui.QFileDialog.getOpenFileName(self, 'Open image', '/mnt/phenocam/a_data/TimeStreams/Borevitz/BVZ0036/BVZ0036-GC02L-C01~fullres-orig/2014/2014_06/2014_06_24/2014_06_24_08/') app.processEvents() if len(fname) == 0: return self.image = cv2.imread(str(fname))[:,:,::-1] self.status.append('Loaded image from ' + str(fname)) # reset all outputs # self.colorcardList = [] # self.trayList = [] # self.potList = [] self.isDistortionCorrected = False if self.rotationAngle != None: self.image = cd.rotateImage(self.image, self.rotationAngle + self.smaleRotationAngle) # Undistort image if mapping available if not self.isDistortionCorrected and self.UndistMapX != None and self.UndistMapY != None: self.image = cv2.remap(self.image.astype(np.uint8), self.UndistMapX, self.UndistMapY, cv2.INTER_CUBIC) self.isDistortionCorrected = True self.updateFigure() def changeCursor(self, event): # cursor = Cursor(self.ax, useblit=True, color='red', linewidth=1) self.canvas.setCursor(QtGui.QCursor(QtCore.Qt.CrossCursor )) def updateFigure(self, image = None, resetFigure = False): if self.image != None: if image == None: image = self.image if self.ax == None: self.ax = self.figure.add_subplot(111) self.ax.figure.canvas.mpl_connect('button_press_event', self.onMouseClicked) self.ax.figure.canvas.mpl_connect('motion_notify_event', self.onMouseMoves) self.ax.figure.canvas.mpl_connect('figure_enter_event', self.changeCursor) self.ax.hold(False) if self.plotImg == None or resetFigure: self.plotImg = self.ax.imshow(image) else: self.plotImg.set_data(image) self.figure.tight_layout() xs, ys = [], [] for Rect in self.colorcardList: tl, bl, br, tr = Rect xs = xs + [tl[0], bl[0], br[0], tr[0], tl[0], np.nan] ys = ys + [tl[1], bl[1], br[1], tr[1], tl[1], np.nan] for Rect in self.trayList: tl, bl, br, tr = Rect xs = xs + [tl[0], bl[0], br[0], tr[0], tl[0], np.nan] ys = ys + [tl[1], bl[1], br[1], tr[1], tl[1], np.nan] for Rect in self.potList: tl, bl, br, tr = Rect xs = xs + [tl[0], bl[0], br[0], tr[0], tl[0], np.nan] ys = ys + [tl[1], bl[1], br[1], tr[1], tl[1], np.nan] for x,y in self.leftClicks: xs = xs + [x] ys = ys + [y] # if self.crosshair != None: # xs = xs + [np.nan, 0, self.image.shape[1], np.nan, self.crosshair[0], self.crosshair[0], np.nan] # ys = ys + [np.nan, self.crosshair[1], self.crosshair[1], np.nan, 0, self.image.shape[0], np.nan] if len(xs) > 0 and len(ys) > 0: if self.plotRect == None: self.ax.hold(True) self.plotRect, = self.ax.plot(xs, ys, 'b') self.ax.hold(False) self.ax.set_xlim([0,self.image.shape[1]]) self.ax.set_ylim([0,self.image.shape[0]]) self.ax.invert_yaxis() else: self.plotRect.set_data(xs, ys) self.canvas.draw() app.processEvents() def loadCamCalib(self): ''' load camera calibration image and show an image''' calibPath = os.path.join(self.scriptPath, './data') CalibFile = QtGui.QFileDialog.getOpenFileName(self, 'Open image', calibPath) self.ImageSize, SquareSize, self.CameraMatrix, self.DistCoefs, RVecs, TVecs = cd.readCalibration(CalibFile) self.status.append('Loaded camera parameters from ' + CalibFile) print('CameraMatrix =', self.CameraMatrix) print('DistCoefs =', self.DistCoefs) self.UndistMapX, self.UndistMapY = cv2.initUndistortRectifyMap(self.CameraMatrix, self.DistCoefs, \ None, self.CameraMatrix, self.ImageSize, cv2.CV_32FC1) if self.image != None: self.image = cv2.remap(self.image.astype(np.uint8), self.UndistMapX, self.UndistMapY, cv2.INTER_CUBIC) self.isDistortionCorrected = True self.status.append('Corrected image distortion.') self.updateFigure() # def loadPotTemplate(self): # ''' load pot template image''' # fname = QtGui.QFileDialog.getOpenFileName(self, 'Open image', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') # self.status.append('Loading image...') # app.processEvents() # self.potTemplate = cv2.imread(str(fname))[:,:,::-1] # if len(self.potList) > 0: def correctColor(self): if self.colorcardParams == None: if len(self.colorcardList) > 0: medianSize = cd.getMedianRectSize(self.colorcardList) capturedColorcards = cd.rectifyRectImages(self.image, self.colorcardList, medianSize) self.colorcardColors, _ = cd.getColorcardColors(capturedColorcards[0], GridSize = [6, 4]) self.colorcardParams = cd.estimateColorParameters(cd.CameraTrax_24ColorCard, self.colorcardColors) else: self.status.append('Need to select a color card first.') return colorMatrix, colorConstant, colorGamma = self.colorcardParams self.imageCorrected = cd.correctColorVectorised(self.image.astype(np.float), colorMatrix, colorConstant, colorGamma) self.imageCorrected[np.where(self.imageCorrected < 0)] = 0 self.imageCorrected[np.where(self.imageCorrected > 255)] = 255 self.imageCorrected = self.imageCorrected.astype(np.uint8) self.updateFigure(self.imageCorrected) def savePipelineSettings(self): ''' save to pipeline setting file''' self.settingFileName = str(QtGui.QFileDialog.getSaveFileName(self, \ 'Save selection (default in ./_data)', self.timestreamRootPath)) if len(self.settingFileName) == 0: return self.settingPath = os.path.relpath(os.path.dirname(self.settingFileName), self.timestreamRootPath) self.settings = {} if self.ImageSize != None and self.CameraMatrix != None and self.DistCoefs != None: undistortDic = {'cameraMatrix': self.CameraMatrix.tolist(), \ 'distortCoefs': self.DistCoefs.tolist(), \ 'imageSize': list(self.ImageSize), 'rotationAngle': self.rotationAngle + self.smaleRotationAngle } else: undistortDic = {} self.settings['undistort'] = undistortDic if len(self.colorcardList) > 0: medianSize = cd.getMedianRectSize(self.colorcardList) capturedColorcards = cd.rectifyRectImages(self.image, self.colorcardList, medianSize) colorCardFile = 'CapturedColorcard.png' cv2.imwrite(os.path.join(self.timestreamRootPath, self.settingPath, colorCardFile), capturedColorcards[0][:,:,::-1].astype(np.uint8)) colorcardColors, colorStd = cd.getColorcardColors(capturedColorcards[0], GridSize = [6,4]) colorcardPosition, Width, Height, Angle = cd.getRectangleParamters(self.colorcardList[0]) colorcardDic = {'colorcardFile': colorCardFile,\ 'colorcardPosition': colorcardPosition.tolist(),\ 'colorcardTrueColors': cd.CameraTrax_24ColorCard,\ 'settingPath': '_data' } else: colorcardDic = {} self.settings['colorcarddetect'] = colorcardDic self.settings['colorcorrect'] = {'minIntensity': 15} if len(self.trayList) > 0: trayMedianSize = cd.getMedianRectSize(self.trayList) trayImages = cd.rectifyRectImages(self.image, self.trayList, trayMedianSize) trayDict = {} trayDict['settingPath'] = '_data' trayDict['trayNumber'] = len(self.trayList) trayDict['trayFiles'] = 'Tray_%02d.png' trayPositions = [] for i,tray in enumerate(trayImages): cv2.imwrite(os.path.join(self.timestreamRootPath, self.settingPath, trayDict['trayFiles'] %i), tray[:,:,::-1].astype(np.uint8)) trayPosition, Width, Height, Angle = cd.getRectangleParamters(self.trayList[i]) trayPositions.append(trayPosition.tolist()) trayDict['trayPositions'] = trayPositions else: trayDict = {} self.settings['traydetect'] = trayDict if len(self.potList) > 0: trayMedianSize = cd.getMedianRectSize(self.trayList) potPosition, Width, Height, Angle = cd.getRectangleParamters(self.potList[0]) Width, Height = int(Width), int(Height) topLeft = [int(self.potList[0][0][0]), int(self.potList[0][0][1])] self.potImage = self.image[topLeft[1]:topLeft[1]+Height, topLeft[0]:topLeft[0]+Width, :] potFile = 'Pot.png' cv2.imwrite(os.path.join(self.timestreamRootPath, self.settingPath, potFile), self.potImage[:,:,::-1].astype(np.uint8)) potDict = {} potDict['potPositions'] = potPosition.tolist() potDict['potSize'] = [int(Width), int(Height)] potDict['traySize'] = [int(trayMedianSize[0]), int(trayMedianSize[1])] potDict['potFile'] = potFile potDict['potTemplateFile'] = 'PotTemplate.png' potDict['settingPath'] = '_data' potTemplatePathIn = os.path.join(self.scriptPath, './data/PotTemplate.png') potTemplatePathOut = os.path.join(self.timestreamRootPath, self.settingPath, potDict['potTemplateFile']) shutil.copyfile(potTemplatePathIn, potTemplatePathOut) if self.potTemplate != None: potTemplateFile = 'potTemplate.png' cv2.imwrite(os.path.join(self.timestreamRootPath, self.settingPath, potTemplateFile), self.potTemplate[:,:,::-1]) potDict['potTemplateFile'] = potTemplateFile else: potDict = {} self.settings['potdetect'] = potDict self.settings['plantextract'] = {'meth': 'method1', 'methargs': {'threshold' : 0.6, 'kSize' : 5, 'blobMinSize' : 50} } with open(self.settingFileName, 'w') as outfile: outfile.write( yaml.dump(self.settings, default_flow_style=None) ) self.status.append('Saved initial data to ' + self.settingFileName) def testPipeline(self): ''' try running processing pipeline based on user inputs''' if self.tsImages != None: # load setting file if missing if self.settingFileName == None: settingFileName = str(QtGui.QFileDialog.getOpenFileName(self, 'Open pipeline setting file', self.ts.path)) if len(settingFileName) > 0: self.settingFileName = settingFileName else: return # initialise pipeline if self.pl == None: f = file(self.settingFileName) self.settings = yaml.load(f) self.ts.data["settings"] = self.settings self.pl = pipeline.ImagePipeline(self.settings) # process only from undistortion to pot detection self.pl.pipeline = self.pl.pipeline[:5] # read next image instant of pipeline try: tsImage = self.tsImages.next() if tsImage == None: self.status.append('Missing image.') return except: tsImage = None self.status.append('There is no more images.') return self.status.append('Processing ' + tsImage.path) context = {"rts":self.ts, "wts":None, "img":tsImage} result = self.pl.process(context, [tsImage]) self.image, potPosList2 = result potSize = self.settings[4][1]["potSize"] self.potList = [] for potPosList in potPosList2: if potPosList == None: continue for potPos in potPosList: tl = [potPos[0] - potSize[0]//2, potPos[1] - potSize[1]//2] bl = [potPos[0] - potSize[0]//2, potPos[1] + potSize[1]//2] br = [potPos[0] + potSize[0]//2, potPos[1] + potSize[1]//2] tr = [potPos[0] + potSize[0]//2, potPos[1] - potSize[1]//2] self.potList.append([tl, bl, br, tr]) self.updateFigure() self.status.append('Done') else: self.status.append('Pipeline or setting file is missing.') def rotateImage90Degrees(self): if self.image == None: self.status.append('No image to rotate.') return self.rotationAngle = self.rotationAngle + 90 if self.rotationAngle >= 360: self.rotationAngle = self.rotationAngle - 360 self.image = np.rot90(self.image) #.astype(uint8) self.status.append('Rot. angle = %d deg' %self.rotationAngle) self.updateFigure(resetFigure = True) def rotateSmallAngle(self, value): self.smaleRotationAngle = float(value)/4.0 if self.image != None: self.rotatedImage = cd.rotateImage(self.image, self.smaleRotationAngle) self.updateFigure(self.rotatedImage) self.status.append('Rot. angle = %f deg' %(self.rotationAngle + self.smaleRotationAngle)) def applySmallRotation(self): if self.image != None: self.image = cd.rotateImage(self.image, self.smaleRotationAngle) self.updateFigure() self.status.append('Apply small angle rotation') def onMouseClicked(self, event): if self.panMode or self.zoomMode: return print('click', event.button, event.xdata, event.ydata) if event.button == 1 and event.xdata != None and event.ydata != None: self.leftClicks.append([event.xdata, event.ydata]) print('self.leftClicks =', self.leftClicks) Rect = [] AspectRatio = None if self.trayRadioButton.isChecked(): AspectRatio = self.trayAspectRatio elif self.colorcardRadioButton.isChecked(): AspectRatio = self.colorcardAspectRatio elif self.potRadioButton.isChecked(): AspectRatio = self.potAspectRatio if len(self.leftClicks) == 2 and AspectRatio != None: if self.colorcardRadioButton.isChecked(): Rect = cd.getRectCornersFrom2Points(self.image, self.leftClicks, AspectRatio) if self.trayRadioButton.isChecked(): Rect = cd.getRectCornersFrom2Points(self.image, self.leftClicks, AspectRatio, Rounded = self.trayRoundCheckBox.isChecked()) elif self.potRadioButton.isChecked(): Rect = cd.getRectCornersFrom2Points(self.image, self.leftClicks, AspectRatio, Rounded = True) self.leftClicks = [] elif len(self.leftClicks) == 4: Rect = [[x,y] for x,y in self.leftClicks] Rect = cd.correctPointOrder(Rect) self.leftClicks = [] if len(Rect) > 0: if self.trayRadioButton.isChecked(): self.trayList.append(Rect) self.status.append('Added tray selection.') elif self.colorcardRadioButton.isChecked(): self.colorcardList.append(Rect) self.status.append('Added color card selection.') else: self.potList.append(Rect) self.status.append('Added pot selection.') self.updateFigure() elif event.button == 3: # remove the last selection if len(self.leftClicks) > 0: self.leftClicks = self.leftClicks[:-1] self.status.append('Removed a previous click') else: if self.trayRadioButton.isChecked() and len(self.trayList) > 0: self.trayList = self.trayList[:-1] self.status.append('Removed a previous tray selection') elif self.colorcardRadioButton.isChecked() and len(self.colorcardList) > 0: self.colorcardList = self.colorcardList[:-1] self.status.append('Removed a previous color card selection.') elif self.potRadioButton.isChecked() and len(self.potList) > 0: self.potList = self.potList[:-1] self.status.append('Removed a previous pot selection') self.updateFigure() else: print('Ignored click') def onMouseMoves(self, event): if event.inaxes == self.ax: self.mousePosition.setText('x=%d, y=%d' %(event.xdata, event.ydata)) # self.crosshair = [event.xdata, event.ydata] else: self.mousePosition.setText('') # self.crosshair = None # self.updateFigure() def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_Escape: self.close() def closeEvent(self, event): quit_msg = "Are you sure you want to exit the program?" reply = QtGui.QMessageBox.question(self, 'Message', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: self.saveInputs() event.accept() else: event.ignore() def saveInputs(self): with open('./.inputs.yml', 'w') as myfile: dicInputs = {'rootPath': str(self.timestreamText.text()), 'startDate': str(self.timestreamDateText.text()), 'timeInterval': str(self.timestreamTimeText.text()), } myfile.write( yaml.dump(dicInputs, default_flow_style=None) ) def loadPreviousInputs(self): try: with open('./.inputs.yml', 'r') as myfile: dicInputs = yaml.load(myfile) self.timestreamText.setText(dicInputs['rootPath']) self.timestreamDateText.setText(dicInputs['startDate']) self.timestreamTimeText.setText(dicInputs['timeInterval']) except: pass
class smileiQtPlot(QWidget): scalarDict=dict() fieldDict=dict() phaseDict=dict() fieldFile=None phaseFile=None nplots=0 ax={} dirName=None someCheckBoxChanged=True pauseSignal=pyqtSignal() shiftPressed=False title='' def __init__(self,parent,dirName): super(smileiQtPlot, self).__init__() self.setParent(parent) uiFile=os.path.dirname(os.path.realpath(__file__))+'/smileiQtPlot.ui' self.ui=uic.loadUi(uiFile,self) self.dirName=dirName self.parent=parent self.parent.timer.timeout.connect(self.next) self.parent.ui.next.released.connect(self.next) self.parent.ui.previous.released.connect(self.previous) self.parent.ui.first.released.connect(self.first) self.parent.ui.last.released.connect(self.last) self.pauseSignal.connect(self.parent.pause) self.setWindowFlags(Qt.Window) self.setWindowTitle(dirName) self.step=0 self.ui.savePoints.setIcon(self.ui.style().standardIcon(QStyle.SP_DialogSaveButton)) self.ui.savePoints.released.connect(self.doSavePoints) self.ui.tabWidget.currentChanged.connect(self.changeTab) self.ui.autoScale.stateChanged.connect(self.doPlots) self.fig = Figure() self.ui.reload.setIcon(self.ui.style().standardIcon(QStyle.SP_BrowserReload)) self.ui.reload.released.connect(self.reloadAll) self.canvas = FigureCanvas(self.fig) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.mpl_connect('motion_notify_event', self.on_movement) self.canvas.mpl_connect('key_press_event', self.on_key_press) self.canvas.mpl_connect('key_release_event', self.on_key_release) self.canvas.mpl_connect('button_press_event', self.on_button_press) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.setFixedHeight(18) self.canvas.setCursor(Qt.CrossCursor) self.ui.plotLayout.addWidget(self.canvas) self.ui.plotLayout.addWidget(self.toolbar) fname=os.path.join(dirName, "scalars.txt") if os.path.isfile(fname) : self.scalarData = np.loadtxt(fname) names=[] for line in open(fname): li=line.strip() if li.startswith("#"): list=line.split() names.append(list[-1]) scalars_names=names[1:-2] for i in range(len(scalars_names)): my_button= QCheckBox(scalars_names[i]) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutScalars.addWidget(my_button) self.ui.layoutScalars.addStretch() else : print "Problem reading ",fname # self.deleteLater() self.fieldSteps=[] fname=os.path.join(dirName, "Fields.h5") if os.path.isfile(fname) : self.fieldFile=tb.openFile(fname) self.cell_length=self.fieldFile.root._v_attrs.cell_length[0] self.res_time=self.fieldFile.root._v_attrs.res_time self.sim_length=self.fieldFile.root._v_attrs.sim_length # JDT self.fieldEvery=self.fieldFile.root._v_attrs.every first=True for group in self.fieldFile.listNodes("/", classname='Group'): self.fieldSteps.append(group._v_name) if first: first=False for array in group: my_button= QCheckBox(array._v_name) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutFields.addWidget(my_button) self.ui.layoutFields.addStretch() self.ui.slider.setRange(0,len(self.fieldSteps)-1) else : print "Problem reading ",fname # self.deleteLater() self.ui.spinStep.setSuffix("/"+str(len(self.fieldSteps)-1)) self.ui.spinStep.setMaximum(len(self.fieldSteps)-1) fname=os.path.join(dirName, "PhaseSpace.h5") if os.path.isfile(fname) : self.phaseFile=tb.openFile(fname) for phaseData in self.phaseFile.walkNodes("/", classname='Array'): my_button= QCheckBox(phaseData._v_pathname) my_button.stateChanged.connect(self.checkBoxChanged) self.ui.layoutPhase.addWidget(my_button) self.ui.layoutPhase.addStretch() else : print "Problem reading ",fname # self.deleteLater() self.load_settings() if sys.platform == "darwin": self.raise_() self.show() def reloadAll(self): self.fieldSteps=[] fname=os.path.join(self.dirName, "Fields.h5") if isinstance(self.fieldFile,tb.file.File): self.fieldFile.close() if os.path.isfile(fname) : self.fieldFile=tb.openFile(fname) for group in self.fieldFile.listNodes("/", classname='Group'): self.fieldSteps.append(group._v_name) print "last:",self.fieldSteps[-1] self.ui.spinStep.setSuffix("/"+str(len(self.fieldSteps)-1)) self.ui.spinStep.setMaximum(len(self.fieldSteps)-1) self.ui.slider.setRange(0,len(self.fieldSteps)-1) self.preparePlots() def doSavePoints(self): fname=QFileDialog.getSaveFileName(self, 'Save Point logger', self.dirName, selectedFilter='*.txt') if fname: f = open(fname, 'w') f.write(self.ui.logger.toPlainText()) f.close() def checkBoxChanged(self): self.someCheckBoxChanged=True def load_settings(self): settings=QSettings(QFileInfo(__file__).fileName(),"") settings.beginGroup(QDir(self.dirName).dirName()) log.info("settings file: %s"%settings.fileName()) frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): chkbox.setChecked(settings.value(chkbox.text()).toBool()) settings.endGroup() settings.endGroup() self.ui.tabWidget.setCurrentIndex(0) def save_settings(self): settings=QSettings(QFileInfo(__file__).fileName(),"") settings.beginGroup(QDir(self.dirName).dirName()) frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : settings.beginGroup(frame.objectName()) for chkbox in frame.findChildren(QCheckBox): settings.setValue(chkbox.text(),chkbox.isChecked()) settings.endGroup() settings.endGroup() def next(self): self.ui.slider.setValue(self.step+1) def previous(self): self.ui.slider.setValue(self.step-1) def first(self): self.ui.slider.setValue(0) def last(self): self.ui.slider.setValue(len(self.fieldSteps)-1) def on_slider_valueChanged(self,step): self.step=step self.doPlots() @pyqtSignature("int") def on_spinStep_valueChanged(self,my_step): self.ui.slider.setValue(my_step) @pyqtSignature("int") def changeTab(self, tabNum): if self.ui.tabWidget.currentIndex()==0: self.doPlots() else: self.pauseSignal.emit() def preparePlots(self): self.someCheckBoxChanged=False self.scalarDict=dict() self.fieldDict=dict() self.phaseDict=dict() self.nplots=0 frames=[self.ui.scalars, self.ui.fields, self.ui.phase] for frame in [self.ui.scalars, self.ui.fields, self.ui.phase] : for chkbox in frame.findChildren(QCheckBox): if chkbox.isChecked() : self.nplots+=1 if self.nplots > 0: self.fig.clear() self.title=self.fig.suptitle('') self.ax={} plot=0 col=0 log.info("preparing scalars") for i in self.ui.scalars.findChildren(QCheckBox): col+=1 if i.isChecked() : name=str(i.text()) if not (name in self.fieldDict): x=self.scalarData[:,0] y=self.scalarData[:,col] self.scalarDict[name]=(x,y) ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.plot(x,y) ax.set_xlim(x.min(),x.max()) ax.set_ylabel(name) ax.axvline(x=0,c="red",linewidth=2,zorder=0, clip_on=False) self.ax[name]=ax plot+=1 log.info("preparing fields") for i in self.ui.fields.findChildren(QCheckBox): if i.isChecked() : log.info(i.text()) ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) data=[] name=str(i.text()) for d in self.fieldFile.root: data.append(d._f_getChild(name)) self.fieldDict[name]=data if len(self.sim_length) == 1 : ax.set_xlim(0,self.sim_length) ax.set_ylabel(name) x=np.array(range(len(data[0])))*self.cell_length y=data[0].read() ax.plot(x,y) self.ax[name]=ax elif len(self.sim_length) == 2 : divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) ax.set_ylabel(name) im=ax.imshow([[0]],extent=(0,self.sim_length[0],0,self.sim_length[1]), aspect='auto',origin='lower') im.set_interpolation('nearest') cb=plt.colorbar(im, cax=cax) self.ax[name]=ax plot+=1 log.info("preparing phase") for i in self.ui.phase.findChildren(QCheckBox): if i.isChecked() : name=str(i.text()) node=self.phaseFile.getNode(name) self.phaseDict[name]=node ax=self.fig.add_subplot(self.nplots,1,plot+1) ax.xaxis.grid(True) ax.yaxis.grid(True) ax.set_ylabel(name) divider = make_axes_locatable(ax) cax = divider.new_horizontal(size="2%", pad=0.05) self.fig.add_axes(cax) im=ax.imshow([[0]],extent=node._v_attrs.extents.reshape(4).tolist(),aspect='auto',origin='lower') im.set_interpolation('nearest') cb=plt.colorbar(im, cax=cax) self.ax[name]=ax plot+=1 log.info("done") self.doPlots() def on_movement(self, event): if not event.inaxes: return msg = "%G %G" % (event.xdata, event.ydata) self.ui.pos.setText(msg) def on_key_press(self,event): if not event.inaxes: return if event.key == 'a': for line in event.inaxes.lines : if line.get_xdata().size > 1: data=line.get_ydata() nonzero=data[np.nonzero(data)] if len(nonzero) : mini=np.min(nonzero) maxi=np.max(nonzero) if mini != maxi : event.inaxes.set_ylim(mini,maxi) for image in event.inaxes.images : data=np.array(image.get_array()) nonzero=data[np.nonzero(data)] if len(nonzero) : mini=np.min(nonzero) maxi=np.max(nonzero) if mini != maxi : image.set_clim(mini,maxi) self.canvas.draw() elif event.key == 'l': if event.inaxes.lines : scale='log' if event.inaxes.get_yaxis().get_scale()== 'linear' else 'linear' try: event.inaxes.set_yscale(scale) self.canvas.draw() except ValueError: scale='log' if scale == 'linear' else 'linear' event.inaxes.set_yscale(scale) self.canvas.draw() elif event.inaxes.images : for image in event.inaxes.images : mini = np.array(image.get_array()).clip(0).min() if mini >0: maxi = np.array(image.get_array()).clip(0).max() pprint (vars(event.inaxes.images[0].norm)) try: event.inaxes.images[0].set_norm(LogNorm(mini,maxi)) self.canvas.draw() except ValueError: self.canvas.draw() elif event.key == 'x': range, ok = QInputDialog.getText(self, 'Ranges', 'Give '+event.key+' range:') if ok: ranges=range.split(' ') event.inaxes.set_xlim(float(ranges[0]),float(ranges[1])) self.canvas.draw() elif event.key == 'y': range, ok = QInputDialog.getText(self, 'Ranges', 'Give '+event.key+' range:') if ok: ranges=range.split(' ') event.inaxes.set_ylim(float(ranges[0]),float(ranges[1])) self.canvas.draw() elif event.key == 'c': range, ok = QInputDialog.getText(self, 'Ranges', 'Give '+event.key+' range:') if ok: ranges=range.split(' ') event.inaxes.images[0].set_clim(float(ranges[0]),float(ranges[1])) self.canvas.draw() elif event.key == 'shift': self.shiftPressed=True def on_key_release(self,event): if not event.inaxes: return if event.key == 'shift': self.shiftPressed=False def on_button_press(self,event): if not event.inaxes: return if self.shiftPressed == True : self.ui.logger.moveCursor (QTextCursor.End); for i in range(len(self.fig.axes)) : if self.fig.axes[i] == event.inaxes: # JDT txt = "%d %G %G %G\n" % (i, self.step/self.res_time*self.fieldEvery, event.xdata, event.ydata) txt = "%d %G %G\n" % (i, event.xdata, event.ydata) QApplication.clipboard().setText(txt) self.ui.logger.insertPlainText(txt); self.ui.logger.moveCursor (QTextCursor.End); def doPlots(self): if len(self.fieldSteps) == 0 : return if self.someCheckBoxChanged==True: self.preparePlots() self.step %= len(self.fieldSteps) self.slider.setValue(self.step) self.ui.spinStep.setValue(self.step) # JDT time=float(self.step)/self.res_time*self.fieldEvery time=float(self.step)/self.res_time for name in self.scalarDict: self.ax[name].lines[-1].set_xdata(time) for name in self.fieldDict: data=self.fieldDict[name][self.step].read() if len(self.sim_length) == 1 : self.ax[name].lines[-1].set_ydata(data) if self.ui.autoScale.isChecked(): self.ax[name].set_ylim(min(data),max(data)) elif len(self.sim_length) == 2 : im=self.ax[name].images[-1] npData=np.array(data) im.set_data(npData.T) if self.ui.autoScale.isChecked(): im.set_clim(npData.min(),npData.max()) for name in self.phaseDict: data=self.phaseDict[name][self.step].T im=self.ax[name].images[-1] im.set_data(data) if self.ui.autoScale.isChecked(): im.set_clim(data.min(),data.max()) self.title.set_text('Time: %.3f'%time) self.canvas.draw() if self.ui.saveImages.isChecked(): fname=self.dirName+'/frame-%06d.png' % self.step print fname self.fig.savefig(fname) def closeEvent(self,event): self.save_settings() if self.fieldFile is not None : self.fieldFile.close() if self.phaseFile is not None : self.phaseFile.close() self.parent.plots.remove(self) QApplication.processEvents() self.deleteLater()
class Window(QtGui.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.canvas.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.hide() # Just some button self.colorcardRadioButton = QtGui.QRadioButton('Select color car&d') self.colorcardRadioButton.setChecked(False) self.colorcardRadioButton.clicked.connect(self.selectWhat) self.trayRadioButton = QtGui.QRadioButton('Select &tray') self.trayRadioButton.setChecked(False) self.trayRadioButton.clicked.connect(self.selectWhat) self.potRadioButton = QtGui.QRadioButton('Select &pot') self.potRadioButton.setChecked(False) self.potRadioButton.clicked.connect(self.selectWhat) self.loadImageButton = QtGui.QPushButton('&Load image') self.loadImageButton.clicked.connect(self.loadImage) self.rotateImageButton = QtGui.QPushButton('&Rotate 90-deg') self.rotateImageButton.clicked.connect(self.rotateImage90Degrees) self.loadCamCalibButton = QtGui.QPushButton('Load &cam. param.') self.loadCamCalibButton.clicked.connect(self.loadCamCalib) self.saveGeometriesButton = QtGui.QPushButton('&Save selected geometries') self.saveGeometriesButton.clicked.connect(self.saveSelectedGeometries) self.saveTraysButton = QtGui.QPushButton('&Save selected tray images') self.saveTraysButton.clicked.connect(self.saveSelectedTrayImages) self.saveColorcadButton = QtGui.QPushButton('&Save sel. col. card images') self.saveColorcadButton.clicked.connect(self.saveSelectedColorcardImages) self.save2PipelineButton = QtGui.QPushButton('&Save as pipeline settings') self.save2PipelineButton.clicked.connect(self.savePipelineSettings) self.zoomButton = QtGui.QPushButton('&Zoom') self.zoomButton.setCheckable(True) self.zoomButton.clicked.connect(self.zoom) self.panButton = QtGui.QPushButton('&Pan') self.panButton.setCheckable(True) self.panButton.clicked.connect(self.pan) self.homeButton = QtGui.QPushButton('&Home') self.homeButton.clicked.connect(self.home) self.status = QtGui.QTextEdit('') self.status.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) self.mousePosition = QtGui.QLabel('') # set the layout layout = QtGui.QHBoxLayout() rightWidget = QtGui.QWidget() buttonlayout = QtGui.QVBoxLayout(rightWidget) buttonlayout.addWidget(self.loadImageButton) buttonlayout.addWidget(self.rotateImageButton) buttonlayout.addWidget(self.loadCamCalibButton) buttonlayout.addWidget(self.colorcardRadioButton) buttonlayout.addWidget(self.trayRadioButton) buttonlayout.addWidget(self.potRadioButton) buttonlayout.addWidget(self.zoomButton) buttonlayout.addWidget(self.panButton) buttonlayout.addWidget(self.homeButton) buttonlayout.addWidget(self.saveGeometriesButton) buttonlayout.addWidget(self.saveColorcadButton) buttonlayout.addWidget(self.saveTraysButton) buttonlayout.addWidget(self.save2PipelineButton) buttonlayout.addWidget(self.status) buttonlayout.addWidget(self.mousePosition) rightWidget.setMaximumWidth(200) leftLayout = QtGui.QVBoxLayout() leftLayout.addWidget(self.toolbar) leftLayout.addWidget(self.canvas) layout.addWidget(rightWidget) layout.addLayout(leftLayout) self.setLayout(layout) self.group = QtGui.QButtonGroup() self.group.addButton(self.colorcardRadioButton) self.group.addButton(self.trayRadioButton) self.group.addButton(self.potRadioButton) self.panMode = False self.zoomMode = False self.ax = None self.plotRect = None self.plotImg = None self.image = None self.potTemplate = None self.UndistMapX = None self.UndistMapY = None self.trayAspectRatio = 0.835 self.colorcardAspectRatio = 1.5 self.potAspectRatio = 1.0 self.leftClicks = [] self.ImageSize = None self.CameraMatrix = None self.DistCoefs = None # # change cursor shape # self.setCursor(QtGui.QCursor(QtCore.Qt.CrossCursor )) # Ouput parameters self.colorcardList = [] self.trayList = [] self.potList = [] self.rotationAngle = 0 self.isDistortionCorrected = False def selectWhat(self): if self.trayRadioButton.isChecked(): self.status.append('Start selecting tray.') elif self.colorcardRadioButton.isChecked(): self.status.append('Start selecting color bar.') else: self.status.append('Start selecting pot.') def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() if not self.zoomMode: self.zoomMode = True self.panMode = False self.panButton.setChecked(False) else: self.zoomMode = False def pan(self): self.toolbar.pan() if not self.panMode: self.panMode = True self.zoomMode = False self.zoomButton.setChecked(False) else: self.panMode = False def loadImage(self): ''' load and show an image''' fname = QtGui.QFileDialog.getOpenFileName(self, 'Open image', '/mnt/phenocam/a_data/TimeStreams/BorevitzTest/BVZ0036/BVZ0036-GC02L~fullres-orig/2014/2014_06/2014_06_20/2014_06_20_12') self.status.append('Loading image...') app.processEvents() self.image = cv2.imread(str(fname))[:,:,::-1] self.status.append('Loaded image from ' + str(fname)) # reset all outputs self.colorcardList = [] self.trayList = [] self.potList = [] self.rotationAngle = 0 self.isDistortionCorrected = False # Undistort image if mapping available if not self.isDistortionCorrected and self.UndistMapX != None and self.UndistMapY != None: self.image = cv2.remap(self.image.astype(np.uint8), self.UndistMapX, self.UndistMapY, cv2.INTER_CUBIC) self.isDistortionCorrected = True if self.image != None: if self.ax == None: self.ax = self.figure.add_subplot(111) self.ax.figure.canvas.mpl_connect('button_press_event', self.onMouseClicked) self.ax.figure.canvas.mpl_connect('motion_notify_event', self.onMouseMoves) self.ax.figure.canvas.mpl_connect('figure_enter_event', self.changeCursor) self.ax.hold(False) if self.plotImg == None: self.plotImg = self.ax.imshow(self.image) else: self.plotImg.set_data(self.image) self.figure.tight_layout() self.canvas.draw() def changeCursor(self, event): # cursor = Cursor(self.ax, useblit=True, color='red', linewidth=1) self.canvas.setCursor(QtGui.QCursor(QtCore.Qt.CrossCursor )) def updateFigure(self): xs, ys = [], [] for Rect in self.colorcardList: tl, bl, br, tr = Rect xs = xs + [tl[0], bl[0], br[0], tr[0], tl[0], np.nan] ys = ys + [tl[1], bl[1], br[1], tr[1], tl[1], np.nan] for Rect in self.trayList: tl, bl, br, tr = Rect xs = xs + [tl[0], bl[0], br[0], tr[0], tl[0], np.nan] ys = ys + [tl[1], bl[1], br[1], tr[1], tl[1], np.nan] for Rect in self.potList: tl, bl, br, tr = Rect xs = xs + [tl[0], bl[0], br[0], tr[0], tl[0], np.nan] ys = ys + [tl[1], bl[1], br[1], tr[1], tl[1], np.nan] for x,y in self.leftClicks: xs = xs + [x] ys = ys + [y] # if self.crosshair != None: # xs = xs + [np.nan, 0, self.image.shape[1], np.nan, self.crosshair[0], self.crosshair[0], np.nan] # ys = ys + [np.nan, self.crosshair[1], self.crosshair[1], np.nan, 0, self.image.shape[0], np.nan] if len(xs) > 0 and len(ys) > 0: if self.plotRect == None: self.ax.hold(True) self.plotRect, = self.ax.plot(xs, ys, 'b') self.ax.hold(False) self.ax.set_xlim([0,self.image.shape[1]]) self.ax.set_ylim([0,self.image.shape[0]]) self.ax.invert_yaxis() else: self.plotRect.set_data(xs, ys) self.canvas.draw() app.processEvents() def loadCamCalib(self): ''' load camera calibration image and show an image''' CalibFile = QtGui.QFileDialog.getOpenFileName(self, 'Open image', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') self.ImageSize, SquareSize, self.CameraMatrix, self.DistCoefs, RVecs, TVecs = utils.readCalibration(CalibFile) self.status.append('Loaded camera parameters from ' + CalibFile) print('CameraMatrix =', self.CameraMatrix) print('DistCoefs =', self.DistCoefs) self.UndistMapX, self.UndistMapY = cv2.initUndistortRectifyMap(self.CameraMatrix, self.DistCoefs, \ None, self.CameraMatrix, self.ImageSize, cv2.CV_32FC1) if self.image != None: self.image = cv2.remap(self.image.astype(np.uint8), self.UndistMapX, self.UndistMapY, cv2.INTER_CUBIC) self.isDistortionCorrected = True self.status.append('Corrected image distortion.') if self.plotImg == None: self.plotImg = self.ax.imshow(self.image) else: self.plotImg.set_data(self.image) self.canvas.draw() # def loadPotTemplate(self): # ''' load pot template image''' # fname = QtGui.QFileDialog.getOpenFileName(self, 'Open image', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') # self.status.append('Loading image...') # app.processEvents() # self.potTemplate = cv2.imread(str(fname))[:,:,::-1] # if len(self.potList) > 0: def saveSelectedGeometries(self): ''' save selected geometries''' fname = QtGui.QFileDialog.getSaveFileName(self, 'Save selected geometries', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') colorcardList2 = [] for colorcard in self.colorcardList: colorcardList2 = colorcardList2 + colorcard trayList2 = [] for tray in self.trayList: trayList2 = trayList2 + tray potList2 = [] for pot in self.potList: potList2 = potList2 + pot dicdata = {'colorcardself.crosshair = NoneList':np.asarray(colorcardList2), \ 'trayList':np.asarray(trayList2), \ 'potList':np.asarray(potList2), \ 'rotationAngle':self.rotationAngle, \ 'distortionCorrected':int(self.isDistortionCorrected)} cv2yml.dic2yml(fname, dicdata) self.status.append('Saved selected geometries to ' + fname) def saveSelectedTrayImages(self): ''' save selected trays''' fname = QtGui.QFileDialog.getSaveFileName(self, 'Save selected tray images', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') medianWidth, medianHeight = utils.getMedianRectSize(self.trayList) rectifiedTrayImages = utils.rectifyRectImages(self.image, self.trayList, MedianSize = [medianWidth, medianHeight]) for i,rectifiedImage in enumerate(rectifiedTrayImages): cv2.imwrite(str(fname) %i, rectifiedImage) def saveSelectedColorcardImages(self): ''' save selected trays''' fname = QtGui.QFileDialog.getSaveFileName(self, 'Save selected color card images', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') medianWidth, medianHeight = utils.getMedianRectSize(self.colorcardList) rectifiedColorcardImages = utils.rectifyRectImages(self.image, self.colorcardList, MedianSize = [medianWidth, medianHeight]) for i,rectifiedImage in enumerate(rectifiedColorcardImages): cv2.imwrite(str(fname) %i, rectifiedImage) def savePipelineSettings(self): ''' save to pipeline setting file''' fname = QtGui.QFileDialog.getSaveFileName(self, 'Save selection to pipeline settings', '/home/chuong/Workspace/traitcapture-bin/unwarp_rectify/data') settingPath = os.path.dirname(str(fname)) settings = [] if self.ImageSize != None and self.CameraMatrix != None and self.DistCoefs != None: undistort = ['undistort', \ {'mess': 'perform optical undistortion', \ 'cameraMatrix': self.CameraMatrix.tolist(), \ 'distortCoefs': self.DistCoefs.tolist(), \ 'imageSize': list(self.ImageSize), 'rotationAngle': self.rotationAngle } \ ] else: undistort = ['undistort', {'mess': '---skip optical undistortion---'}] settings.append(undistort) if len(self.colorcardList) > 0: medianSize = utils.getMedianRectSize(self.colorcardList) capturedColorcards = utils.rectifyRectImages(self.image, self.colorcardList, medianSize) colorCardFile = 'CapturedColorcard.png' cv2.imwrite(os.path.join(settingPath, colorCardFile), capturedColorcards[0][:,:,::-1].astype(np.uint8)) colorcardColors, colorStd = utils.getColorcardColors(capturedColorcards[0], GridSize = [6,4]) colorcardPosition, Width, Height, Angle = utils.getRectangleParamters(self.colorcardList[0]) colorcarddetect = ['colorcarddetect', \ {'mess': '---perform color card detection---', \ 'colorcardFile': colorCardFile,\ 'colorcardPosition': colorcardPosition.tolist(),\ 'colorcardTrueColors': utils.CameraTrax_24ColorCard } ] else: colorcarddetect = ['colorcarddetect', {'mess': '---skip color card detection---'}] settings.append(colorcarddetect) colorcorrect = ['colorcorrect', {'mess': '---perform color correction---'}] settings.append(colorcorrect) if len(self.trayList) > 0: trayMedianSize = utils.getMedianRectSize(self.trayList) trayImages = utils.rectifyRectImages(self.image, self.trayList, trayMedianSize) colorcardColors, colorStd = utils.getColorcardColors(capturedColorcards[0], GridSize = [6,4]) trayDict = {'mess': '---perform tray detection---'} trayDict['trayNumber'] = len(self.trayList) trayDict['trayFiles'] = 'Tray_%02d.png' trayPositions = [] for i,tray in enumerate(trayImages): cv2.imwrite(os.path.join(settingPath, trayDict['trayFiles'] %i), tray[:,:,::-1].astype(np.uint8)) trayPosition, Width, Height, Angle = utils.getRectangleParamters(self.trayList[i]) trayPositions.append(trayPosition.tolist()) trayDict['trayPositions'] = trayPositions traydetect = ['traydetect', trayDict] else: traydetect = ['traydetect', {'mess': '---skip tray detection---'}] settings.append(traydetect) if len(self.potList) > 0: trayMedianSize = utils.getMedianRectSize(self.trayList) potPosition, Width, Height, Angle = utils.getRectangleParamters(self.potList[0]) Width, Height = int(Width), int(Height) topLeft = [int(self.potList[0][0][0]), int(self.potList[0][0][1])] self.potImage = self.image[topLeft[1]:topLeft[1]+Height, topLeft[0]:topLeft[0]+Width, :] potFile = 'Pot.png' cv2.imwrite(os.path.join(settingPath, potFile), self.potImage[:,:,::-1].astype(np.uint8)) potDict = {'mess': '---perform pot detection---'} potDict['potPosition'] = potPosition.tolist() potDict['potSize'] = [int(Width), int(Height)] potDict['traySize'] = [int(trayMedianSize[0]), int(trayMedianSize[1])] potDict['potFile'] = potFile if self.potTemplate != None: potTemplateFile = 'potTemplate.png' cv2.imwrite(os.path.join(settingPath, potTemplateFile), self.potTemplate[:,:,::-1]) potDict['potTemplateFile'] = potTemplateFile potdetect = ['potdetect', potDict] else: potdetect = ['potdetect', {'mess': '---skip pot detection---'}] settings.append(potdetect) plantextract = ['plantextract', {'mess': '---perfrom plant biometrics extraction---'}] settings.append(plantextract) with open(fname, 'w') as outfile: outfile.write( yaml.dump(settings, default_flow_style=None) ) def rotateImage90Degrees(self): if self.image == None: self.status.append('No image to rotate.') return self.rotationAngle = self.rotationAngle + 90 if self.rotationAngle >= 360: self.rotationAngle = self.rotationAngle - 360 self.image = np.rot90(self.image) #.astype(uint8) self.status.append('Rot. angle = %d deg' %self.rotationAngle) if self.plotImg == None: self.plotImg = self.ax.imshow(self.image) else: self.plotImg.set_data(self.image) self.canvas.draw() def onMouseClicked(self, event): if self.panMode or self.zoomMode: return print('click', event.button, event.xdata, event.ydata) if event.button == 1 and event.xdata != None and event.ydata != None: self.leftClicks.append([event.xdata, event.ydata]) print('self.leftClicks =', self.leftClicks) Rect = [] AspectRatio = None if self.trayRadioButton.isChecked(): AspectRatio = self.trayAspectRatio elif self.colorcardRadioButton.isChecked(): AspectRatio = self.colorcardAspectRatio elif self.potRadioButton.isChecked(): AspectRatio = self.potAspectRatio if len(self.leftClicks) == 2 and AspectRatio != None: if self.potRadioButton.isChecked(): Rect = utils.getRectCornersFrom2Points(self.image, self.leftClicks, AspectRatio, Rounded = True) else: Rect = utils.getRectCornersFrom2Points(self.image, self.leftClicks, AspectRatio) self.leftClicks = [] elif len(self.leftClicks) == 4: Rect = [[x,y] for x,y in self.leftClicks] Rect = utils.correctPointOrder(Rect) self.leftClicks = [] if len(Rect) > 0: if self.trayRadioButton.isChecked(): self.trayList.append(Rect) self.status.append('Added tray selection.') elif self.colorcardRadioButton.isChecked(): self.colorcardList.append(Rect) self.status.append('Added color card selection.') else: self.potList.append(Rect) self.status.append('Added pot selection.') self.updateFigure() elif event.button == 3: # remove the last selection if len(self.leftClicks) > 0: self.leftClicks = self.leftClicks[:-1] self.status.append('Removed a previous click') else: if self.trayRadioButton.isChecked() and len(self.trayList) > 0: self.trayList = self.trayList[:-1] self.status.append('Removed a previous tray selection') elif self.colorcardRadioButton.isChecked() and len(self.colorcardList) > 0: self.colorcardList = self.colorcardList[:-1] self.status.append('Removed a previous color card selection.') elif self.potRadioButton.isChecked() and len(self.potList) > 0: self.potList = self.potList[:-1] self.status.append('Removed a previous pot selection') self.updateFigure() else: print('Ignored click') def onMouseMoves(self, event): if event.inaxes == self.ax: self.mousePosition.setText('x=%d, y=%d' %(event.xdata, event.ydata)) # self.crosshair = [event.xdata, event.ydata] else: self.mousePosition.setText('') # self.crosshair = None # self.updateFigure() def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_Escape: self.close() def closeEvent(self, event): quit_msg = "Are you sure you want to exit the program?" reply = QtGui.QMessageBox.question(self, 'Message', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: event.accept() else: event.ignore()
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(1500, 842) MainWindow.setAutoFillBackground(False) MainWindow.setStyleSheet(_fromUtf8("background-color: rgb(197, 197, 197)")) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.stackedWidget = QtGui.QStackedWidget(self.centralwidget) self.stackedWidget.setGeometry(QtCore.QRect(0, 0, 1500, 842)) self.stackedWidget.setObjectName(_fromUtf8("stackedWidget")) self.page1 = QtGui.QWidget() self.page1.setObjectName(_fromUtf8("page")) self.lineEdit1 = QtGui.QLineEdit(self.page1) self.lineEdit1.setGeometry(QtCore.QRect(810, 340, 129, 27)) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lineEdit1.sizePolicy().hasHeightForWidth()) self.lineEdit1.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setFamily(_fromUtf8("URW Chancery L")) font.setPointSize(18) #self.lineEdit1.setStyleSheet(_fromUtf8("background-color: rgb(166, 166, 166)")) self.lineEdit1.setFont(font) self.lineEdit1.setAutoFillBackground(True) self.lineEdit1.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase) self.lineEdit1.setObjectName(_fromUtf8("lineEdit1")) self.label1 = QtGui.QLabel(self.page1) self.label1.setGeometry(QtCore.QRect(600, 320, 191, 71)) font = QtGui.QFont() font.setFamily(_fromUtf8("URW Palladio L")) font.setPointSize(24) self.label1.setFont(font) self.label1.setAutoFillBackground(False) self.label1.setObjectName(_fromUtf8("label1")) self.lineEdit1_2 = QtGui.QLineEdit(self.page1) self.lineEdit1_2.setGeometry(QtCore.QRect(810, 420, 129, 27)) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.lineEdit1_2.sizePolicy().hasHeightForWidth()) self.lineEdit1_2.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setFamily(_fromUtf8("URW Chancery L")) font.setPointSize(18) self.lineEdit1_2.setFont(font) #self.lineEdit1_2.setStyleSheet(_fromUtf8("background-color: rgb(166, 166, 166)")) self.lineEdit1_2.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase) self.lineEdit1_2.setObjectName(_fromUtf8("lineEdit1_2")) self.label1_2 = QtGui.QLabel(self.page1) self.label1_2.setGeometry(QtCore.QRect(600, 390, 191, 81)) font = QtGui.QFont() font.setFamily(_fromUtf8("URW Palladio L")) font.setPointSize(24) self.label1_2.setFont(font) self.label1_2.setAutoFillBackground(True) self.label1_2.setObjectName(_fromUtf8("label1_2")) self.label = QtGui.QLabel(self.page1) self.pixmap = QPixmap('small_400.jpg') self.label.setPixmap(self.pixmap) self.label.setGeometry(QtCore.QRect(560, 70, 400, 233)) self.label.setAutoFillBackground(True) self.label.setObjectName(_fromUtf8("label")) self.proceed = QtGui.QPushButton(self.page1) #self.proceed.setStyleSheet(_fromUtf8("background-color: rgb(166, 166, 166)")) self.proceed.setGeometry(QtCore.QRect(730, 490, 121, 31)) self.proceed.setObjectName(_fromUtf8("proceed")) self.proceed.clicked.connect(self.getInterface) self.stackedWidget.addWidget(self.page1) self.page2 = QtGui.QWidget() self.page2.setObjectName(_fromUtf8("page")) self.verticalLayout = QtGui.QVBoxLayout(self.page2) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setSizeConstraint(QtGui.QLayout.SetMaximumSize) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.horizontalLayout_2.setContentsMargins(-1, -1, -1, 10) self.verticalLayout_4 = QtGui.QVBoxLayout() self.verticalLayout_4.setContentsMargins(-1, 0, -1, -1) self.verticalLayout_4.setSpacing(30) self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.w = QtGui.QWidget() self.b = QtGui.QLabel(self.w) self.b.setText("Sniffing on interface:") self.c = QtGui.QLabel(self.w) self.c.setText("Timeout Limit") self.d = QtGui.QLabel(self.w) self.d.setText("ARP Table is Clean.\t\t") self.e = QtGui.QLabel(self.w) self.e.setText(".\t\t\t\t") self.listViewbtn = QtGui.QPushButton(self.w) self.listViewbtn.setGeometry(QtCore.QRect(40, 110, 75, 23)) self.listViewbtn.setObjectName(_fromUtf8("List_View")) self.listViewbtn.clicked.connect(self.switchView) self.c.move(2,30) self.d.move(2,60) self.e.move(2,80) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.w.sizePolicy().hasHeightForWidth()) self.verticalLayout_4.addWidget(self.w) self.fig5 = Figure(figsize=(1,1)) #self.fig5.patch.set_alpha(0.5) #self.ax = self.fig5.add_subplot(111) #self.ax.patch.set_facecolor('#ababab') #self.ax.patch.set_alpha(0.5) self.canvas5 = FigureCanvas(self.fig5) self.canvas5.setStyleSheet(_fromUtf8("background-color: transparent")) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.canvas5.sizePolicy().hasHeightForWidth()) clickable(self.canvas5).connect(lambda: self.swap(5)) self.canvas5.setSizePolicy(sizePolicy) self.verticalLayout_4.addWidget(self.canvas5) self.horizontalLayout_2.addLayout(self.verticalLayout_4) self.fig6 = Figure() self.canvas6 = FigureCanvas(self.fig6) self.canvas6.setStyleSheet("background-color: transparent;") sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.canvas6.sizePolicy().hasHeightForWidth()) self.canvas6.setSizePolicy(sizePolicy) #self.canvas6.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) #clickable(self.canvas6).connect(lambda: self.swap(5)) self.horizontalLayout_2.addWidget(self.canvas6) self.horizontalLayout_2.setStretch(0, 24) self.horizontalLayout_2.setStretch(1, 76) self.verticalLayout.addLayout(self.horizontalLayout_2) self.horizontalLayout = QtGui.QHBoxLayout() self.horizontalLayout.setSpacing(25) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.fig1 = Figure(figsize=(1,1)) self.canvas1 = FigureCanvas(self.fig1) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.canvas1.sizePolicy().hasHeightForWidth()) self.canvas1.setSizePolicy(sizePolicy) self.canvas1.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) clickable(self.canvas1).connect(lambda: self.swap(1)) self.horizontalLayout.addWidget(self.canvas1) self.fig2 = Figure(figsize=(1,1)) self.canvas2 = FigureCanvas(self.fig2) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.canvas2.sizePolicy().hasHeightForWidth()) self.canvas2.setSizePolicy(sizePolicy) self.canvas2.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) clickable(self.canvas2).connect(lambda: self.swap(2)) self.horizontalLayout.mouseReleaseEvent = print("hey") self.horizontalLayout.addWidget(self.canvas2) self.fig3 = Figure(figsize=(1,1)) self.canvas3 = FigureCanvas(self.fig3) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.canvas3.sizePolicy().hasHeightForWidth()) self.canvas3.setSizePolicy(sizePolicy) self.canvas3.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) clickable(self.canvas3).connect(lambda: self.swap(3)) self.horizontalLayout.addWidget(self.canvas3) self.fig4 = Figure(figsize=(1,1)) self.canvas4 = FigureCanvas(self.fig4) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.canvas4.sizePolicy().hasHeightForWidth()) self.canvas4.setSizePolicy(sizePolicy) self.canvas4.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) clickable(self.canvas4).connect(lambda: self.swap(4)) self.horizontalLayout.addWidget(self.canvas4) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.setStretch(0, 10) self.verticalLayout.setStretch(1, 4) self.stackedWidget.addWidget(self.page2) #List view: self.page3 = QtGui.QWidget() self.page3.setObjectName(_fromUtf8("page")) self.verticalLayout_List = QtGui.QVBoxLayout(self.page3) self.verticalLayout_List.setObjectName(_fromUtf8("verticalLayout_List")) self.tableWidget = QtGui.QTableWidget(self.centralwidget) self.tableWidget.setObjectName(_fromUtf8("tableWidget")) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth()) self.tableWidget.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self.tableWidget.setSizePolicy(sizePolicy) self.tableWidget.setColumnCount(6) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.cellClicked.connect(lambda:self.updateListView(self.tableWidget.currentRow())) print(dir(self.tableWidget.scroll)) self.tableWidget.setColumnWidth(0,220) self.tableWidget.setColumnWidth(1,220) self.tableWidget.setColumnWidth(2,220) self.tableWidget.setColumnWidth(3,220) self.tableWidget.setColumnWidth(4,220) self.tableWidget.setColumnWidth(5,220) self.tableWidget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.tableWidget.scrollToBottom() self.tableWidget.setRowCount(0) self.verticalLayout_List.addWidget(self.tableWidget) self.info = QtGui.QWidget() self.b1 = QtGui.QLabel(self.info) self.b1.setText("Sniffing on interface:") self.b2 = QtGui.QLabel(self.info) self.b2.setText("Sniffing on interface:") self.b2.move(0,30) self.b3 = QtGui.QLabel(self.info) self.b3.setText("Sniffing on interface:") self.b3.move(0,60) self.verticalLayout_List.addWidget(self.info) self.verticalLayout_List.setStretch(0, 4) self.verticalLayout_List.setStretch(1, 2) self.stackedWidget.addWidget(self.page3) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25)) self.menubar.setObjectName(_fromUtf8("menubar")) self.view = QtGui.QMenu(self.menubar) self.view.setObjectName(_fromUtf8("view")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.change_View = QtGui.QAction(MainWindow) self.change_View.setObjectName(_fromUtf8("change_view")) self.change_View.triggered.connect(self.switchView) self.view.addAction(self.change_View) self.menubar.addAction(self.view.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def mousePressEvent(self, QMouseEvent): print (QMouseEvent.pos()) def mouseReleaseEvent(self, QMouseEvent): cursor =QtGui.QCursor() print (cursor.pos()) def swap(self,a): global cur cur = a def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) self.listViewbtn.setText(_translate("List_View", "List View", None)) self.change_View.setText(_translate("change_view", "List View", None)) self.view.setTitle(_translate("MainWindow", "View", None)) self.label1.setText(_translate("MainWindow", "Interface :", None)) self.label1_2.setText(_translate("MainWindow", "Timeout :", None)) self.proceed.setText(_translate("MainWindow", "Proceed", None)) def getInterface(self): global sniffingInterface, sniffingTimeOut, t2 sniffingInterface = self.lineEdit1.text() sniffingTimeOut = int(self.lineEdit1_2.text()) print(sniffingInterface,sniffingTimeOut) self.stackedWidget.setCurrentIndex(1) self.plot() def switchView(self): global isListView if(isListView): self.change_View.setText("List View") self.stackedWidget.setCurrentIndex(1) isListView = False else: self.change_View.setText("Graphic View") self.stackedWidget.setCurrentIndex(2) isListView = True def plot(self): global cur global a global color global autoScroll global lenOfArray global x_base global arp_attack global mac_add ax1 = self.fig1.add_subplot(111) ax1.clear() ax1.set_ylim([0,60]) ax1.fill_between(x_base,0,a[0,-100:],linewidth=1.4,color=color[0]) self.canvas1.draw() ax2 = self.fig2.add_subplot(111) ax2.clear() ax2.set_ylim([0,60]) ax2.fill_between(x_base,0,a[1,-100:],linewidth=1.4,color=color[1]) self.canvas2.draw() ax3 = self.fig3.add_subplot(111) ax3.clear() ax3.set_ylim([0,60]) ax3.fill_between(x_base,0,a[2,-100:],linewidth=1.4,color=color[2]) self.canvas3.draw() ax4 = self.fig4.add_subplot(111) ax4.clear() ax4.set_ylim([0,60]) ax4.fill_between(x_base,0,a[3,-100:],linewidth=1.4,color=color[3]) self.canvas4.draw() ax5 = self.fig5.add_subplot(111) ax5.clear() ax5.set_ylim([0,60]) ax5.fill_between(x_base,0,a[4,-100:],linewidth=1.4,color=color[4]) self.canvas5.draw() ax6 = self.fig6.add_subplot(111) ax6.clear() ax6.set_ylim([0,60]) ax6.fill_between(x_base,0,a[cur-1,-100:],linewidth=3.0,color=color[cur-1]) self.canvas6.draw() if(lenOfArray<a.size): self.tableWidget.insertRow(self.tableWidget.rowCount()) for i in range(6): self.x = self.tableWidget.rowCount() self.tableWidget.setRowCount(self.x) self.tableWidget.setItem(self.x-1,i,QtGui.QTableWidgetItem(str(a[i,int(lenOfArray/6)]))) if(autoScroll): self.tableWidget.scrollToBottom() lenOfArray += 6 QtCore.QTimer.singleShot(1, self.plot) if(arp_attack): self.d.setText("ARP spoof detected") self.d.setStyleSheet(_fromUtf8("background-color: rgb(255, 10, 10)")) self.e.setText("Suspicious mac address: "+mac_add) self.e.setStyleSheet(_fromUtf8("background-color: rgb(255, 10, 10)")) def updateListView(self, x): global autoScroll autoScroll = False self.b1.setText("data"+str(a[0,x+100])) self.b2.setText("data"+str(a[1,x+100])) self.b3.setText("data"+str(a[2,x+100])) print(a[:,x+2])