def __init__(self, parent: Any = None): super().__init__(parent) self.setWindowTitle('text-from-image') self.central_widget = QSplitter(self) self.setCentralWidget(self.central_widget) self.image_view = ImageView() self.image_view.new_field.connect(self.on_new_field) self.central_widget.addWidget(self.image_view) self.recognized_view = RecognizedView() self.central_widget.addWidget(self.recognized_view) self.central_widget.setSizes([10000000, 10000000]) self.central_widget.setStretchFactor(0, 1) self.central_widget.setStretchFactor(1, 1) self.menubar = QMenuBar(self) self.setMenuBar(self.menubar) self.file_menu = QMenu("&File", self) self.menubar.addMenu(self.file_menu) self.open_image_action = QAction('&Open image', self) self.file_menu.addAction(self.open_image_action) self.open_image_action.triggered.connect( self.open_image) # type: ignore
def __init__(self, parent=None, img_save_path='../data/images/'): #Set up the style of the main window super(AbsWindow, self).__init__(parent) self.setGeometry(40, 40, 960, 720) self.setWindowTitle(WINDOWTITLE) icon = u"plus_24x24" self.setWindowIcon(QtGui.QIcon("./icon/%s.png" % icon)) self.status_bar = self.statusBar() self.status_bar.showMessage(WELCOME) self.busy_indicator = QtGui.QProgressDialog(labelText=u'计算中,请等待...', minimum=0, maximum=100) #上下结构,上面是imageview,下面是imagecontrolwidget #-abswindow # --spliter # --imageview # --imagecontrolwidget self.main = ImageView(self) self.image_control_widget = ImageControlWidget(parent=self) splitter = QtGui.QSplitter(self) splitter.addWidget(self.main) splitter.addWidget(self.image_control_widget) splitter.setOrientation(Qt.Vertical) self.setCentralWidget(splitter) self.createMenus() #创建菜单 self.setMouseStyleCross() #将鼠标设置成十字的 self.image_file_path = img_save_path #The path to save the image #Initialize attributes self.guidal = GUIDAL() self.svmModel = SVM() self.region_grow_module = RegionGrow() self.reset_attribute() #Initialize
def __init__(self,parent = None,img_save_path = '../data/images/'): #Set up the style of the main window super(AbsWindow, self).__init__(parent) self.setGeometry(40,40,960,720) self.setWindowTitle(WINDOWTITLE) icon = u"plus_24x24" self.setWindowIcon(QtGui.QIcon("./icon/%s.png" % icon)) self.status_bar = self.statusBar() self.status_bar.showMessage(WELCOME) self.busy_indicator = QtGui.QProgressDialog(labelText=u'计算中,请等待...',minimum = 0, maximum = 100) #上下结构,上面是imageview,下面是imagecontrolwidget #-abswindow # --spliter # --imageview # --imagecontrolwidget self.main=ImageView(self) self.image_control_widget = ImageControlWidget(parent=self) splitter = QtGui.QSplitter(self) splitter.addWidget(self.main) splitter.addWidget(self.image_control_widget) splitter.setOrientation(Qt.Vertical) self.setCentralWidget(splitter) self.createMenus()#创建菜单 self.setMouseStyleCross()#将鼠标设置成十字的 self.image_file_path = img_save_path#The path to save the image #Initialize attributes self.guidal = GUIDAL() self.svmModel = SVM() self.region_grow_module = RegionGrow() self.reset_attribute()#Initialize
def __initUI(self): tabwidget = QTabWidget() self.fileViewer = FileListView() #图片列表 self.pointsViewer = PointsListView() #控制点列表 self.fullViewer = FileListView() #全图列表 self.imageViewer = ImageView() #显示图像 tabwidget.addTab(self.fileViewer, '待拼接图列表') tabwidget.addTab(self.pointsViewer, '控制点列表') tabwidget.addTab(self.fullViewer, '全图列表') tabwidget.setTabPosition(QTabWidget.South) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(tabwidget) self.splitter.addWidget(self.imageViewer) #设置初始每个Widget的大小 width = self.width() ratio = [0.2, 0.8] self.splitterSize = [width * ratio[0], width * ratio[1]] self.__setSplitterSize() hbox = QHBoxLayout() hbox.addWidget(self.splitter) self.setLayout(hbox) self.fileViewer.itemDoubleClicked.connect(self.showCurrentImage) self.fullViewer.itemDoubleClicked.connect(self.showFullImage) self.splitter.splitterMoved.connect(self.__getSplitterSize)
def __init__(self, parent=None): #QtGui.QWidget.__init__(self) super(MainWindow, self).__init__(parent) self.setGeometry(40, 40, 880, 660) self.diagonosis = None self.imgNameSuffix = 1 #starts from 001 to 999 self.curImgNo = -1 self.croppedImages = [] #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.splTop=QtGui.QSplitter(Qt.Horizontal,self.splCmd) self.main = ImageView(self) #self.main=ImageView(self.splTop) self.setCentralWidget(self.main) #self.main.setAlignment(Qt.AlignHCenter) #self.splTop.addWidget(self.main) #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.main=ImageView(self.splCmd) #self.main.setAlignment(Qt.AlignHCenter) #self.splCmd.addWidget(self.main) self.createMenus() self.setMouseStyleCross()
def __initUI(self): self.viewerOriginal=ImageView(self) self.viewerEnhance=ImageView(self) self.connect_signal_slot() #控件宽度 width=self.width() height=self.height() ratioMain=[0.5,0.5] sizeMain=[width*ratioMain[0],width*ratioMain[1]] splitter=QSplitter(Qt.Horizontal,self) splitter.addWidget(self.viewerOriginal) splitter.addWidget(self.viewerEnhance) splitter.setSizes(sizeMain) hbox=QHBoxLayout() hbox.addWidget(splitter) self.setLayout(hbox)
def __init__(self,parent = None): #QtGui.QWidget.__init__(self) super(MainWindow, self).__init__(parent) self.setGeometry(40,40,880,660) self.diagonosis = None self.imgNameSuffix = 1#starts from 001 to 999 self.curImgNo = -1 self.croppedImages = [] #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.splTop=QtGui.QSplitter(Qt.Horizontal,self.splCmd) self.main=ImageView(self) #self.main=ImageView(self.splTop) self.setCentralWidget(self.main) #self.main.setAlignment(Qt.AlignHCenter) #self.splTop.addWidget(self.main) #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.main=ImageView(self.splCmd) #self.main.setAlignment(Qt.AlignHCenter) #self.splCmd.addWidget(self.main) self.createMenus() self.setMouseStyleCross()
def showCurrentImage(self, file): if not os.path.exists(file): return self.currentImageFile = file frame = Image.open(file) img = ImageQt.ImageQt(frame).convertToFormat(QImage.Format_RGB888) if type(self.imageViewer) is not ImageView: #删除掉旧控件 viewer = self.splitter.widget(1) # viewer.setParent(self) viewer.deleteLater() #设置当前显示图像的控件 self.imageViewer = ImageView() self.splitter.insertWidget(1, self.imageViewer) self.__setSplitterSize() self.imageViewer.clearImage() self.imageViewer.setImage(img)
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): #QtGui.QWidget.__init__(self) super(MainWindow, self).__init__(parent) self.setGeometry(40, 40, 880, 660) self.diagonosis = None self.imgNameSuffix = 1 #starts from 001 to 999 self.curImgNo = -1 self.croppedImages = [] #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.splTop=QtGui.QSplitter(Qt.Horizontal,self.splCmd) self.main = ImageView(self) #self.main=ImageView(self.splTop) self.setCentralWidget(self.main) #self.main.setAlignment(Qt.AlignHCenter) #self.splTop.addWidget(self.main) #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.main=ImageView(self.splCmd) #self.main.setAlignment(Qt.AlignHCenter) #self.splCmd.addWidget(self.main) self.createMenus() self.setMouseStyleCross() #This is wrong with SVM, comment it temp.. #self.svmModel = SVM() def setMouseStyleCross(self): self.main.setCursor(Qt.CrossCursor) def setMouseStyleNormal(self): self.main.setCursor(Qt.ArrowCursor) def createMenus(self): fileOpenAction = self.createAction(u"打开", self.load, QtGui.QKeySequence.Open, "fileopen", u"打开新的图像文件") cropImageAction = self.createAction(u"&裁剪...", self.crop, tip=u"裁剪图像") svmGuessAction = self.createAction(u"&Magic...", self.curveletExtract, tip=u"分析图像患病概率") shPaInfoDialAction = self.createAction(u"&输入患者信息...", \ self.showPatientInfoDialog,tip = u"输入患者信息") nextImageAction = self.createAction( u"&下一张...", self.nextImage, tip=u"下一张图像", shortcut=QtGui.QKeySequence.MoveToNextChar) lastImageAction = self.createAction( u"&上一张...", self.lastImage, tip=u"上一张图像", shortcut=QtGui.QKeySequence.MoveToPreviousChar) self.fileMenu = self.menuBar().addMenu(u"文件") self.imgMenu = self.menuBar().addMenu(u"图像") self.funcMenu = self.menuBar().addMenu(u"功能") self.fileMenuActions = [fileOpenAction] self.imgMenuActions = [cropImageAction] self.funcMenuActions = [svmGuessAction, shPaInfoDialAction] self.addAction(fileOpenAction) self.addAction(cropImageAction) self.addAction(svmGuessAction) self.addAction(nextImageAction) self.addAction(lastImageAction) self.addAction(shPaInfoDialAction) self.fileMenu.clear() self.imgMenu.clear() self.funcMenu.clear() self.addActions(self.fileMenu, self.fileMenuActions[:]) self.addActions(self.imgMenu, self.imgMenuActions[:]) self.addActions(self.funcMenu, self.funcMenuActions[:]) def addActions(self, target, actions): '''Reload the function''' for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): action = QtGui.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, QtCore.SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action def getImage(self): '''Return displayed image''' i = self.main.getImage() return i def openFile(self, name): '''Open image with given name''' self.main.loadImage(name) #self.setTitle() self.postOp(self.getImage(), False) def postOp(self, i, doUpdate=True): '''Function to call after performing an operation.Redraw the image and handle any errors''' '''i Image that was processed''' '''doUpdate If true, update image on screen. In some operations it may be unnecessary to update, like if the image was not modified, or if the update is done in other way. Default is to update''' self.main.cancelRect( ) #Will ensure that updateMenus() will be called in the process if doUpdate: self.main.update() def reloadImageAfterCrop(self): '''After Crop,set the image to None''' del self.iamgePaths[self.curImgNo] if not self.iamgePaths: if self.main.image: del self.main.image self.main.image = None return else: self.openFile(self.iamgePaths[0]) #Show first image self.curImgNo = 0 def load(self): '''Action 1''' '''Open image without given name''' self.iamgePaths = openFileDialog(self, QString("Open Image"), QString(), self.filters(), QString()) #TEmp if not self.iamgePaths: return self.openFile(self.iamgePaths[0]) #Show first image self.curImgNo = 0 self.imgNamePrefix = "201309011030_001_" def lastImage(self): '''Show the last Image if there is''' if self.curImgNo == -1: return if self.curImgNo - 1 >= 0: self.openFile(self.iamgePaths[self.curImgNo - 1]) self.curImgNo += -1 else: print('There is no more image, first one!') def nextImage(self): '''Show the next Image if there is''' if self.curImgNo == -1: return if self.curImgNo + 1 <= len(self.iamgePaths) - 1: self.openFile(self.iamgePaths[self.curImgNo + 1]) self.curImgNo += 1 else: print('There is no more image, last one!') def filters(self, useGeneric=None, useBareFormat=None): '''Return suggested filters to use in a save/load dialog''' out = QtCore.QStringList() out << "Dicom (*.dcm *.dicom)" out << "PNG (*.png)" out << "BMP (*.bmp)" out << "JPEG (*.jpg *.jpeg)" return out def getImage(self): '''Return displayed image Print out error message if no image is loaded''' i = self.main.getImage() if not i: pass #cmdLine->addError(tr("No image is loaded")); return i #def getImageAndParams(self):#,param): #'''If all parameters are valid for given function, and image is loaded, return image. #Otherwise return NULL and print any error messages to console #param parameters to check''' ##if not self.getParams(param): ##return None ##Get image and return it #i=self.getImage() #return i def save(self): '''Save image under given name Parameter specifies name of image. If name is given in parameter and not with dialog, no questions about overwriting will be asked. If no parameter is specified, dialog is invoked to ask for one''' i = self.getImage() if not i: return fileName = "%s%s%03d.png" % (image_saved_path, self.imgNamePrefix, self.imgNameSuffix) self.imgNameSuffix += 1 self.main.saveImage(ps2qs(fileName)) self.postOp(i, False) #Once saved, append the save img's path into the croppedImages list self.croppedImages.append(fileName) #self.curveletExtract(fileName) #def crop(self,param): def crop(self): #A rectangle is normally expressed as an upper-left corner and a size '''Crop image _QStringList param Command parameters''' i = self.getImage() #param) if not i: print("No image to crop & save") return rectan = self.main.getSelection() if not rectan: print("No selection for this image") return #print(QRect(rectan.left(), rectan.top(), rectan.width(), rectan.height())) i.crop(rectan.left(), rectan.top(), rectan.width(), rectan.height()) self.save() #Save immediately after crop #Flip to next image, without this image,show the user cropped image. self.reloadImageAfterCrop() self.postOp(i) def cleanAfterPredict(self): '''To do:Clean the context''' #cropped Images #curImgNo #imgSavedNumber pass def curveletExtract(self): '''Extract the curvelet from given image name''' if not self.croppedImages: print("No images cropped(selected) yet") return vecList = [] for name in self.croppedImages: XX = misc.imread(name) #If it's a gray image, shape of XX would be 2d ,sth like (73,63) if len(XX.shape) == 2: pass else: XX = XX[:, :, 0] if XX.shape[2] > 1 else XX #if RGB,only tackle R [ MEAN, SD, CT, HG, MP, ENG, INE, IDM, ENT, COR, SM, DM, SE, DE, ANGLES ] = ccf.ccf(XX) results = ccf.ccf(XX) vec = [] for r in results[:-1]: #The last item has 3 cells vec += r vecList.append(vec) self.svmPredict(vecList) self.cleanAfterPredict() def svmPredict(self, vectorList): '''Predict the probability of a feature''' print(self.svmModel.predict(vectorList)) def showPatientInfoDialog(self): #http://stackoverflow.com/questions/5874025/pyqt4-how-to-show-a-modeless-dialog #If you don't pass the self argument,it will be recycled by garbage collector! form = PatientInfoDialog(parent=self) if form.exec_(): self.diagonosis = form.getDiagnosisInfo() #get UI_Diagnosis print(self.diagonosis)
class Window(QMainWindow): def __init__(self, parent: Any = None): super().__init__(parent) self.setWindowTitle('text-from-image') self.central_widget = QSplitter(self) self.setCentralWidget(self.central_widget) self.image_view = ImageView() self.image_view.new_field.connect(self.on_new_field) self.central_widget.addWidget(self.image_view) self.recognized_view = RecognizedView() self.central_widget.addWidget(self.recognized_view) self.central_widget.setSizes([10000000, 10000000]) self.central_widget.setStretchFactor(0, 1) self.central_widget.setStretchFactor(1, 1) self.menubar = QMenuBar(self) self.setMenuBar(self.menubar) self.file_menu = QMenu("&File", self) self.menubar.addMenu(self.file_menu) self.open_image_action = QAction('&Open image', self) self.file_menu.addAction(self.open_image_action) self.open_image_action.triggered.connect( self.open_image) # type: ignore _recognizers: set[Recognizer] = set() def remove_recognizer(self, recognizer: Recognizer): self._recognizers.remove(recognizer) def recognize(self, runtime_field: RuntimeField): thread = QThread(self) recognizer = Recognizer(self.image_path, runtime_field.field.rect) self._recognizers.add(recognizer) recognizer.moveToThread(thread) thread.started.connect(recognizer.run) # type: ignore recognizer.finished.connect(runtime_field.set_recognized) recognizer.finished.connect(thread.quit) recognizer.finished.connect(recognizer.deleteLater) recognizer.destroyed.connect(self.remove_recognizer) # type: ignore thread.finished.connect(thread.deleteLater) # type: ignore thread.start() def on_new_field(self, runtime_field: RuntimeField): self.image_changed.connect(runtime_field.underlying_image_changed) self.recognized_view.add_field(runtime_field) def recognize_in_field(): runtime_field.set_recognized('Recognizing...') self.recognize(runtime_field) connection = self.image_changed.connect(recognize_in_field) runtime_field.destroyed.connect( lambda: self.disconnect(connection)) # type: ignore recognize_in_field() image_changed = pyqtSignal() def open_image(self): path = QFileDialog.getOpenFileName(None, 'Open File', './', 'Image (*.png *.jpg *jpeg)')[0] if path: self.image_path = path self.image_view.open_image(path) self.image_changed.emit()
class AbsWindow(QtGui.QMainWindow): def __init__(self,parent = None,img_save_path = '../data/images/'): #Set up the style of the main window super(AbsWindow, self).__init__(parent) self.setGeometry(40,40,960,720) self.setWindowTitle(WINDOWTITLE) icon = u"plus_24x24" self.setWindowIcon(QtGui.QIcon("./icon/%s.png" % icon)) self.status_bar = self.statusBar() self.status_bar.showMessage(WELCOME) self.busy_indicator = QtGui.QProgressDialog(labelText=u'计算中,请等待...',minimum = 0, maximum = 100) #上下结构,上面是imageview,下面是imagecontrolwidget #-abswindow # --spliter # --imageview # --imagecontrolwidget self.main=ImageView(self) self.image_control_widget = ImageControlWidget(parent=self) splitter = QtGui.QSplitter(self) splitter.addWidget(self.main) splitter.addWidget(self.image_control_widget) splitter.setOrientation(Qt.Vertical) self.setCentralWidget(splitter) self.createMenus()#创建菜单 self.setMouseStyleCross()#将鼠标设置成十字的 self.image_file_path = img_save_path#The path to save the image #Initialize attributes self.guidal = GUIDAL() self.svmModel = SVM() self.region_grow_module = RegionGrow() self.reset_attribute()#Initialize def reset_attribute(self): self.image_item_list = ImageItemsList()#Hold all the images self.diagonosis_info = None#The info (patients info ,images,predictions) self.imgNameSuffix = 1#names of image starts from 001 to 999 #self.reload_cur_image() def setMouseStyleCross(self): '''Set the mouse style to cross +''' self.main.setCursor(Qt.CrossCursor) def setMouseStyleNormal(self): '''Set the mouse style to normal''' self.main.setCursor(Qt.ArrowCursor) #def createToolBar(self): #exit = QtGui.QAction(QtGui.QIcon('icons/web.png'), 'Exit', self) def createMenus(self): '''Initialize and create menus,actions,toolbar''' fileOpenAction = self.createAction(u"导入图像", self.load, QtGui.QKeySequence.Open, "document_stroke_24x24", u"导入图像文件") cropImageAction = self.createAction(u"&裁剪...", self.crop,icon="fullscreen_alt_24x24",tip = u"裁剪图像") svmGuessAction = self.createAction(u"预测", self.curveletExtract,tip = u"分析图像患病概率", icon="check_alt_24x24") shPaInfoDialAction = self.createAction(u"输入患者信息...", \ self.showPatientInfoDialog,tip = u"输入患者信息", icon="user_18x24") selectDiagonosisAction = self.createAction(u"查询诊断信息...", \ self.show_select_diagonosis_dialog,tip = u"查询诊断信息", icon="magnifying_glass_alt_24x24") nextImageAction = self.createAction(u"&下一张...", self.nextImage,tip = u"下一张图像", shortcut=QtGui.QKeySequence.MoveToNextChar, icon="arrow_right_24x24") previousImageAction = self.createAction(u"&上一张...", self.previousImage,tip = u"上一张图像", shortcut=QtGui.QKeySequence.MoveToPreviousChar, icon = "arrow_left_24x24") resetImageAction = self.createAction(u"重置图像...", self.reset_current_image,tip = u"重置图像", icon = "reload_24x28") self.toolbar = self.addToolBar("Tools") self.toolbar.addAction(fileOpenAction) self.toolbar.addAction(shPaInfoDialAction) self.toolbar.addAction(selectDiagonosisAction) self.toolbar.addSeparator() self.toolbar.addAction(previousImageAction) self.toolbar.addAction(nextImageAction) self.toolbar.addAction(cropImageAction) self.toolbar.addAction(resetImageAction) self.toolbar.addSeparator() self.toolbar.addAction(svmGuessAction) self.fileMenu = self.menuBar().addMenu(u"文件") self.imgMenu = self.menuBar().addMenu(u"图像") self.funcMenu = self.menuBar().addMenu(u"功能") self.fileMenuActions = [fileOpenAction,shPaInfoDialAction,selectDiagonosisAction] self.imgMenuActions = [previousImageAction,nextImageAction,cropImageAction,resetImageAction] self.funcMenuActions = [svmGuessAction] self.addAction(fileOpenAction) self.addAction(cropImageAction) self.addAction(svmGuessAction) self.addAction(nextImageAction) self.addAction(previousImageAction) self.addAction(shPaInfoDialAction) self.addAction(selectDiagonosisAction) self.addAction(resetImageAction) self.fileMenu.clear() self.imgMenu.clear() self.funcMenu.clear() self.addActions(self.fileMenu, self.fileMenuActions[:]) self.addActions(self.imgMenu, self.imgMenuActions[:]) self.addActions(self.funcMenu, self.funcMenuActions[:]) def addActions(self, target, actions): '''Reload the function''' for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def createAction(self, text, slot=None, shortcut=None, icon=None,tip=None, checkable=False, signal="triggered()"): '''A helper function to create an GUI action''' action = QtGui.QAction(text, self) if icon is not None: action.setIcon(QtGui.QIcon("./icon/%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, QtCore.SIGNAL(signal), slot) if checkable: action.setCheckable(True) #if icon: #action.setIcon(icon) return action def getImage(self): '''Return displayed image''' i = self.main.getImage() return i def openFile(self,name): '''Open image with given name''' if not self.main.loadImage(name): print("[Abswindow]:Image null %s "% name) return #self.setTitle() self.postOp(self.getImage(),False) def postOp(self,i,doUpdate= True): '''Function to call after performing an operation.Redraw the image and handle any errors''' '''i Image that was processed''' '''doUpdate If true, update image on screen. In some operations it may be unnecessary to update, like if the image was not modified, or if the update is done in other way. Default is to update''' self.main.cancelRect()#Will ensure that updateMenus() will be called in the process if doUpdate:self.main.update() self.update_image_control_state() #def reloadImageAfterCrop(self): #'''After Crop,set the image to None''' #del self.images_tuple[self.curImgNo][0] #if not self.iamgePaths: #if self.main.image: del self.main.image #self.main.image = None #return #else: #self.openFile(self.images_tuple[0][0])#Show first image #self.curImgNo = 0 def reload_cur_image(self): ''' Reload the image.Ask for which image to show and open that image. call this in crop,region grow and reset ''' file_path = self.image_item_list.get_current_image_file() if file_path: self.openFile(file_path)#Show first image def load(self): '''Action 1''' '''Open image without given name''' img_paths = openFileDialog(self,QString(u"打开图片"),QString(),self.filters(),QString())#TEmp if not img_paths: return self.image_item_list.init_list(img_paths) file_path = self.image_item_list.get_current_image_file() if file_path: self.openFile(file_path)#Show first image self.imgNamePrefix = qs2ps(QtCore.QDateTime.currentDateTime().toString("yyMMdd_hhmmss")) #PyQt4.QtCore.QString(u'131029_143236') def previousImage(self): '''Show the last Image if there is''' prev_image_file_path = self.image_item_list.get_prev_image_file_name() if prev_image_file_path: self.openFile(prev_image_file_path) else: print('No previous image!') self.status_bar.showMessage(u"没有上一张图像",5000) def nextImage(self): '''Show the next Image if there is''' next_image_file_path = self.image_item_list.get_next_image_file_name() if next_image_file_path: self.openFile(next_image_file_path) else: print('No next image!') self.status_bar.showMessage(u"没有下一张图像",5000) def filters(self,useGeneric = None,useBareFormat=None): '''Return suggested filters to use in a save/load dialog''' out = QtCore.QStringList() out << "Dicom (*.dcm *.dicom)" out << "PNG (*.png)" out << "BMP (*.bmp)" out << "JPEG (*.jpg *.jpeg)" return out def getImage(self): '''Return displayed image Print out error message if no image is loaded''' i=self.main.getImage() if not i: pass #cmdLine->addError(tr("No image is loaded")); return i def change_image_in_use_state(self,able): self.image_item_list.do_enable_current_image(able) def update_image_control_state(self): able = self.image_item_list.is_current_image_in_use() self.image_control_widget.set_in_use_checked(able) def save_after_regiongrow(self,img): '''Save image after regiongrow.''' i=self.getImage() if not i: return _pfileName="%s%s%03d_croped_regiongrowed.png" % (self.image_file_path,self.imgNamePrefix,self.imgNameSuffix) fileName = ps2qs(_pfileName) self.imgNameSuffix+=1 #self.main.saveImage(fileName) misc.imsave(_pfileName,img) self.image_item_list.do_current_image_regiongrow(fileName)#set the cropped image's name to the image_item_list self.reload_cur_image() self.postOp(i,False) def save_after_crop(self): '''Save image after cropped.''' i=self.getImage() if not i: return _pfileName="%s%s%03d_cropped.png" % (self.image_file_path,self.imgNamePrefix,self.imgNameSuffix) fileName = ps2qs(_pfileName) self.imgNameSuffix+=1 if not self.main.saveImage(fileName): _showed_message =u"[保存失败]%s 文件" % (_pfileName) self.status_bar.showMessage(_showed_message,5000) return False self.postOp(i,False) self.image_item_list.do_current_image_crop(fileName)#set the cropped image's name to the image_item_list _showed_message =u"裁剪成功,保存到 %s 文件" % (_pfileName) self.status_bar.showMessage(_showed_message,5000) return True def crop(self): #A rectangle is normally expressed as an upper-left corner and a size '''Crop image _QStringList param Command parameters''' i=self.getImage()#param) if not i: print("No image to crop & save") self.status_bar.showMessage(u"当前没有图像,不能进行裁剪操作",5000) return rectan = self.main.getSelection() if not rectan: print("No selection for this image") self.status_bar.showMessage(u"没有选择矩形区域,不能进行裁剪操作",5000) return #print(QRect(rectan.left(), rectan.top(), rectan.width(), rectan.height())) i.crop(rectan.left(), rectan.top(), rectan.width(), rectan.height()) if not self.save_after_crop():#Save immediately after crop return #not filp to next image #self.reloadImageAfterCrop() self.reload_cur_image() self.postOp(i) self.status_bar.showMessage(u"按住alt键,选择种子点,对图像进行区域生长算法") def cleanAfterPredict(self): '''To do:Clean the context''' #cropped Images #curImgNo #imgSavedNumber pass def region_grow(self,point): '''Doctor push the region grow button''' i=self.getImage() if not i: print("No image to region_grow") self.status_bar.showMessage(u"没有图像来进行区域生长") return _threshold = self.image_control_widget.get_threshold_value()#Get the current user setting of the threshold self.show_busy_indicator_progress()#---------------------Start- Compute--------------------------- _qcur_img_file = self.image_item_list.get_current_image_file() cur_img_file = qs2ps(_qcur_img_file) img = misc.imread(cur_img_file) if not len(img.shape) == 2: img= img[:,:,0] if img.shape[2] > 1 else img print "[Region Grow]\n[Image]%s\n[Shape]:%r\n[Pos]:%r:" % (_qcur_img_file,img.shape,point) img = self.region_grow_module.getRegionGrowImage(img,(point.x(),point.y()),_threshold) self.save_after_regiongrow(img) self.cancel_busy_indicator_progress()#-------------------ENd---Compute--------------------------- def curveletExtract(self): '''Extract the curvelet from given image name''' all_image_paths = self.image_item_list.get_all_enable_images_path() if not all_image_paths: print("No images to extract curvelet features") self.status_bar.showMessage(u"没有图像来进行预测") return if not self.diagonosis_info: print("No Info to extract curvelet features") self.status_bar.showMessage(u"没有输入患者信息来进行预测") return image_features_dic = {}#{'../data/images/131102_110830004_croped_regiongrowed.png':[6.9639934,2,23]} for _qname in all_image_paths: name = qs2ps(_qname) #name = qs2ps(_qname) XX = misc.imread(name) #If it's a gray image, shape of XX would be 2d ,sth like (73,63) if len(XX.shape) == 2: pass else: XX= XX[:,:,0] if XX.shape[2] > 1 else XX#if RGB,only tackle R [MEAN,SD,CT,HG,MP,ENG,INE,IDM,ENT,COR,SM,DM,SE,DE,ANGLES] = ccf.ccf(XX) results = ccf.ccf(XX) vec = [] for r in results[:-1]:#The last item has 3 cells vec+= r print(vec) image_features_dic[name] = vec self.svmPredict(image_features_dic) def svmPredict(self,image_features_dic): '''Predict the probability of a feature''' patient_info_feature_list = self.diagonosis_info.convert_to_predictDiagnosis().convert_to_list() (p_with,p_without) = self.svmModel.predict(patient_info_feature_list,image_features_dic) #p_with,p_without = 1,0 self.diagonosis_info.set_probability(str(p_with),str(p_without))#set the probability attribute patien_info_dic = self.diagonosis_info.convert_to_dict() self.show_result_dialog_and_savetodatavase(p_with,p_without,patien_info_dic,patient_info_feature_list,image_features_dic) def show_result_dialog_and_savetodatavase(self,p_with,p_without,patien_info_dic,patient_info_feature_list,image_features_dic): '''Show the prediction result,with buttons the confirm the result''' form = ShowResultDialog(parent=self,predict_value1=p_with,predict_value2=p_without) if form.exec_(): #If doctor confirms the diagnosis,add new test cases and save .else, just save label = -1 add_to_traning = False sure_value = form.get_sure_value() if sure_value == 1:#Yes,youbing label = 1 add_to_traning = True elif sure_value == 2:#No,meibing label = 0 add_to_traning = True #save it into database try: self.guidal.save_diagnosis_record(patien_info_dic, patient_info_feature_list, image_features_dic, (p_with,p_without), label, add_to_traning) except Exception as e: print "Database save error %s" % e traceback.print_exc() self.cleanAfterPredict() def showPatientInfoDialog(self): #http://stackoverflow.com/questions/5874025/pyqt4-how-to-show-a-modeless-dialog #If you don't pass the self argument,it will be recycled by garbage collector! '''Show the disgnosis input window and let the doctor to type in infos''' form = PatientInfoDialog(parent=self) if form.exec_(): self.diagonosis_info = form.getDiagnosisInfo() print(self.diagonosis_info) def show_select_diagonosis_dialog(self): '''Just for test''' all_diagnosis = self.guidal.get_all_diagnosis_info()# [[id,张三,13-02-01,98%,100%],[],[]] form = DiagnosisListDlg( u"过往诊断", all_diagnosis) if form.exec_(): pass #print "\n".join([unicode(x) for x in form.stringlist]) def show_patientinfo_readonly_dialog(self,diagnosis_to_show): '''Create and show readonly diagnosis info Dialog window''' form = PatientInfoReadOnlyDialog(diagnosis_to_show) if form.exec_(): print("finish showing the read only diagnosis") def show_busy_indicator_progress(self): '''Show the loading window''' self.busy_indicator.reset() self.busy_indicator.show() for i in range(30): self.busy_indicator.setValue(i) time.sleep(0.02) def cancel_busy_indicator_progress(self): '''Close the loading... window''' for i in range(70,100): self.busy_indicator.setValue(i) time.sleep(0.05) self.busy_indicator.cancel() def reset_current_image(self): ''' Reset the image,change the cropped or region growed image to the original image. ''' i=self.getImage()#param) if not i: print("No image reset") self.status_bar.showMessage(u"当前没有图像,无需重置",5000) return self.image_item_list.do_reset_current_image()#set the current image to original one. self.reload_cur_image() self.postOp(None,False)
class AbsWindow(QtGui.QMainWindow): def __init__(self, parent=None, img_save_path='../data/images/'): #Set up the style of the main window super(AbsWindow, self).__init__(parent) self.setGeometry(40, 40, 960, 720) self.setWindowTitle(WINDOWTITLE) icon = u"plus_24x24" self.setWindowIcon(QtGui.QIcon("./icon/%s.png" % icon)) self.status_bar = self.statusBar() self.status_bar.showMessage(WELCOME) self.busy_indicator = QtGui.QProgressDialog(labelText=u'计算中,请等待...', minimum=0, maximum=100) #上下结构,上面是imageview,下面是imagecontrolwidget #-abswindow # --spliter # --imageview # --imagecontrolwidget self.main = ImageView(self) self.image_control_widget = ImageControlWidget(parent=self) splitter = QtGui.QSplitter(self) splitter.addWidget(self.main) splitter.addWidget(self.image_control_widget) splitter.setOrientation(Qt.Vertical) self.setCentralWidget(splitter) self.createMenus() #创建菜单 self.setMouseStyleCross() #将鼠标设置成十字的 self.image_file_path = img_save_path #The path to save the image #Initialize attributes self.guidal = GUIDAL() self.svmModel = SVM() self.region_grow_module = RegionGrow() self.reset_attribute() #Initialize def reset_attribute(self): self.image_item_list = ImageItemsList() #Hold all the images self.diagonosis_info = None #The info (patients info ,images,predictions) self.imgNameSuffix = 1 #names of image starts from 001 to 999 #self.reload_cur_image() def setMouseStyleCross(self): '''Set the mouse style to cross +''' self.main.setCursor(Qt.CrossCursor) def setMouseStyleNormal(self): '''Set the mouse style to normal''' self.main.setCursor(Qt.ArrowCursor) #def createToolBar(self): #exit = QtGui.QAction(QtGui.QIcon('icons/web.png'), 'Exit', self) def createMenus(self): '''Initialize and create menus,actions,toolbar''' fileOpenAction = self.createAction(u"导入图像", self.load, QtGui.QKeySequence.Open, "document_stroke_24x24", u"导入图像文件") cropImageAction = self.createAction(u"&裁剪...", self.crop, icon="fullscreen_alt_24x24", tip=u"裁剪图像") svmGuessAction = self.createAction(u"预测", self.curveletExtract, tip=u"分析图像患病概率", icon="check_alt_24x24") shPaInfoDialAction = self.createAction(u"输入患者信息...", \ self.showPatientInfoDialog,tip = u"输入患者信息", icon="user_18x24") selectDiagonosisAction = self.createAction(u"查询诊断信息...", \ self.show_select_diagonosis_dialog,tip = u"查询诊断信息", icon="magnifying_glass_alt_24x24") nextImageAction = self.createAction( u"&下一张...", self.nextImage, tip=u"下一张图像", shortcut=QtGui.QKeySequence.MoveToNextChar, icon="arrow_right_24x24") previousImageAction = self.createAction( u"&上一张...", self.previousImage, tip=u"上一张图像", shortcut=QtGui.QKeySequence.MoveToPreviousChar, icon="arrow_left_24x24") resetImageAction = self.createAction(u"重置图像...", self.reset_current_image, tip=u"重置图像", icon="reload_24x28") self.toolbar = self.addToolBar("Tools") self.toolbar.addAction(fileOpenAction) self.toolbar.addAction(shPaInfoDialAction) self.toolbar.addAction(selectDiagonosisAction) self.toolbar.addSeparator() self.toolbar.addAction(previousImageAction) self.toolbar.addAction(nextImageAction) self.toolbar.addAction(cropImageAction) self.toolbar.addAction(resetImageAction) self.toolbar.addSeparator() self.toolbar.addAction(svmGuessAction) self.fileMenu = self.menuBar().addMenu(u"文件") self.imgMenu = self.menuBar().addMenu(u"图像") self.funcMenu = self.menuBar().addMenu(u"功能") self.fileMenuActions = [ fileOpenAction, shPaInfoDialAction, selectDiagonosisAction ] self.imgMenuActions = [ previousImageAction, nextImageAction, cropImageAction, resetImageAction ] self.funcMenuActions = [svmGuessAction] self.addAction(fileOpenAction) self.addAction(cropImageAction) self.addAction(svmGuessAction) self.addAction(nextImageAction) self.addAction(previousImageAction) self.addAction(shPaInfoDialAction) self.addAction(selectDiagonosisAction) self.addAction(resetImageAction) self.fileMenu.clear() self.imgMenu.clear() self.funcMenu.clear() self.addActions(self.fileMenu, self.fileMenuActions[:]) self.addActions(self.imgMenu, self.imgMenuActions[:]) self.addActions(self.funcMenu, self.funcMenuActions[:]) def addActions(self, target, actions): '''Reload the function''' for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"): '''A helper function to create an GUI action''' action = QtGui.QAction(text, self) if icon is not None: action.setIcon(QtGui.QIcon("./icon/%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, QtCore.SIGNAL(signal), slot) if checkable: action.setCheckable(True) #if icon: #action.setIcon(icon) return action def getImage(self): '''Return displayed image''' i = self.main.getImage() return i def openFile(self, name): '''Open image with given name''' if not self.main.loadImage(name): print("[Abswindow]:Image null %s " % name) return #self.setTitle() self.postOp(self.getImage(), False) def postOp(self, i, doUpdate=True): '''Function to call after performing an operation.Redraw the image and handle any errors''' '''i Image that was processed''' '''doUpdate If true, update image on screen. In some operations it may be unnecessary to update, like if the image was not modified, or if the update is done in other way. Default is to update''' self.main.cancelRect( ) #Will ensure that updateMenus() will be called in the process if doUpdate: self.main.update() self.update_image_control_state() #def reloadImageAfterCrop(self): #'''After Crop,set the image to None''' #del self.images_tuple[self.curImgNo][0] #if not self.iamgePaths: #if self.main.image: del self.main.image #self.main.image = None #return #else: #self.openFile(self.images_tuple[0][0])#Show first image #self.curImgNo = 0 def reload_cur_image(self): ''' Reload the image.Ask for which image to show and open that image. call this in crop,region grow and reset ''' file_path = self.image_item_list.get_current_image_file() if file_path: self.openFile(file_path) #Show first image def load(self): '''Action 1''' '''Open image without given name''' img_paths = openFileDialog(self, QString(u"打开图片"), QString(), self.filters(), QString()) #TEmp if not img_paths: return self.image_item_list.init_list(img_paths) file_path = self.image_item_list.get_current_image_file() if file_path: self.openFile(file_path) #Show first image self.imgNamePrefix = qs2ps( QtCore.QDateTime.currentDateTime().toString("yyMMdd_hhmmss")) #PyQt4.QtCore.QString(u'131029_143236') def previousImage(self): '''Show the last Image if there is''' prev_image_file_path = self.image_item_list.get_prev_image_file_name() if prev_image_file_path: self.openFile(prev_image_file_path) else: print('No previous image!') self.status_bar.showMessage(u"没有上一张图像", 5000) def nextImage(self): '''Show the next Image if there is''' next_image_file_path = self.image_item_list.get_next_image_file_name() if next_image_file_path: self.openFile(next_image_file_path) else: print('No next image!') self.status_bar.showMessage(u"没有下一张图像", 5000) def filters(self, useGeneric=None, useBareFormat=None): '''Return suggested filters to use in a save/load dialog''' out = QtCore.QStringList() out << "Dicom (*.dcm *.dicom)" out << "PNG (*.png)" out << "BMP (*.bmp)" out << "JPEG (*.jpg *.jpeg)" return out def getImage(self): '''Return displayed image Print out error message if no image is loaded''' i = self.main.getImage() if not i: pass #cmdLine->addError(tr("No image is loaded")); return i def change_image_in_use_state(self, able): self.image_item_list.do_enable_current_image(able) def update_image_control_state(self): able = self.image_item_list.is_current_image_in_use() self.image_control_widget.set_in_use_checked(able) def save_after_regiongrow(self, img): '''Save image after regiongrow.''' i = self.getImage() if not i: return _pfileName = "%s%s%03d_croped_regiongrowed.png" % ( self.image_file_path, self.imgNamePrefix, self.imgNameSuffix) fileName = ps2qs(_pfileName) self.imgNameSuffix += 1 #self.main.saveImage(fileName) misc.imsave(_pfileName, img) self.image_item_list.do_current_image_regiongrow( fileName) #set the cropped image's name to the image_item_list self.reload_cur_image() self.postOp(i, False) def save_after_crop(self): '''Save image after cropped.''' i = self.getImage() if not i: return _pfileName = "%s%s%03d_cropped.png" % ( self.image_file_path, self.imgNamePrefix, self.imgNameSuffix) fileName = ps2qs(_pfileName) self.imgNameSuffix += 1 if not self.main.saveImage(fileName): _showed_message = u"[保存失败]%s 文件" % (_pfileName) self.status_bar.showMessage(_showed_message, 5000) return False self.postOp(i, False) self.image_item_list.do_current_image_crop( fileName) #set the cropped image's name to the image_item_list _showed_message = u"裁剪成功,保存到 %s 文件" % (_pfileName) self.status_bar.showMessage(_showed_message, 5000) return True def crop(self): #A rectangle is normally expressed as an upper-left corner and a size '''Crop image _QStringList param Command parameters''' i = self.getImage() #param) if not i: print("No image to crop & save") self.status_bar.showMessage(u"当前没有图像,不能进行裁剪操作", 5000) return rectan = self.main.getSelection() if not rectan: print("No selection for this image") self.status_bar.showMessage(u"没有选择矩形区域,不能进行裁剪操作", 5000) return #print(QRect(rectan.left(), rectan.top(), rectan.width(), rectan.height())) i.crop(rectan.left(), rectan.top(), rectan.width(), rectan.height()) if not self.save_after_crop(): #Save immediately after crop return #not filp to next image #self.reloadImageAfterCrop() self.reload_cur_image() self.postOp(i) self.status_bar.showMessage(u"按住alt键,选择种子点,对图像进行区域生长算法") def cleanAfterPredict(self): '''To do:Clean the context''' #cropped Images #curImgNo #imgSavedNumber pass def region_grow(self, point): '''Doctor push the region grow button''' i = self.getImage() if not i: print("No image to region_grow") self.status_bar.showMessage(u"没有图像来进行区域生长") return _threshold = self.image_control_widget.get_threshold_value( ) #Get the current user setting of the threshold self.show_busy_indicator_progress( ) #---------------------Start- Compute--------------------------- _qcur_img_file = self.image_item_list.get_current_image_file() cur_img_file = qs2ps(_qcur_img_file) img = misc.imread(cur_img_file) if not len(img.shape) == 2: img = img[:, :, 0] if img.shape[2] > 1 else img print "[Region Grow]\n[Image]%s\n[Shape]:%r\n[Pos]:%r:" % ( _qcur_img_file, img.shape, point) img = self.region_grow_module.getRegionGrowImage( img, (point.x(), point.y()), _threshold) self.save_after_regiongrow(img) self.cancel_busy_indicator_progress( ) #-------------------ENd---Compute--------------------------- def curveletExtract(self): '''Extract the curvelet from given image name''' all_image_paths = self.image_item_list.get_all_enable_images_path() if not all_image_paths: print("No images to extract curvelet features") self.status_bar.showMessage(u"没有图像来进行预测") return if not self.diagonosis_info: print("No Info to extract curvelet features") self.status_bar.showMessage(u"没有输入患者信息来进行预测") return image_features_dic = { } #{'../data/images/131102_110830004_croped_regiongrowed.png':[6.9639934,2,23]} for _qname in all_image_paths: name = qs2ps(_qname) #name = qs2ps(_qname) XX = misc.imread(name) #If it's a gray image, shape of XX would be 2d ,sth like (73,63) if len(XX.shape) == 2: pass else: XX = XX[:, :, 0] if XX.shape[2] > 1 else XX #if RGB,only tackle R [ MEAN, SD, CT, HG, MP, ENG, INE, IDM, ENT, COR, SM, DM, SE, DE, ANGLES ] = ccf.ccf(XX) results = ccf.ccf(XX) vec = [] for r in results[:-1]: #The last item has 3 cells vec += r print(vec) image_features_dic[name] = vec self.svmPredict(image_features_dic) def svmPredict(self, image_features_dic): '''Predict the probability of a feature''' patient_info_feature_list = self.diagonosis_info.convert_to_predictDiagnosis( ).convert_to_list() (p_with, p_without) = self.svmModel.predict(patient_info_feature_list, image_features_dic) #p_with,p_without = 1,0 self.diagonosis_info.set_probability( str(p_with), str(p_without)) #set the probability attribute patien_info_dic = self.diagonosis_info.convert_to_dict() self.show_result_dialog_and_savetodatavase(p_with, p_without, patien_info_dic, patient_info_feature_list, image_features_dic) def show_result_dialog_and_savetodatavase(self, p_with, p_without, patien_info_dic, patient_info_feature_list, image_features_dic): '''Show the prediction result,with buttons the confirm the result''' form = ShowResultDialog(parent=self, predict_value1=p_with, predict_value2=p_without) if form.exec_(): #If doctor confirms the diagnosis,add new test cases and save .else, just save label = -1 add_to_traning = False sure_value = form.get_sure_value() if sure_value == 1: #Yes,youbing label = 1 add_to_traning = True elif sure_value == 2: #No,meibing label = 0 add_to_traning = True #save it into database try: self.guidal.save_diagnosis_record(patien_info_dic, patient_info_feature_list, image_features_dic, (p_with, p_without), label, add_to_traning) except Exception as e: print "Database save error %s" % e traceback.print_exc() self.cleanAfterPredict() def showPatientInfoDialog(self): #http://stackoverflow.com/questions/5874025/pyqt4-how-to-show-a-modeless-dialog #If you don't pass the self argument,it will be recycled by garbage collector! '''Show the disgnosis input window and let the doctor to type in infos''' form = PatientInfoDialog(parent=self) if form.exec_(): self.diagonosis_info = form.getDiagnosisInfo() print(self.diagonosis_info) def show_select_diagonosis_dialog(self): '''Just for test''' all_diagnosis = self.guidal.get_all_diagnosis_info( ) # [[id,张三,13-02-01,98%,100%],[],[]] form = DiagnosisListDlg(u"过往诊断", all_diagnosis) if form.exec_(): pass #print "\n".join([unicode(x) for x in form.stringlist]) def show_patientinfo_readonly_dialog(self, diagnosis_to_show): '''Create and show readonly diagnosis info Dialog window''' form = PatientInfoReadOnlyDialog(diagnosis_to_show) if form.exec_(): print("finish showing the read only diagnosis") def show_busy_indicator_progress(self): '''Show the loading window''' self.busy_indicator.reset() self.busy_indicator.show() for i in range(30): self.busy_indicator.setValue(i) time.sleep(0.02) def cancel_busy_indicator_progress(self): '''Close the loading... window''' for i in range(70, 100): self.busy_indicator.setValue(i) time.sleep(0.05) self.busy_indicator.cancel() def reset_current_image(self): ''' Reset the image,change the cropped or region growed image to the original image. ''' i = self.getImage() #param) if not i: print("No image reset") self.status_bar.showMessage(u"当前没有图像,无需重置", 5000) return self.image_item_list.do_reset_current_image( ) #set the current image to original one. self.reload_cur_image() self.postOp(None, False)
class MainWindow(QtGui.QMainWindow): def __init__(self,parent = None): #QtGui.QWidget.__init__(self) super(MainWindow, self).__init__(parent) self.setGeometry(40,40,880,660) self.diagonosis = None self.imgNameSuffix = 1#starts from 001 to 999 self.curImgNo = -1 self.croppedImages = [] #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.splTop=QtGui.QSplitter(Qt.Horizontal,self.splCmd) self.main=ImageView(self) #self.main=ImageView(self.splTop) self.setCentralWidget(self.main) #self.main.setAlignment(Qt.AlignHCenter) #self.splTop.addWidget(self.main) #self.splCmd=QtGui.QSplitter(Qt.Vertical,self) #self.main=ImageView(self.splCmd) #self.main.setAlignment(Qt.AlignHCenter) #self.splCmd.addWidget(self.main) self.createMenus() self.setMouseStyleCross() #This is wrong with SVM, comment it temp.. #self.svmModel = SVM() def setMouseStyleCross(self): self.main.setCursor(Qt.CrossCursor) def setMouseStyleNormal(self): self.main.setCursor(Qt.ArrowCursor) def createMenus(self): fileOpenAction = self.createAction(u"打开", self.load, QtGui.QKeySequence.Open, "fileopen", u"打开新的图像文件") cropImageAction = self.createAction(u"&裁剪...", self.crop,tip = u"裁剪图像") svmGuessAction = self.createAction(u"&Magic...", self.curveletExtract,tip = u"分析图像患病概率") shPaInfoDialAction = self.createAction(u"&输入患者信息...", \ self.showPatientInfoDialog,tip = u"输入患者信息") nextImageAction = self.createAction(u"&下一张...", self.nextImage,tip = u"下一张图像", shortcut=QtGui.QKeySequence.MoveToNextChar) lastImageAction = self.createAction(u"&上一张...", self.lastImage,tip = u"上一张图像", shortcut=QtGui.QKeySequence.MoveToPreviousChar) self.fileMenu = self.menuBar().addMenu(u"文件") self.imgMenu = self.menuBar().addMenu(u"图像") self.funcMenu = self.menuBar().addMenu(u"功能") self.fileMenuActions = [fileOpenAction] self.imgMenuActions = [cropImageAction] self.funcMenuActions = [svmGuessAction,shPaInfoDialAction] self.addAction(fileOpenAction) self.addAction(cropImageAction) self.addAction(svmGuessAction) self.addAction(nextImageAction) self.addAction(lastImageAction) self.addAction(shPaInfoDialAction) self.fileMenu.clear() self.imgMenu.clear() self.funcMenu.clear() self.addActions(self.fileMenu, self.fileMenuActions[:]) self.addActions(self.imgMenu, self.imgMenuActions[:]) self.addActions(self.funcMenu, self.funcMenuActions[:]) def addActions(self, target, actions): '''Reload the function''' for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def createAction(self, text, slot=None, shortcut=None, icon=None,tip=None, checkable=False, signal="triggered()"): action = QtGui.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, QtCore.SIGNAL(signal), slot) if checkable: action.setCheckable(True) return action def getImage(self): '''Return displayed image''' i = self.main.getImage() return i def openFile(self,name): '''Open image with given name''' self.main.loadImage(name) #self.setTitle() self.postOp(self.getImage(),False) def postOp(self,i,doUpdate= True): '''Function to call after performing an operation.Redraw the image and handle any errors''' '''i Image that was processed''' '''doUpdate If true, update image on screen. In some operations it may be unnecessary to update, like if the image was not modified, or if the update is done in other way. Default is to update''' self.main.cancelRect()#Will ensure that updateMenus() will be called in the process if doUpdate:self.main.update() def reloadImageAfterCrop(self): '''After Crop,set the image to None''' del self.iamgePaths[self.curImgNo] if not self.iamgePaths: if self.main.image: del self.main.image self.main.image = None return else: self.openFile(self.iamgePaths[0])#Show first image self.curImgNo = 0 def load(self): '''Action 1''' '''Open image without given name''' self.iamgePaths = openFileDialog(self,QString("Open Image"),QString(),self.filters(),QString())#TEmp if not self.iamgePaths:return self.openFile(self.iamgePaths[0])#Show first image self.curImgNo = 0 self.imgNamePrefix = "201309011030_001_" def lastImage(self): '''Show the last Image if there is''' if self.curImgNo == -1:return if self.curImgNo - 1 >= 0: self.openFile(self.iamgePaths[self.curImgNo-1]) self.curImgNo += -1 else: print('There is no more image, first one!') def nextImage(self): '''Show the next Image if there is''' if self.curImgNo == -1:return if self.curImgNo+1 <= len(self.iamgePaths) - 1: self.openFile(self.iamgePaths[self.curImgNo+1]) self.curImgNo += 1 else: print('There is no more image, last one!') def filters(self,useGeneric = None,useBareFormat=None): '''Return suggested filters to use in a save/load dialog''' out = QtCore.QStringList() out << "Dicom (*.dcm *.dicom)" out << "PNG (*.png)" out << "BMP (*.bmp)" out << "JPEG (*.jpg *.jpeg)" return out def getImage(self): '''Return displayed image Print out error message if no image is loaded''' i=self.main.getImage() if not i: pass #cmdLine->addError(tr("No image is loaded")); return i #def getImageAndParams(self):#,param): #'''If all parameters are valid for given function, and image is loaded, return image. #Otherwise return NULL and print any error messages to console #param parameters to check''' ##if not self.getParams(param): ##return None ##Get image and return it #i=self.getImage() #return i def save(self): '''Save image under given name Parameter specifies name of image. If name is given in parameter and not with dialog, no questions about overwriting will be asked. If no parameter is specified, dialog is invoked to ask for one''' i=self.getImage() if not i: return fileName="%s%s%03d.png" % (image_saved_path,self.imgNamePrefix,self.imgNameSuffix) self.imgNameSuffix+=1 self.main.saveImage(ps2qs(fileName)) self.postOp(i,False) #Once saved, append the save img's path into the croppedImages list self.croppedImages.append(fileName) #self.curveletExtract(fileName) #def crop(self,param): def crop(self): #A rectangle is normally expressed as an upper-left corner and a size '''Crop image _QStringList param Command parameters''' i=self.getImage()#param) if not i: print("No image to crop & save") return rectan = self.main.getSelection() if not rectan: print("No selection for this image") return #print(QRect(rectan.left(), rectan.top(), rectan.width(), rectan.height())) i.crop(rectan.left(), rectan.top(), rectan.width(), rectan.height()) self.save()#Save immediately after crop #Flip to next image, without this image,show the user cropped image. self.reloadImageAfterCrop() self.postOp(i) def cleanAfterPredict(self): '''To do:Clean the context''' #cropped Images #curImgNo #imgSavedNumber pass def curveletExtract(self): '''Extract the curvelet from given image name''' if not self.croppedImages: print("No images cropped(selected) yet") return vecList = [] for name in self.croppedImages: XX = misc.imread(name) #If it's a gray image, shape of XX would be 2d ,sth like (73,63) if len(XX.shape) == 2: pass else: XX= XX[:,:,0] if XX.shape[2] > 1 else XX#if RGB,only tackle R [MEAN,SD,CT,HG,MP,ENG,INE,IDM,ENT,COR,SM,DM,SE,DE,ANGLES] = ccf.ccf(XX) results = ccf.ccf(XX) vec = [] for r in results[:-1]:#The last item has 3 cells vec+= r vecList.append(vec) self.svmPredict(vecList) self.cleanAfterPredict() def svmPredict(self,vectorList): '''Predict the probability of a feature''' print(self.svmModel .predict(vectorList)) def showPatientInfoDialog(self): #http://stackoverflow.com/questions/5874025/pyqt4-how-to-show-a-modeless-dialog #If you don't pass the self argument,it will be recycled by garbage collector! form = PatientInfoDialog(parent=self) if form.exec_(): self.diagonosis = form.getDiagnosisInfo()#get UI_Diagnosis print(self.diagonosis)
class CenterUI(QWidget): def __init__(self): super().__init__() self.__initVariable() self.__initUI() def __initVariable(self): self.linkView=True def __initUI(self): self.viewerOriginal=ImageView(self) self.viewerEnhance=ImageView(self) self.connect_signal_slot() #控件宽度 width=self.width() height=self.height() ratioMain=[0.5,0.5] sizeMain=[width*ratioMain[0],width*ratioMain[1]] splitter=QSplitter(Qt.Horizontal,self) splitter.addWidget(self.viewerOriginal) splitter.addWidget(self.viewerEnhance) splitter.setSizes(sizeMain) hbox=QHBoxLayout() hbox.addWidget(splitter) self.setLayout(hbox) #连接信号与槽 def connect_signal_slot(self): #1连接2 self.viewerOriginal.wheelZoom.connect(self.viewerEnhance.accept_wheelZoom) self.viewerOriginal.mouseButtonPressed.connect(self.viewerEnhance.accept_mousePress) self.viewerOriginal.mouseButtonMove.connect(self.viewerEnhance.accept_mouseMove) self.viewerOriginal.mouseButtonRelease.connect(self.viewerEnhance.accept_mouseRelease) #2连接1 self.viewerEnhance.wheelZoom.connect(self.viewerOriginal.accept_wheelZoom) self.viewerEnhance.mouseButtonPressed.connect(self.viewerOriginal.accept_mousePress) self.viewerEnhance.mouseButtonMove.connect(self.viewerOriginal.accept_mouseMove) self.viewerEnhance.mouseButtonRelease.connect(self.viewerOriginal.accept_mouseRelease) #关闭信号与槽的连接 def disconnect_signal_slot(self): #1连接2 self.viewerOriginal.wheelZoom.disconnect(self.viewerEnhance.accept_wheelZoom) self.viewerOriginal.mouseButtonPressed.disconnect(self.viewerEnhance.accept_mousePress) self.viewerOriginal.mouseButtonMove.disconnect(self.viewerEnhance.accept_mouseMove) self.viewerOriginal.mouseButtonRelease.disconnect(self.viewerEnhance.accept_mouseRelease) #2连接1 self.viewerEnhance.wheelZoom.disconnect(self.viewerOriginal.accept_wheelZoom) self.viewerEnhance.mouseButtonPressed.disconnect(self.viewerOriginal.accept_mousePress) self.viewerEnhance.mouseButtonMove.disconnect(self.viewerOriginal.accept_mouseMove) self.viewerEnhance.mouseButtonRelease.disconnect(self.viewerOriginal.accept_mouseRelease) def changeLinkState(self): if self.linkView: self.linkView=False self.disconnect_signal_slot() else: self.linkView=True self.connect_signal_slot() self.viewerOriginal.clearMoveAndZoom() self.viewerEnhance.clearMoveAndZoom() def setOriginalImage(self,file): self.viewerOriginal.clearMoveAndZoom() self.viewerEnhance.clearMoveAndZoom() self.viewerOriginal.clearImage() self.viewerEnhance.clearImage() if isinstance(file,str): if not os.path.exists(file): QMessageBox.information(self,'失败','图像不存在,请检查路径') return frame=Image.open(file) img=ImageQt.ImageQt(frame).convertToFormat(QImage.Format_RGB888) self.viewerOriginal.setImage(img) else: self.viewerOriginal.setImage(file) def setEnhanceImage(self,file,mode): #第一次读取图像 if mode==0: if self.linkView: self.viewerOriginal.clearMoveAndZoom() self.viewerEnhance.clearMoveAndZoom() self.viewerEnhance.clearImage() else:#更新增项图像 # self.viewerEnhance.clearImage() pass if isinstance(file,str): if not os.path.exists(file): QMessageBox.information(self,'失败','图像不存在,请检查路径') return frame=Image.open(file) img=ImageQt.ImageQt(frame).convertToFormat(QImage.Format_RGB888) self.viewerEnhance.setImage(img) else: self.viewerEnhance.setImage(file)