def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name #self.station_name.setText('') #self.station_name.clear() #self.station_name.addItems(name.optional_values) if not self.file_list.currentItem().station is None: self.station_name.setText(self.file_list.currentItem().station) else: self.station_name.setText(name.value) #font = QFont("Consolas", 11) #self.station_name.lineEdit().setFont(font) #self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) if self.dark_theme: img = 255 - img processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show()
def setPreviewImage(self, image): """Show image in self.preview.""" factor = self.factor.value() pix = image.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene)
def drawSnippet(self, graphicsview, snippet): """Draw single result item to graphicsview""" processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) pix = pix.scaled(graphicsview.width(), graphicsview.height()-1, Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show()
def loadFileFromFile(self,path): global image image = QImage(path) scene = QGraphicsScene() scene.addPixmap(QPixmap(path)) self.graphicsView.setScene(scene) print 'loading ' + path
def main(): app = QApplication(sys.argv) mainView = QGraphicsView() scene = QGraphicsScene() pixmap = QPixmap(r":/8a130311.png") scene.addPixmap( pixmap.scaled(100, 100, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)) mainView.setScene(scene) mainView.show() app.exec_()
def loadFile(self): global image path = QFileDialog.getOpenFileName() image = QImage(path) scene = QGraphicsScene() scene.addPixmap(QPixmap(path)) self.graphicsView.setScene(scene) print 'loading ' + path
def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) #cv2.imwrite('snippets/'+unicode(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) if graphicsview.height() < pix.height(): pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show()
def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) #cv2.imwrite('snippets/'+str(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) if graphicsview.height() < pix.height(): pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show()
def main(): app = QApplication(sys.argv) grview = QGraphicsView() scene = QGraphicsScene() scene.setSceneRect(0, 0, 680, 459) scene.addPixmap(QPixmap('01.png')) grview.setScene(scene) item = GraphicsRectItem(0, 0, 300, 150) scene.addItem(item) grview.fitInView(scene.sceneRect(), Qt.KeepAspectRatio) grview.show() sys.exit(app.exec_())
def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name self.station_name.setEditText(name.value) img = self.cutImage(res.contrast_station_img, name) processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show()
def drawSnippet(self, graphicsview, snippet): """Draw single result item to graphicsview""" try: h, w = snippet.shape except: h, w, c = snippet.shape if h < 1 or w < 1: return processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) pix = pix.scaled(graphicsview.width(), graphicsview.height() - 1, Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show()
def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name self.station_name.addItems(name.optional_values) self.station_name.setEditText(name.value) font = QFont() font.setPointSize(11) self.station_name.lineEdit().setFont(font) self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show()
def _add_cookie_callback(self): if self.stage.live: cookie_idx = self.cookie_select.currentIndex() pos_idx = self.pos_select.currentIndex() self.logger.info( 'Adding cookie {0} to the recipe at {1}'.format(self.icings[cookie_idx], self.positions[pos_idx])) self.recipe.add_cookie( {'icing': self.icings[cookie_idx]}, self.positions[pos_idx]) image = self.q_image_displays[pos_idx] scene = QGraphicsScene() scene.addPixmap( QPixmap(os.path.join(DATA_DIR, self.pattern_images[cookie_idx].value))) image.setScene(scene) image.fitInView(scene.itemsBoundingRect()) image.show() else: self.logger.info( 'Stage is dead, cannot do anything. Please exit.')
class ModuleBWidget(QWidget): def __init__(self): QWidget.__init__(self) self.ui = Ui_ModuleB() self.ui.setupUi(self) self.timer = QTimer() QObject.connect(self.timer, SIGNAL("timeout()"), self.read_inputs) self.scene_nobat = QGraphicsScene() self.scene_nobat.addPixmap(QPixmap("modules/ModuleB-nobat.png")) self.scene_off = QGraphicsScene() self.scene_off.addPixmap(QPixmap("modules/ModuleB-off.png")) self.scene_on = QGraphicsScene() self.scene_on.addPixmap(QPixmap("modules/ModuleB-on.png")) self.scene_nobulb = QGraphicsScene() self.scene_nobulb.addPixmap(QPixmap("modules/ModuleB-nobulb.png")) self.ui.widgetImg.setScene(self.scene_nobat) def read_inputs(self): r = self.dev.read() us = r[1] / 1023.0 * 3.3 uc = r[2] / 1023.0 * 3.3 i = (us - uc) / 18 * 1000 if i < 0.0 or uc == 0.0: i = 0.0 self.ui.labelUs.setText("Us = %0.3f V" % us) self.ui.labelUc.setText("Uc = %0.3f V" % uc) self.ui.labelI.setText("I = %0.2f mA" % i) if us < 1.5: self.ui.widgetImg.setScene(self.scene_nobat) else: if uc < 0.9: self.ui.widgetImg.setScene(self.scene_off) elif uc > 2.0: self.ui.widgetImg.setScene(self.scene_nobulb) else: self.ui.widgetImg.setScene(self.scene_on)
class ModuleBWidget(QWidget): def __init__(self): QWidget.__init__(self) self.ui = Ui_ModuleB() self.ui.setupUi(self) self.timer = QTimer() QObject.connect(self.timer, SIGNAL("timeout()"), self.read_inputs) self.scene_nobat = QGraphicsScene() self.scene_nobat.addPixmap(QPixmap('modules/ModuleB-nobat.png')) self.scene_off = QGraphicsScene() self.scene_off.addPixmap(QPixmap('modules/ModuleB-off.png')) self.scene_on = QGraphicsScene() self.scene_on.addPixmap(QPixmap('modules/ModuleB-on.png')) self.scene_nobulb = QGraphicsScene() self.scene_nobulb.addPixmap(QPixmap('modules/ModuleB-nobulb.png')) self.ui.widgetImg.setScene(self.scene_nobat) def read_inputs(self): r = self.dev.read() us = r[1] / 1023.0 * 3.3 uc = r[2] / 1023.0 * 3.3 i = (us - uc) / 18 * 1000 if i < 0.0 or uc == 0.0: i = 0.0 self.ui.labelUs.setText('Us = %0.3f V' % us) self.ui.labelUc.setText('Uc = %0.3f V' % uc) self.ui.labelI.setText('I = %0.2f mA' % i) if us < 1.5: self.ui.widgetImg.setScene(self.scene_nobat) else: if uc < 0.9: self.ui.widgetImg.setScene(self.scene_off) elif uc > 2.0: self.ui.widgetImg.setScene(self.scene_nobulb) else: self.ui.widgetImg.setScene(self.scene_on)
class ViewPerson(QGraphicsView): """QGraphicsView widget which will show where the player is located.""" def __init__(self, data, parent=None): """Initialize the abstracted class instance""" super(ViewPerson, self).__init__(parent) #Create Containter to store graphicObjectsaaaaa self.scene = QGraphicsScene() self.setScene(self.scene) #View Settings (Fix Scroll Bars) self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) #Reference to data for event calls. self.data = data self.initUI() #LoadObjects def initUI(self): """Load places and character""" #Load Places from Loc Object List for loc in self.data.places: self.loadGraphic(loc) #Load Character self.loadGraphic(self.data.character) def loadGraphic(self, loc): """Loads graphics""" obj = self.scene.addPixmap(QtGui.QPixmap(loc.image)) loc.pViewObj = obj obj.setX(loc.x) obj.setY(loc.y) loc.updatePViewObj() if self.data.debug: print 'Load '+str(loc.image)+' at:', obj.x(), obj.y()
class PreView(QGraphicsView): def __init__(self): QGraphicsView.__init__(self) self.zoom = 2 self.scale(self.zoom, self.zoom) self.lastSize = 0 self.setDragMode(QGraphicsView.ScrollHandDrag) # self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.installEventFilter(self) self.hudLayout = QVBoxLayout(self) self.hudLayout.setContentsMargins(0,0,0,0) self.ellipseLabel = QLabel() self.ellipseLabel.setMinimumWidth(self.width()) self.hudLayout.addWidget(self.ellipseLabel) self.ellipseLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True) def setPreviewImage(self, previewImage): self.grscene = QGraphicsScene() pixmapImage = QPixmap(previewImage) self.grscene.addPixmap(pixmapImage) self.setScene(self.grscene) def eventFilter(self, obj, event): if(event.type()==QEvent.Resize): self.ellipseLabel.setMinimumWidth(self.width()) self.updateFilledCircle(self.lastSize) return False def sizeHint(self): return QSize(200, 200) def setFilledBrsuh(self, size): self.updateFilledCircle(size) def updateCircle(self, s): size = s * self.zoom pixmap = QPixmap(self.width(), self.height()) pixmap.fill(Qt.transparent) #painter ellipse 1 painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing) pen = QPen(Qt.red) pen.setWidth(3) painter.setPen(pen) brush = QBrush(Qt.green) painter.setBrush(brush) painter.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size)) painter.end() #painter ellipse 2 painter2 = QPainter() painter2.begin(pixmap) painter2.setRenderHint(QPainter.Antialiasing) pen2 = QPen(Qt.green) pen2.setStyle(Qt.DotLine) pen2.setWidth(3) painter2.setPen(pen2) painter2.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size)) painter2.end() self.ellipseLabel.setPixmap(QPixmap(pixmap)) self.lastSize = s def updateFilledCircle(self, s): size = s * self.zoom pixmap = QPixmap(self.width(), self.height()) pixmap.fill(Qt.transparent) #painter filled ellipse p = QPalette() painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing) brush = QBrush(p.link().color()) painter.setBrush(brush) painter.setOpacity(0.4) painter.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size)) painter.end() #painter ellipse 2 painter2 = QPainter() painter2.begin(pixmap) painter2.setRenderHint(QPainter.Antialiasing) pen2 = QPen(Qt.green) pen2.setWidth(1) painter2.setPen(pen2) painter2.drawEllipse(QRect(self.width()/2 - size/2, self.height()/2 - size/2, size, size)) painter2.end() self.ellipseLabel.setPixmap(QPixmap(pixmap)) self.lastSize = s
class LeapFlow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.controller = Controller() self.listener = LeapListener(self) self.controller.add_listener(self.listener) self.mode = "gallery" self.scroll = False self.direction = "" self.direction_x = 0 self.scroll_velocity = 0 self.current_index = 0 # List containing images for the gallery self.list_view = QListWidget() self.list_view.setFlow(0) self.list_view.setHorizontalScrollMode(1) self.list_view.setMouseTracking(True) self.list_view.itemClicked.connect(self.show_image) # Setting the style of the ListView, background, item selected, etc self.list_view.setStyleSheet( """ QListWidget::item:hover {background: transparent;} QListWidget::item:disabled:hover {background: transparent;} QListWidget::item:hover:!active {background: transparent;} QListWidget::item:selected:active {background: transparent;} QListWidget::item:selected:!active {background: transparent;} QListWidget::item:selected:disabled {background: transparent;} QListWidget::item:selected:!disabled {background: transparent;} QListWidget {background: #2C3539} """ ) # Image viewer self.scene = QGraphicsScene() self.viewer = QGraphicsView(self.scene) self.stackedWidget = QStackedWidget() self.stackedWidget.addWidget(self.list_view) self.stackedWidget.addWidget(self.viewer) self.setCentralWidget(self.stackedWidget) self.resize(500, 400) self.showMaximized() scan = ScanLibrary("/home/chris/Example") threads.append(scan) self.connect(scan, SIGNAL(scan.signal), self.add_images_to_list) scan.start() self.connect(self, SIGNAL("scrollChanged(bool)"), self.scroll_view) def setScroll(self, scroll): """Emit signal to scroll the view""" if self.scroll != scroll: self.scroll = scroll self.emit(SIGNAL("scrollChanged(bool)"), scroll) def scroll_view(self): """Scroll the view based on scroll velocity and direction""" x = self.direction_x * self.scroll_velocity / 100 bar_x = self.list_view.horizontalScrollBar().value() self.list_view.horizontalScrollBar().setValue(bar_x + x) def add_images_to_list(self): """To add a widget to the listview you must add a QListWidgetItem and replace with your widget""" for image in library: item = QListWidgetItem() pixmap = QPixmap.fromImage(QImage(library[image])) label = QLabel() label.setPixmap(pixmap.scaled(600, 400)) item.setSizeHint(label.sizeHint()) item.setData(0, library[image]) self.list_view.addItem(item) self.list_view.setItemWidget(item, label) def show_image(self, item): """"Display the selected image""" self.current_index = self.list_view.indexFromItem(item).row() self.scene.addPixmap((QPixmap.fromImage(QImage(item.text()))).scaled(self.viewer.size())) self.stackedWidget.setCurrentIndex(1) self.mode = "viewer" def previous_image(self): """Load previous image""" if self.current_index - 1 >= 0: self.current_index -= 1 self.load_image() def next_image(self): """Load next image""" if self.current_index + 1 <= len(library.keys()) - 1: self.current_index += 1 self.load_image() def load_image(self): """Load the image in self.current_index""" self.scene.addPixmap(QPixmap.fromImage(QImage(library[library.keys()[self.current_index]])))
class DualImageView(QGraphicsView): VERTICAL = 0 HORIZONTAL = 1 IMAGE_A = 0 IMAGE_B = 1 # no argument signal images_changed = pyqtSignal() annotations_changed = pyqtSignal() annotation_selected = pyqtSignal(int) no_selection = pyqtSignal() # click/point signals image_a_click = pyqtSignal(int,int) image_b_click = pyqtSignal(int,int) # keyboard key_event = pyqtSignal(int) def __init__(self, main_win): super(QGraphicsView,self).__init__(main_win) self.parent_ = main_win self.main_win_ = main_win self.setInteractive(True) self.setStyleSheet("QGraphicsView { border: none; }") self.scene_ = QGraphicsScene(0,0,0,0,self.parent_) self.image_item_ = self.scene_.addPixmap(QPixmap()) self.image_item_.setPos(0,0) #self.ann_group_ = QGraphicsItemGroup() #self.ann_group_.setPos(0,0) #self.scene_.addItem(self.ann_group_) self.setScene(self.scene_) self.scene_.selectionChanged.connect(self.on_selection_changed) # TODO: handle orientation self.orientation_ = DualImageView.VERTICAL self.images_ = [None, None] self.composite_ = None self.annotations_ = [] self.dim_ = 0 self.offset_ = np.array([0,0]) self.cancel_click_ = False self.images_changed.connect(self.on_images_changed) self.annotations_changed.connect(self.on_annotations_changed) def on_selection_changed(self): log.debug("on_selection_changed") selected = self.scene_.selectedItems() if len(selected) > 0: self.cancel_click_ = True selected = self.scene_.selectedItems()[0] idx = -1 for a in self.annotations_: idx += 1 if a.item == selected: log.debug(" emitting selection {0}".format(idx)) self.annotation_selected.emit(idx) else: self.no_selection.emit() @property def image_b_offset(self): return np.array([0,self.dim_],dtype=np.int32) def point_in_image(self, p): if p[1] < self.dim_: return 0 else: return 1 def point_to_image(self, which, p): if which == DualImageView.IMAGE_B: return p - self.image_b_offset return p def image_to_view(self, which, p): if which == DualImageView.IMAGE_B: return p + self.image_b_offset return p def on_images_changed(self): imga = self.images_[0] imgb = self.images_[1] width = max(imga.shape[1],imgb.shape[1]) heighta = imga.shape[0] heightb = imgb.shape[0] height = heighta + heightb self.dim_ = heighta self.offset_ = np.array([0,heighta]) # this assumes rgb images :-( comp = np.empty((height,width,imga.shape[2]),dtype=imga.dtype) comp[0:heighta,:imga.shape[1],:] = imga comp[heighta:(heighta+heightb),:imgb.shape[1],:] = imgb self.composite_ = comp qimg = qn.array2qimage(self.composite_) pix = QPixmap.fromImage(qimg) self.image_item_.setPixmap(pix) self.scene_.setSceneRect(0,0, width, height) self.repaint() def on_annotations_changed(self): #log.debug("on_annotations_changed") # self.scene_.removeItem(self.ann_group_) # self.ann_group_ = QGraphicsItemGroup() # self.ann_group_.setHandlesChildEvents(False) # self.ann_group_.setPos(0,0) # for a in self.annotations_: # log.debug(" adding item") # self.ann_group_.addToGroup(a.get_item()) # self.scene_.addItem(self.ann_group_) self.repaint() def transform_raw_pt(self, ev): pt = self.mapToScene(ev.x(), ev.y()) return np.array([int(pt.x()), int(pt.y())], dtype=np.int32) def clear(self): self.images_ = [None,None] self.composite_ = None self.annotations_ = None self.images_changed.emit() self.annotations_changed.emit() def set_images(self, img_pair): self.images_ = img_pair self.images_changed.emit() # @property # def annotations(self): # return self.annotations_ # @annotations.setter # def annotations(self, anns): # self.annotations_ = anns # self.annotations_changed.emit() # def set_annotations(self, anns): # self.annotations_ = anns # self.annotations_changed.emit() def paintEvent(self, ev): painter = QPainter(self.viewport()) painter.fillRect(0,0,self.viewport().width(),self.viewport().height(), QColor(0,0,0)) painter.end() QGraphicsView.paintEvent(self, ev) def annotation(self, idx): return self.annotations_[idx] def clear_annotations(self): for a in self.annotations_: self.scene_.removeItem(a.item) self.annotations_ = [] self.annotations_changed.emit() def add_annotation(self, ann): ann.changed.connect(self.on_annotations_changed) self.annotations_.append(ann) self.scene_.addItem(ann.item) self.annotations_changed.emit() return len(self.annotations_) - 1 def remove_last_annotation(self): self.scene_.removeItem(self.annotations_[-1].item) del self.annotations_[-1] self.annotations_changed.emit() def remove_annotation(self, idx): self.scene_.removeItem(self.annotations_[idx].item) del self.annotations_[idx] self.annotations_changed.emit() def mousePressEvent(self, ev): super(DualImageView,self).mousePressEvent(ev) if self.cancel_click_: return log.debug("mouse pressed: " + str(ev)) self.img_local_pt = self.transform_raw_pt(ev) def mouseReleaseEvent(self, ev): super(DualImageView,self).mouseReleaseEvent(ev) if self.cancel_click_: self.cancel_click_ = False return log.debug("mouse released: " + str(ev)) rel_pt = self.transform_raw_pt(ev) delta = rel_pt - self.img_local_pt if abs(delta[0]) < 3 and abs(delta[1] < 3): # it was a successful click self.mouseClicked(self.img_local_pt) else: # recognize this as a rectangle drag self.mouseDragged(self.img_local_pt, delta) def mouseDragged(self, pt, delta): log.debug("mouse dragged: {0}, {1}".format(pt,delta)) def mouseClicked(self, pt): log.debug("mouse clicked: {0}".format(pt)) if pt[1] < self.dim_: self.image_a_click.emit(pt[0],pt[1]) else: self.image_b_click.emit(pt[0],pt[1] - self.dim_) # handle the keyboard events here! def keyPressEvent(self, ev): pass def keyReleaseEvent(self, ev): k = ev.key() self.key_event.emit(k)
class LearningWizard(QWizard, Ui_Wizard): def __init__(self, settings): QWizard.__init__(self) self.setupUi(self) self.settings = settings self.wizardPage3.pageCreated.connect(self.showSummary) self.wizardPage3.fullfilled = True self.wizardPage2.fullfilled = True self.errors = 0 self.steps = 0 self.delete_images_button.clicked.connect(self.deleteUserImages) self.add_files_button.clicked.connect(self.AddFiles) self.remove_file_button.clicked.connect(self.removeFile) self.save_button.clicked.connect(self.saveImgData) self.train_button.clicked.connect(self.trainOCR) self.ocr_button.clicked.connect(self.runOCR) self.next_button.clicked.connect(self.nextWord) self.prev_button.clicked.connect(self.previousWord) #self.add_screenshots.clicked.connect(self.AddFiles) #self.wizardPage2.pageCreated.connect(self.AnalyzeImg) #self.contrast = 0.0 #self.img_fields = [self.g1,self.g2,self.g3,self.g4,self.g5,self.g6,self.g7,self.g8,self.g9,self.g10,self.g11,self.g12,self.g13,self.g14,self.g15,self.g16,self.g17,self.g18,self.g19,self.g20] #self.input_fields = [self.e1,self.e2,self.e3,self.e4,self.e5,self.e6,self.e7,self.e8,self.e9,self.e10,self.e11,self.e12,self.e13,self.e14,self.e15,self.e16,self.e17,self.e18,self.e19,self.e20] self.gviews = [] self.ledits = [] self.boxlist = [] self.imglist = [] self.charlist = [] self.words = [] self.boundaries = [] self.wordcount = 0 self.current = 0 self.scene = None self.ratio_h = 1.0 self.ratio_w = 1.0 self.base = self.loadBase() self.user = self.loadUser() if not self.base is None: self.base_data_label.setText(self.getBaseData()) if not self.user is None: self.delete_images_button.setEnabled(True) self.user_data_label.setText(self.getUserData()) #self.resizeElements() #for index,item in zip(range(20), self.input_fields): # item.textEdited.connect(partial(self.changeText, index)) self.train_button.setEnabled(True) #self.grid = QGridLayout() #self.field_holder.addLayout(self.grid) def deleteUserImages(self): self.user = None path = self.settings.storage_path+os.sep+"user_training_data.pck" remove(path) self.user_data_label.setText("-") self.delete_images_button.setEnabled(False) def showSummary(self): summary = "" userdata = {} characters = ["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '*', '+', '#'] for word in self.words: for letter in word: if letter[1] in characters: if letter[1] in userdata: userdata[letter[1]] += 1 else: userdata[letter[1]] = 1 for key in characters: if key in userdata: summary += '"'+key+'"' +": " +str(userdata[key])+", " self.summary_label.setText(summary) def trainOCR(self): self.train_button.setEnabled(False) alldata = self.connectData() testnumbers = self.getRandomData(alldata,[',', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) testletters = self.getRandomData(alldata,["'", ',', '-', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']) teststation = self.getRandomData(alldata,["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']) testlevel = self.getRandomData(alldata,['*', '+', '#']) self.movie = QMovie(":/ico/loader.gif") self.loader.setMovie(self.movie) self.movie.start() self.numberstrainerthread = Trainer(self, "numbers", self.base, self.user, testnumbers, testletters, teststation, testlevel) self.letterstrainerthread = Trainer(self, "letters", self.base, self.user, testnumbers, testletters, teststation, testlevel) self.stationtrainerthread = Trainer(self, "station", self.base, self.user, testnumbers, testletters, teststation, testlevel) self.leveltrainerthread = Trainer(self, "level" , self.base, self.user, testnumbers, testletters, teststation, testlevel) QObject.connect(self.numberstrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished) QObject.connect(self.letterstrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished) QObject.connect(self.stationtrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished) QObject.connect(self.leveltrainerthread , SIGNAL('finished(QString, int)'), self.stepFinished) #QObject.connect(self.trainerthread, SIGNAL('finishedall(int)'), self.trainingFinished) self.numberstrainerthread.execute() self.letterstrainerthread.execute() self.stationtrainerthread.execute() self.leveltrainerthread.execute() self.training_summary.setText("Training in progress") def trainingFinished(self): if self.errors < 3: self.training_summary.setText("The training sucessfully finished. Your OCR accuracy should be very high.") elif self.errors < 6: self.training_summary.setText("The training sucessfully finished. Your OCR accuracy should satisfactory. You might still increase it by repeating this process with other screenshots.") elif self.errors < 10: self.training_summary.setText("The training sucessfully finished. Your OCR accuracy is sufficient but not perfect. You should repeat this process with other screenshots.") else: self.training_summary.setText("The training finished. Your OCR accuracy is not sufficient. You should repeat this process with other screenshots.") def stepFinished(self, value, error): self.steps += 1 self.details.append(value+"\n") self.errors += error if self.steps == 3: self.trainingFinished() self.movie.stop() self.loader.clear() def connectData(self): connected = {} characters = ["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '*', '+', '#'] if self.user is None: self.user = {} if self.base is None: self.base = {} for char in characters: if char in self.base and char in self.user: connected[char] = self.base[char]+self.user[char] elif char in self.base: connected[char] = self.base[char] elif char in self.user: connected[char] = self.user[char] return connected def getRandomData(self, data, characters): self.testsamples = {} samples = 30 for char in characters: amount = len(data[char])/400 if amount > samples: picks = random.sample(range(amount), samples) else: picks = random.sample(range(amount), amount) temp = bitarray() for pick in picks: temp += data[char][pick*400:pick*400+400] self.testsamples[char] = temp return self.testsamples def saveImgData(self): characters = ["'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '*', '+', '#'] if self.user is None: self.user = {} for word in self.words: for letter in word: if letter[1] in characters: data = bitarray() image = cv2.resize(letter[0], (20, 20)) ret,image = cv2.threshold(image,250,255,cv2.THRESH_BINARY) for row in image: for cell in row: if cell == 255: data.append(True) else: data.append(False) if letter[1] in self.user: self.user[letter[1]] += data else: self.user[letter[1]] = data path = self.settings.storage_path+os.sep+"user_training_data.pck" file = gzip.GzipFile(path, 'wb') pickle.dump(self.user, file,-1) file.close() self.save_button.setEnabled(False) self.train_button.setEnabled(True) def changeText(self, index): #print index self.words[self.current][index][1] = unicode(self.ledits[index].text()) def getBaseData(self): text = "" keys = [] for key in self.base: keys.append(key) keys.sort() for key in keys: text += key + ": " + str(len(self.base[key])/400)+", " #print keys return text def getUserData(self): text = "" keys = [] for key in self.user: keys.append(key) keys.sort() for key in keys: text += key + ": " + str(len(self.user[key])/400)+", " return text def loadBase(self): try: path = self.settings.app_path+os.sep+"trainingdata"+os.sep+"base_training_data.pck" file = gzip.GzipFile(path, 'rb') letters = pickle.load(file) file.close() return letters except: return None def loadUser(self): try: path = self.settings.storage_path+os.sep+"user_training_data.pck" file = gzip.GzipFile(path, 'rb') letters = pickle.load(file) file.close() return letters except: return None def removeFile(self): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item def AddFiles(self): if self.settings["native_dialog"]: files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir']) else: files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir'], options = QFileDialog.DontUseNativeDialog) if files == []: return first_item = None counter = 0 for file in files: file1 = unicode(file).encode(sys.getfilesystemencoding()) item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) counter+=1 """ def resizeElements(self): fields = self.input_fields for field in fields: field.setMinimumSize(QSize(0, self.settings['input_size'])) field.setMaximumSize(QSize(16777215, self.settings['input_size'])) canvases = self.img_fields for canvas in canvases: canvas.setMinimumSize(QSize(0, self.settings['snippet_size'])) canvas.setMaximumSize(QSize(16777215, self.settings['snippet_size'])) """ def runOCR(self): self.add_files_button.setEnabled(False) self.remove_file_button.setEnabled(False) self.ocr_button.setEnabled(False) self.file_list.setEnabled(False) self.repaint() self.current_image = 0 self.results = [] self.images = [] self.prev = [] self.marketoffset = [] self.stationoffset = [] files = self.file_list.count() for i in xrange(files): self.file_list.setCurrentRow(i) item = self.file_list.currentItem() color_image = item.loadColorImage() preview_image = item.addTestImage(color_image) self.images.append(color_image) self.prev.append(preview_image) #cv2.imshow("x", color_image) #cv2.waitKey(0) # #images.append(preview_image) #self.setPreviewImage(preview_image) #return self.stationoffset.append(item.ocr_areas.station_name) self.marketoffset.append(item.ocr_areas.market_table) current_result = OCR(color_image, item.ocr_areas, self.settings["ocr_language"], item, levels = False, levenshtein = False) self.results.append(current_result) self.allBoxes() #print len(self.words) #print self.words[1] self.next_button.setEnabled(True) self.prev_button.setEnabled(False) self.showSet() self.notifier.setText("You did not check every word yet.") def showSet(self): #self.snippet_preview bound = self.boundaries[self.current] #print self.current #print bound[1] image = self.images[bound[0]][bound[1][1]-2:bound[1][3]+3,bound[1][0]-2:bound[1][2]+2] self.drawSnippet(self.snippet_preview, image) for gview in self.gviews: self.grid.removeWidget(gview) gview.deleteLater() gview = None for ledit in self.ledits: self.grid.removeWidget(ledit) ledit.deleteLater() ledit = None self.gviews = [] self.ledits = [] letters = len(self.words[self.current]) for i in range(letters): gview = QGraphicsView() self.grid.addWidget(gview,0,i) self.gviews.append(gview) gview.setMaximumSize(50, self.settings['snippet_size']) gview.setVerticalScrollBarPolicy(1) gview.setHorizontalScrollBarPolicy(1) self.drawSnippet(gview, self.words[self.current][i][0]) ledit = QLineEdit() self.grid.addWidget(ledit,1,i) self.ledits.append(ledit) ledit.setMaximumSize(50, self.settings['input_size']) ledit.setAlignment(Qt.AlignHCenter) ledit.setText(self.words[self.current][i][1]) for index,item in zip(range(50), self.ledits): item.textEdited.connect(partial(self.changeText, index)) self.repaint() """ pictures = len(self.img_fields) if pictures < len(self.imglist)-((self.current-1)*20): for i in range(20): if len(self.imglist) > (self.current*20)+i: self.drawSnippet(self.img_fields[i], self.imglist[(self.current*20)+i]) self.input_fields[i].setText(self.charlist[(self.current*20)+i]) else: self.cleanSnippet(self.img_fields[i]) self.input_fields[i].setText("") self.wizardPage2.fullfilled = True self.wizardPage2.completeChanged.emit() """ def previousWord(self): if self.current > 0: self.current -= 1 self.showSet() self.next_button.setEnabled(True) if self.current == 0: self.prev_button.setEnabled(False) else: self.prev_button.setEnabled(True) def nextWord(self): #print self.maxcount if self.current < self.wordcount-1: self.current += 1 self.showSet() self.prev_button.setEnabled(True) if self.current == self.wordcount-1: self.next_button.setEnabled(False) self.notifier.setText("You checked every word now. If you corrected every letter continue to next page.") else: self.next_button.setEnabled(True) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene) def drawOCRPreview(self): factor = 1.0 img = self.prev[0] old_h = img.height() old_w = img.width() pix = img.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() self.ratio_h = old_h/float(new_h) self.ratio_w = old_w/float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) #for box in self.boxes(): # rect = self.addRect(self.scene, box, ratio_w, ratio_h, pen) # self.previewRects.append(rect) rect = self.addRect(self.scene, self.boxlist[0], self.ratio_w, self.ratio_h, pen) self.previewRects.append(rect) self.previewSetScene(self.scene) def drawSnippet(self, graphicsview, snippet): """Draw single result item to graphicsview""" try: h, w = snippet.shape except: h, w, c = snippet.shape if h < 1 or w <1: return processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) pix = pix.scaled(graphicsview.width(), graphicsview.height()-1, Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect((item[0])/ratio_w , (item[2])/ratio_h, item[1]/ratio_w, item[3]/ratio_h, pen) return rect def allBoxes(self): for i in range(self.file_list.count()): self.file_list.setCurrentRow(i) current = self.file_list.currentItem() res = self.results[i].station.name cres = self.results[i] self.charlist += list(res.value.replace(" ", "").upper()) text = res.value.replace(" ", "") imgcount = len(self.results[i].station.name.units) charcount = len(text) word = [] for j in range(imgcount): if j < charcount: char = text[j] else: char = "" unit = self.results[i].station.name.units[j] image = cres.station_img[unit[2]:unit[3]+1,unit[0]:unit[1]] #cv2.imshow("x", image) #cv2.waitKey(0) h = res.h if len(image) > 0: if ((h*1.0)/len(image[0])) > 3: y1 = res.y1 if y1 < 0: y1 = 0 image = cres.station_img[y1:unit[3], unit[0]:unit[1]] border = (h - len(image[0]))/2 image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255)) if len(image) < h/2.0: y1 = res.y1 if y1 < 0: y1 = 0 image = cres.station_img[y1:res.y2, unit[0]:unit[1]] border = (h - len(image[0]))/2 image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255)) th, tw = image.shape if th < 1 or tw < 1: image = np.ones((10,10,1), dtype=np.uint8) * 255 self.imglist.append(image) word.append([image, char]) self.words.append(word) self.boundaries.append([i, [res.box[0]+self.stationoffset[i][0][0], res.box[1]+self.stationoffset[i][0][1], res.box[2]+self.stationoffset[i][0][0], res.box[3]+self.stationoffset[i][0][1]]]) for line in self.results[i].commodities: for item in line.items: if not item is None: text = item.value.replace(" ", "") imgcount = len(item.units) charcount = len(text) word = [] self.charlist += list(item.value.replace(" ", "").upper()) for j in range(imgcount): if j < charcount: char = text[j] else: char = "" unit = item.units[j] self.boxlist.append([unit[0]+current.market_offset[0],unit[1]-unit[0], unit[2]+current.market_offset[1],unit[3]-unit[2]]) image = cres.commodities_img[unit[2]:unit[3]+1,unit[0]:unit[1]] h = line.h if len(image) > 0: if ((h*1.0)/len(image[0])) > 3: y1 = line.y1 if line.y1 >= 0 else 0 if y1 < 0: y1 = 0 image = cres.commodities_img[y1:unit[3], unit[0]:unit[1]] if image.shape[0] > 0 and image.shape[1] > 0: border = (h - len(image[0]))/2 image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255)) if len(image) < h/2.0: y1 = line.y1 if line.y1 >= 0 else 0 if y1 < 0: y1 = 0 image = cres.commodities_img[y1:line.y2, unit[0]:unit[1]] if image.shape[0] > 0 and image.shape[1] > 0: border = (h - len(image[0]))/2 image = cv2.copyMakeBorder(image,0,0,border,border,cv2.BORDER_CONSTANT,value=(255,255,255)) th, tw = image.shape if th < 1 or tw < 1: image = np.ones((10,10,1), dtype=np.uint8) * 255 self.imglist.append(image) word.append([image, char]) self.words.append(word) self.boundaries.append([i, [item.box[0]+self.marketoffset[i][0][0], item.box[1]+self.marketoffset[i][0][1], item.box[2]+self.marketoffset[i][0][0], item.box[3]+self.marketoffset[i][0][1]]]) self.wordcount = len(self.words) #self.maxcount = len(self.imglist)/20 def setPreviewImage(self, image): """Show image in self.preview.""" #factor = self.factor.value() factor = 1.0 pix = image.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show()
class LearningWizard(QWizard, Ui_Wizard): def __init__(self, settings): QWizard.__init__(self) self.setupUi(self) self.settings = settings self.wizardPage3.pageCreated.connect(self.showSummary) self.wizardPage3.fullfilled = True self.wizardPage2.fullfilled = True self.errors = 0 self.steps = 0 self.delete_images_button.clicked.connect(self.deleteUserImages) self.add_files_button.clicked.connect(self.AddFiles) self.remove_file_button.clicked.connect(self.removeFile) self.save_button.clicked.connect(self.saveImgData) self.train_button.clicked.connect(self.trainOCR) self.ocr_button.clicked.connect(self.runOCR) self.next_button.clicked.connect(self.nextWord) self.prev_button.clicked.connect(self.previousWord) #self.add_screenshots.clicked.connect(self.AddFiles) #self.wizardPage2.pageCreated.connect(self.AnalyzeImg) #self.contrast = 0.0 #self.img_fields = [self.g1,self.g2,self.g3,self.g4,self.g5,self.g6,self.g7,self.g8,self.g9,self.g10,self.g11,self.g12,self.g13,self.g14,self.g15,self.g16,self.g17,self.g18,self.g19,self.g20] #self.input_fields = [self.e1,self.e2,self.e3,self.e4,self.e5,self.e6,self.e7,self.e8,self.e9,self.e10,self.e11,self.e12,self.e13,self.e14,self.e15,self.e16,self.e17,self.e18,self.e19,self.e20] self.gviews = [] self.ledits = [] self.boxlist = [] self.imglist = [] self.charlist = [] self.words = [] self.boundaries = [] self.wordcount = 0 self.current = 0 self.scene = None self.ratio_h = 1.0 self.ratio_w = 1.0 self.base = self.loadBase() self.user = self.loadUser() if not self.base is None: self.base_data_label.setText(self.getBaseData()) if not self.user is None: self.delete_images_button.setEnabled(True) self.user_data_label.setText(self.getUserData()) #self.resizeElements() #for index,item in zip(range(20), self.input_fields): # item.textEdited.connect(partial(self.changeText, index)) self.train_button.setEnabled(True) #self.grid = QGridLayout() #self.field_holder.addLayout(self.grid) def deleteUserImages(self): self.user = None path = self.settings.storage_path + os.sep + "user_training_data.pck" remove(path) self.user_data_label.setText("-") self.delete_images_button.setEnabled(False) def showSummary(self): summary = "" userdata = {} characters = [ "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] for word in self.words: for letter in word: if letter[1] in characters: if letter[1] in userdata: userdata[letter[1]] += 1 else: userdata[letter[1]] = 1 for key in characters: if key in userdata: summary += '"' + key + '"' + ": " + str(userdata[key]) + ", " self.summary_label.setText(summary) def trainOCR(self): self.train_button.setEnabled(False) alldata = self.connectData() testnumbers = self.getRandomData( alldata, [',', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']) testletters = self.getRandomData(alldata, [ "'", ',', '-', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]) teststation = self.getRandomData(alldata, [ "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]) self.movie = QMovie(":/ico/loader.gif") self.loader.setMovie(self.movie) self.movie.start() self.numberstrainerthread = Trainer(self, "numbers", self.base, self.user, testnumbers, testletters, teststation) self.letterstrainerthread = Trainer(self, "letters", self.base, self.user, testnumbers, testletters, teststation) self.stationtrainerthread = Trainer(self, "station", self.base, self.user, testnumbers, testletters, teststation) QObject.connect(self.numberstrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished) QObject.connect(self.letterstrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished) QObject.connect(self.stationtrainerthread, SIGNAL('finished(QString, int)'), self.stepFinished) #QObject.connect(self.trainerthread, SIGNAL('finishedall(int)'), self.trainingFinished) self.numberstrainerthread.execute() self.letterstrainerthread.execute() self.stationtrainerthread.execute() self.training_summary.setText("Training in progress") def trainingFinished(self): if self.errors < 3: self.training_summary.setText( "The training sucessfully finished. Your OCR accuracy should be very high." ) elif self.errors < 6: self.training_summary.setText( "The training sucessfully finished. Your OCR accuracy should satisfactory. You might still increase it by repeating this process with other screenshots." ) elif self.errors < 10: self.training_summary.setText( "The training sucessfully finished. Your OCR accuracy is sufficient but not perfect. You should repeat this process with other screenshots." ) else: self.training_summary.setText( "The training finished. Your OCR accuracy is not sufficient. You should repeat this process with other screenshots." ) def stepFinished(self, value, error): self.steps += 1 self.details.append(value + "\n") self.errors += error if self.steps == 3: self.trainingFinished() self.movie.stop() self.loader.clear() def connectData(self): connected = {} characters = [ "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] if self.user is None: self.user = {} if self.base is None: self.base = {} for char in characters: if char in self.base and char in self.user: connected[char] = self.base[char] + self.user[char] elif char in self.base: connected[char] = self.base[char] elif char in self.user: connected[char] = self.user[char] return connected def getRandomData(self, data, characters): self.testsamples = {} samples = 30 for char in characters: amount = len(data[char]) / 400 if amount > samples: picks = random.sample(range(amount), samples) else: picks = random.sample(range(amount), amount) temp = bitarray() for pick in picks: temp += data[char][pick * 400:pick * 400 + 400] self.testsamples[char] = temp return self.testsamples def saveImgData(self): characters = [ "'", ',', '-', '&', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ] if self.user is None: self.user = {} for word in self.words: for letter in word: if letter[1] in characters: data = bitarray() image = cv2.resize(letter[0], (20, 20)) ret, image = cv2.threshold(image, 250, 255, cv2.THRESH_BINARY) for row in image: for cell in row: if cell == 255: data.append(True) else: data.append(False) if letter[1] in self.user: self.user[letter[1]] += data else: self.user[letter[1]] = data path = self.settings.storage_path + os.sep + "user_training_data.pck" file = gzip.GzipFile(path, 'wb') pickle.dump(self.user, file, -1) file.close() self.save_button.setEnabled(False) self.train_button.setEnabled(True) def changeText(self, index): #print index self.words[self.current][index][1] = unicode(self.ledits[index].text()) def getBaseData(self): text = "" keys = [] for key in self.base: keys.append(key) keys.sort() for key in keys: text += key + ": " + str(len(self.base[key]) / 400) + ", " #print keys return text def getUserData(self): text = "" keys = [] for key in self.user: keys.append(key) keys.sort() for key in keys: text += key + ": " + str(len(self.user[key]) / 400) + ", " return text def loadBase(self): try: path = self.settings.app_path + os.sep + "trainingdata" + os.sep + "base_training_data.pck" file = gzip.GzipFile(path, 'rb') letters = pickle.load(file) file.close() return letters except: return None def loadUser(self): try: path = self.settings.storage_path + os.sep + "user_training_data.pck" file = gzip.GzipFile(path, 'rb') letters = pickle.load(file) file.close() return letters except: return None def removeFile(self): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item def AddFiles(self): if self.settings["native_dialog"]: files = QFileDialog.getOpenFileNames( self, "Open", self.settings['screenshot_dir']) else: files = QFileDialog.getOpenFileNames( self, "Open", self.settings['screenshot_dir'], options=QFileDialog.DontUseNativeDialog) if files == []: return first_item = None counter = 0 for file in files: file1 = unicode(file).encode(sys.getfilesystemencoding()) item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) counter += 1 """ def resizeElements(self): fields = self.input_fields for field in fields: field.setMinimumSize(QSize(0, self.settings['input_size'])) field.setMaximumSize(QSize(16777215, self.settings['input_size'])) canvases = self.img_fields for canvas in canvases: canvas.setMinimumSize(QSize(0, self.settings['snippet_size'])) canvas.setMaximumSize(QSize(16777215, self.settings['snippet_size'])) """ def runOCR(self): self.add_files_button.setEnabled(False) self.remove_file_button.setEnabled(False) self.ocr_button.setEnabled(False) self.file_list.setEnabled(False) self.repaint() self.current_image = 0 self.results = [] self.images = [] self.prev = [] self.marketoffset = [] self.stationoffset = [] files = self.file_list.count() for i in xrange(files): self.file_list.setCurrentRow(i) item = self.file_list.currentItem() color_image = item.loadColorImage() preview_image = item.addTestImage(color_image) self.images.append(color_image) self.prev.append(preview_image) #cv2.imshow("x", color_image) #cv2.waitKey(0) # #images.append(preview_image) #self.setPreviewImage(preview_image) #return self.stationoffset.append(item.ocr_areas.station_name) self.marketoffset.append(item.ocr_areas.market_table) current_result = OCR(color_image, item.ocr_areas, self.settings["ocr_language"], item, levels=False, levenshtein=False) self.results.append(current_result) self.allBoxes() #print len(self.words) #print self.words[1] self.next_button.setEnabled(True) self.prev_button.setEnabled(False) self.showSet() self.notifier.setText("You did not check every word yet.") def showSet(self): #self.snippet_preview bound = self.boundaries[self.current] #print self.current #print bound[1] image = self.images[bound[0]][bound[1][1] - 2:bound[1][3] + 3, bound[1][0] - 2:bound[1][2] + 2] self.drawSnippet(self.snippet_preview, image) for gview in self.gviews: self.grid.removeWidget(gview) gview.deleteLater() gview = None for ledit in self.ledits: self.grid.removeWidget(ledit) ledit.deleteLater() ledit = None self.gviews = [] self.ledits = [] letters = len(self.words[self.current]) for i in range(letters): gview = QGraphicsView() self.grid.addWidget(gview, 0, i) self.gviews.append(gview) gview.setMaximumSize(50, self.settings['snippet_size']) gview.setVerticalScrollBarPolicy(1) gview.setHorizontalScrollBarPolicy(1) self.drawSnippet(gview, self.words[self.current][i][0]) ledit = QLineEdit() self.grid.addWidget(ledit, 1, i) self.ledits.append(ledit) ledit.setMaximumSize(50, self.settings['input_size']) ledit.setAlignment(Qt.AlignHCenter) ledit.setText(self.words[self.current][i][1]) for index, item in zip(range(50), self.ledits): item.textEdited.connect(partial(self.changeText, index)) self.repaint() """ pictures = len(self.img_fields) if pictures < len(self.imglist)-((self.current-1)*20): for i in range(20): if len(self.imglist) > (self.current*20)+i: self.drawSnippet(self.img_fields[i], self.imglist[(self.current*20)+i]) self.input_fields[i].setText(self.charlist[(self.current*20)+i]) else: self.cleanSnippet(self.img_fields[i]) self.input_fields[i].setText("") self.wizardPage2.fullfilled = True self.wizardPage2.completeChanged.emit() """ def previousWord(self): if self.current > 0: self.current -= 1 self.showSet() self.next_button.setEnabled(True) if self.current == 0: self.prev_button.setEnabled(False) else: self.prev_button.setEnabled(True) def nextWord(self): #print self.maxcount if self.current < self.wordcount - 1: self.current += 1 self.showSet() self.prev_button.setEnabled(True) if self.current == self.wordcount - 1: self.next_button.setEnabled(False) self.notifier.setText( "You checked every word now. If you corrected every letter continue to next page." ) else: self.next_button.setEnabled(True) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene) def drawOCRPreview(self): factor = 1.0 img = self.prev[0] old_h = img.height() old_w = img.width() pix = img.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() self.ratio_h = old_h / float(new_h) self.ratio_w = old_w / float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) #for box in self.boxes(): # rect = self.addRect(self.scene, box, ratio_w, ratio_h, pen) # self.previewRects.append(rect) rect = self.addRect(self.scene, self.boxlist[0], self.ratio_w, self.ratio_h, pen) self.previewRects.append(rect) self.previewSetScene(self.scene) def drawSnippet(self, graphicsview, snippet): """Draw single result item to graphicsview""" try: h, w = snippet.shape except: h, w, c = snippet.shape if h < 1 or w < 1: return processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) pix = pix.scaled(graphicsview.width(), graphicsview.height() - 1, Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect((item[0]) / ratio_w, (item[2]) / ratio_h, item[1] / ratio_w, item[3] / ratio_h, pen) return rect def allBoxes(self): for i in range(self.file_list.count()): self.file_list.setCurrentRow(i) current = self.file_list.currentItem() res = self.results[i].station.name cres = self.results[i] self.charlist += list(res.value.replace(" ", "").upper()) text = res.value.replace(" ", "") imgcount = len(self.results[i].station.name.units) charcount = len(text) word = [] for j in range(imgcount): if j < charcount: char = text[j] else: char = "" unit = self.results[i].station.name.units[j] image = cres.station_img[unit[2]:unit[3] + 1, unit[0]:unit[1]] #cv2.imshow("x", image) #cv2.waitKey(0) h = res.h if len(image) > 0: if ((h * 1.0) / len(image[0])) > 3: y1 = res.y1 if y1 < 0: y1 = 0 image = cres.station_img[y1:unit[3], unit[0]:unit[1]] border = (h - len(image[0])) / 2 image = cv2.copyMakeBorder(image, 0, 0, border, border, cv2.BORDER_CONSTANT, value=(255, 255, 255)) if len(image) < h / 2.0: y1 = res.y1 if y1 < 0: y1 = 0 image = cres.station_img[y1:res.y2, unit[0]:unit[1]] border = (h - len(image[0])) / 2 image = cv2.copyMakeBorder(image, 0, 0, border, border, cv2.BORDER_CONSTANT, value=(255, 255, 255)) th, tw = image.shape if th < 1 or tw < 1: image = np.ones((10, 10, 1), dtype=np.uint8) * 255 self.imglist.append(image) word.append([image, char]) self.words.append(word) self.boundaries.append([ i, [ res.box[0] + self.stationoffset[i][0][0], res.box[1] + self.stationoffset[i][0][1], res.box[2] + self.stationoffset[i][0][0], res.box[3] + self.stationoffset[i][0][1] ] ]) for line in self.results[i].commodities: for item in line.items: if not item is None: text = item.value.replace(" ", "") imgcount = len(item.units) charcount = len(text) word = [] self.charlist += list( item.value.replace(" ", "").upper()) for j in range(imgcount): if j < charcount: char = text[j] else: char = "" unit = item.units[j] self.boxlist.append([ unit[0] + current.market_offset[0], unit[1] - unit[0], unit[2] + current.market_offset[1], unit[3] - unit[2] ]) image = cres.commodities_img[unit[2]:unit[3] + 1, unit[0]:unit[1]] h = line.h if len(image) > 0: if ((h * 1.0) / len(image[0])) > 3: y1 = line.y1 if line.y1 >= 0 else 0 if y1 < 0: y1 = 0 image = cres.commodities_img[ y1:unit[3], unit[0]:unit[1]] if image.shape[0] > 0 and image.shape[ 1] > 0: border = (h - len(image[0])) / 2 image = cv2.copyMakeBorder( image, 0, 0, border, border, cv2.BORDER_CONSTANT, value=(255, 255, 255)) if len(image) < h / 2.0: y1 = line.y1 if line.y1 >= 0 else 0 if y1 < 0: y1 = 0 image = cres.commodities_img[ y1:line.y2, unit[0]:unit[1]] if image.shape[0] > 0 and image.shape[ 1] > 0: border = (h - len(image[0])) / 2 image = cv2.copyMakeBorder( image, 0, 0, border, border, cv2.BORDER_CONSTANT, value=(255, 255, 255)) th, tw = image.shape if th < 1 or tw < 1: image = np.ones( (10, 10, 1), dtype=np.uint8) * 255 self.imglist.append(image) word.append([image, char]) self.words.append(word) self.boundaries.append([ i, [ item.box[0] + self.marketoffset[i][0][0], item.box[1] + self.marketoffset[i][0][1], item.box[2] + self.marketoffset[i][0][0], item.box[3] + self.marketoffset[i][0][1] ] ]) self.wordcount = len(self.words) #self.maxcount = len(self.imglist)/20 def setPreviewImage(self, image): """Show image in self.preview.""" #factor = self.factor.value() factor = 1.0 pix = image.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show()
class EliteOCR(QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.setupTable() self.settings = Settings(self) self.ocr_all_set = False self.color_image = None self.preview_image = None self.current_result = None self.zoom = False self.fields = [ self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply ] self.canvases = [ self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img ] #setup buttons self.add_button.clicked.connect(self.addFiles) self.remove_button.clicked.connect(self.removeFile) self.save_button.clicked.connect(self.addItemToTable) self.skip_button.clicked.connect(self.nextLine) self.ocr_button.clicked.connect(self.performOCR) self.ocr_all.clicked.connect(self.runOCRAll) self.export_button.clicked.connect(self.export) self.clear_table.clicked.connect(self.clearTable) self.zoom_button.clicked.connect(self.drawOCRPreview) QObject.connect(self.actionHow_to_use, SIGNAL('triggered()'), self.howToUse) QObject.connect(self.actionAbout, SIGNAL('triggered()'), self.About) QObject.connect(self.actionOpen, SIGNAL('triggered()'), self.addFiles) QObject.connect(self.actionPreferences, SIGNAL('triggered()'), self.openSettings) QObject.connect(self.actionCommodity_Editor, SIGNAL('triggered()'), self.openEditor) self.error_close = False if not isfile("./tessdata/big.traineddata"): QMessageBox.critical(self,"Error", "OCR training data not found!\n"+\ "Make sure tessdata directory exists and contains big.traineddata.") self.error_close = True #set up required items for nn self.training_image_dir = self.settings.app_path + "\\nn_training_images\\" self.loadPlugins() def loadPlugins(self): """Load known plugins""" #Trade Dangerous Export by gazelle (bgol) if isfile(self.settings.app_path + "\\plugins\\TD_Export\\TD_Export.py"): plugin2 = imp.load_source('TD_Export', self.settings.app_path+\ "\\plugins\\TD_Export\\TD_Export.py") self.tdexport = plugin2.TD_Export( self, self.settings.app_path.decode('windows-1252')) self.tdexport_button = QPushButton(self.centralwidget) self.tdexport_button.setText("Trade Dangerous Export") self.tdexport_button.setEnabled(False) self.horizontalLayout_2.addWidget(self.tdexport_button) self.tdexport_button.clicked.connect( lambda: self.tdexport.run(self.tableToList())) def enablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.tdexport_button.setEnabled(True) def disablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.tdexport_button.setEnabled(False) def howToUse(self): QMessageBox.about(self, "How to use", "Click \"+\" and select your screenshots. Select "+\ "multiple files by holding CTRL or add them one by one. Select one file and click "+\ "the OCR button. Check if the values have been recognised properly. Optionally "+\ "correct them and click on \"Add and Next\" to continue to next line. You can edit "+\ "the values in the table by double clicking on the entry.\n\nAfter processing one "+\ "screenshot you can "+\ "click on the next file on the list and click the ORC Button again. Should there be r"+\ "epeated entry, you can click \"Skip\" to continue to next line without adding curren"+\ "t one to the list.\n\nWhen finished click on \"Export\" to save your results.") def About(self): QMessageBox.about(self,"About", "EliteOCR\nVersion 0.3.6\n\n"+\ "Contributors:\n"+\ "Seeebek, CapCap, Gazelle\n\n"+\ "EliteOCR is capable of reading the entries in Elite: Dangerous markets screenshots.\n\n"+\ "Best results are achieved with screenshots of 3840 by 2160 pixel (4K) or more. "+\ "You can make screenshots in game by pressing F10. You find them usually in\n"+\ "C:\Users\USERNAME\Pictures\Frontier Developments\Elite Dangerous\n"+\ "Screenshots made with ALT+F10 have lower recognition rate!\n\n"+\ "Owners of Nvidia video cards can use DSR technology to increase the resolution "+\ "for screenshots and revert it back to normal without leaving the game.") def setupTable(self): """Add columns and column names to the table""" self.result_table.setColumnCount(10) self.result_table.setHorizontalHeaderLabels([ 'station', 'commodity', 'sell', 'buy', 'demand', 'dem', 'supply', 'sup', 'timestamp', 'system' ]) self.result_table.setColumnHidden(8, True) def openSettings(self): """Open settings dialog and reload settings""" settingsDialog = SettingsDialog(self.settings) settingsDialog.exec_() def openEditor(self): editorDialog = EditorDialog(self.settings) editorDialog.exec_() def addFiles(self): """Add files to the file list.""" files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir']) if files == []: return first_item = None for file in files: file1 = unicode(file).encode('windows-1252') item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) self.file_list.itemClicked.connect(self.selectFile) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) #self.cleanAllFields() #self.cleanAllSnippets() if first_item != None: self.selectFile(first_item) if self.ocr_button.isEnabled() and self.file_list.count() > 1: self.ocr_all.setEnabled(True) self.cleanAllFields() self.cleanAllSnippets() def removeFile(self): """Remove selected file from file list.""" item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.file_list.currentItem(): self.selectFile(self.file_list.currentItem()) if self.file_list.count() == 0: self.remove_button.setEnabled(False) self.ocr_button.setEnabled(False) self.zoom_button.setEnabled(False) if self.file_list.count() < 2: self.ocr_all.setEnabled(False) def selectFile(self, item): """Select clicked file and shows prewiev of the selected file.""" self.color_image = item.loadColorImage() self.preview_image = item.loadPreviewImage(self.color_image) self.ocr_all_set = False font = QFont() font.setPointSize(11) self.system_not_found.setText("") if len(item.system) == 0: self.system_not_found.setText( "System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!" ) self.system_name.setText(item.system) self.system_name.setFont(font) self.file_list.setCurrentItem(item) self.file_label.setText(item.text()) self.setPreviewImage(self.preview_image) if not item.valid_market: self.system_not_found.setText( "File was not recognized as a valid market screenshot. If the file is valid please report the issue in the forum." ) return self.remove_button.setEnabled(True) self.ocr_button.setEnabled(True) self.zoom_button.setEnabled(True) if self.file_list.count() > 1: self.ocr_all.setEnabled(True) def setPreviewImage(self, image): """Show image in self.preview.""" factor = self.factor.value() pix = image.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show() def runOCRAll(self): self.ocr_all_set = True self.performOCR() def performOCR(self): """Send image to OCR and process the results""" self.OCRline = 0 busyDialog = BusyDialog(self) busyDialog.show() QApplication.processEvents() if self.file_list.currentItem().valid_market: self.current_result = OCR(self.color_image) """ try: self.current_result = OCR(self.color_image) except: QMessageBox.critical(self,"Error", "Error while performing OCR.\nPlease report the "+\ "problem to the developers through github, sourceforge or forum and provide the "+\ "screenshot which causes the problem.") return if self.current_result.station == None: QMessageBox.critical(self,"Error", "Screenshot not recognized.\n"+\ "Make sure you use a valid screenshot from the commodieties market. Should the "+\ "problem persist, please recalibrate the OCR areas with Settings->Calibrate.") return """ self.drawOCRPreview() self.markCurrentRectangle() self.drawStationName() self.skip_button.setEnabled(True) self.save_button.setEnabled(True) self.processOCRLine() else: self.nextFile() def addItemToTable(self): """Adds items from current OCR result line to the result table.""" tab = self.result_table res_station = unicode(self.station_name.currentText()).title() row_count = tab.rowCount() self.export_button.setEnabled(True) self.enablePluginButtons() self.clear_table.setEnabled(True) #check for duplicates duplicate = False if self.settings["remove_dupli"]: for i in range(row_count): station = unicode(tab.item(i, 0).text()).title() com1 = unicode(tab.item(i, 1).text()).title() com2 = unicode(self.fields[0].currentText()).replace( ',', '').title() if station == res_station and com1 == com2: duplicate = True if not duplicate: if not self.current_result.commodities[ self.OCRline].items[0] is None: if self.current_result.commodities[ self.OCRline].items[0].confidence < 0.8: self.addCommodityToDictionary(self.name.currentText()) self.current_result.station.name.value = self.station_name.currentText( ) tab.insertRow(row_count) newitem = QTableWidgetItem( unicode(res_station).title().replace("'S", "'s")) tab.setItem(row_count, 0, newitem) for n, field in enumerate(self.fields): newitem = QTableWidgetItem( unicode(field.currentText()).replace(',', '').title()) tab.setItem(row_count, n + 1, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().timestamp) tab.setItem(row_count, 8, newitem) newitem = QTableWidgetItem(self.system_name.text()) tab.setItem(row_count, 9, newitem) tab.resizeColumnsToContents() tab.resizeRowsToContents() if self.settings['create_nn_images']: self.saveValuesForTraining() self.nextLine() def addCommodityToDictionary(self, text): try: file = open(self.settings.app_path + "\\commodities.json", 'r') file_content = file.read() comm_list = json.loads(file_content) file.close() except: comm_list = ['BEER'] comm_list.append(unicode(text)) comm_list = list(set(comm_list)) comm_list.sort() file = open(self.settings.app_path + "\\commodities.json", 'w') file.write(json.dumps(comm_list, indent=2, separators=(',', ': '))) file.close() def saveValuesForTraining(self): """Get OCR image/user values and save them away for later processing, and training neural net""" cres = self.current_result res = cres.commodities[self.OCRline] if not exists(self.training_image_dir): makedirs(self.training_image_dir) w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) for index, field, canvas, item in zip(range(0, len(self.canvases) - 1), self.fields, self.canvases, res.items): val = unicode(field.currentText()).replace(',', '') if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + val + '_' + unicode(w) + 'x' + unicode(h) +\ '-' + unicode(int(time.time())) + '-' +\ unicode(random.randint(10000, 100000)) + '.png' cv2.imwrite(imageFilepath, snippet) def nextLine(self): """Process next OCR result line.""" self.markCurrentRectangle(QPen(Qt.green)) self.OCRline += 1 if len(self.previewRects) > self.OCRline: self.markCurrentRectangle() self.processOCRLine() else: self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.ocr_all_set: self.nextFile() def nextFile(self): """OCR next file""" if self.file_list.currentRow() < self.file_list.count() - 1: self.file_list.setCurrentRow(self.file_list.currentRow() + 1) self.color_image = self.file_list.currentItem().loadColorImage() self.preview_image = self.file_list.currentItem().loadPreviewImage( self.color_image) self.performOCR() font = QFont() font.setPointSize(11) if self.OCRline == 0: if len(self.file_list.currentItem().system) > 0: self.system_not_found.setText("") self.system_name.setText( self.file_list.currentItem().system) self.system_name.setFont(font) else: self.system_name.setText("") self.system_name.setFont(font) self.system_not_found.setText( "System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!" ) self.system_name.setFocus() self.system_name.selectAll() def clearTable(self): """Empty the result table.""" self.result_table.setRowCount(0) self.clear_table.setEnabled(False) self.export_button.setEnabled(False) self.disablePluginButtons() def processOCRLine(self): """Process current OCR result line.""" if len(self.current_result.commodities) > self.OCRline: font = QFont() font.setPointSize(11) res = self.current_result.commodities[self.OCRline] if self.OCRline > 0: autofill = True else: autofill = False if self.settings["auto_fill"]: for item in res.items: if item == None: continue if not item.confidence > 0.83: autofill = False if res.items[0] is None: autofill = False if res.items[1] is None: autofill = False for field, canvas, item in zip(self.fields, self.canvases, res.items): if item != None: field.clear() field.addItems(item.optional_values) field.setEditText(item.value) field.lineEdit().setFont(font) if not (self.settings["auto_fill"] and autofill): self.setConfidenceColor(field, item) self.drawSnippet(canvas, item) else: self.cleanSnippet(canvas) self.cleanField(field) if self.settings["auto_fill"] and autofill: self.addItemToTable() def setConfidenceColor(self, field, item): c = item.confidence if c > 0.83: color = "#ffffff" if c <= 0.83 and c > 0.67: color = "#ffffbf" if c <= 0.67 and c > 0.5: color = "#fff2bf" if c <= 0.5 and c > 0.34: color = "#ffe6bf" if c <= 0.34 and c > 0.17: color = "#ffd9bf" if c <= 0.17: color = "#ffccbf" field.lineEdit().setStyleSheet("QLineEdit{background: " + color + ";}") def xdrawOCRPreview(self): """Draw processed file preview and show recognised areas.""" res = self.current_result name = res.station img = self.preview_image old_h = img.height() old_w = img.width() #pix = img.scaled(QSize(self.preview.size().width()*2,self.preview.size().height()*2), Qt.KeepAspectRatio, Qt.SmoothTransformation) pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h / float(new_h) ratio_w = old_w / float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, pen) pen = QPen(Qt.yellow) redpen = QPen(Qt.red) for line in res.commodities: if line.w < (0.02 * old_w): rect = self.addRect(self.scene, line, ratio_w, ratio_h, redpen) else: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) self.previewRects.append(rect) self.previewSetScene(self.scene) def drawOCRPreview(self): if self.current_result is None: self.setPreviewImage(self.preview_image) return factor = self.factor.value() res = self.current_result name = res.station img = self.preview_image old_h = img.height() old_w = img.width() pix = img.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h / float(new_h) ratio_w = old_w / float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, greenpen) counter = 0 for line in res.commodities: if counter < self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, greenpen) elif counter == self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, bluepen) else: if line.w < (0.02 * old_w): rect = self.addRect(self.scene, line, ratio_w, ratio_h, redpen) else: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) counter += 1 self.previewRects.append(rect) self.previewSetScene(self.scene) def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect(item.x1 / ratio_w - 3, item.y1 / ratio_h - 3, item.w / ratio_w + 7, item.h / ratio_h + 6, pen) return rect def markCurrentRectangle(self, pen=QPen(Qt.blue)): self.previewRects[self.OCRline].setPen(pen) def cutImage(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1 - 5:item.y2 + 5, item.x1 - 5:item.x2 + 5] return snippet def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) #cv2.imwrite('snippets/'+unicode(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) if graphicsview.height() < pix.height(): pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name self.station_name.addItems(name.optional_values) self.station_name.setEditText(name.value) font = QFont() font.setPointSize(11) self.station_name.lineEdit().setFont(font) self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show() def cleanAllFields(self): for field in self.fields: self.cleanField(field) self.cleanField(self.station_name) def cleanField(self, field): field.setEditText('') field.lineEdit().setStyleSheet("") field.clear() def cleanAllSnippets(self): for field in self.canvases: self.cleanSnippet(field) self.cleanSnippet(self.station_name_img) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene) def tableToList(self, allow_horizontal=False): all_rows = self.result_table.rowCount() all_cols = self.result_table.columnCount() result_list = [[ "System", "Station", "Commodity", "Sell", "Buy", "Demand", "", "Supply", "", "Date" ]] for row in xrange(0, all_rows): line = [ self.safeStrToList(self.result_table.item(row, 9).text()), self.safeStrToList(self.result_table.item(row, 0).text()), self.safeStrToList(self.result_table.item(row, 1).text()), self.safeStrToList(self.result_table.item(row, 2).text()), self.safeStrToList(self.result_table.item(row, 3).text()), self.safeStrToList(self.result_table.item(row, 4).text()), self.safeStrToList(self.result_table.item(row, 5).text()), self.safeStrToList(self.result_table.item(row, 6).text()), self.safeStrToList(self.result_table.item(row, 7).text()), self.safeStrToList(self.result_table.item(row, 8).text()) ] result_list.append(line) if self.settings['horizontal_exp'] and allow_horizontal: result_list = map(list, zip(*result_list)) return result_list def safeStrToList(self, input): try: return int(input) except: return unicode(input) def exportToCsv(self, result, file): for row in result: if len(row[0]) == 0: QMessageBox.warning( self, "No System Name", "There are rows missing system name! \nThe exported CSV file is incompatible with some tools like BPC." ) break towrite = "" for row in result: for cell in row: towrite += unicode(cell) + ";" towrite += "\n" csv_file = open(file, "w") csv_file.write(towrite) csv_file.close() def exportToOds(self, result, file): ods = newdoc(doctype='ods', filename=unicode(file)) sheet = Sheet('Sheet 1', size=(len(result) + 1, len(result[0]) + 1)) ods.sheets += sheet for i in xrange(len(result)): for j in xrange(len(result[0])): sheet[i, j].set_value(result[i][j]) ods.save() def exportToXlsx(self, result, file): wb = Workbook() ws = wb.active for i in xrange(1, len(result) + 1): for j in xrange(1, len(result[0]) + 1): ws.cell(row=i, column=j).value = result[i - 1][j - 1] wb.save(unicode(file)) def export(self): if self.settings['last_export_format'] == "": self.settings.setValue('last_export_format', "csv") self.settings.sync() if self.settings['last_export_format'] == "xlsx": filter = "Excel Workbook (*.xlsx)" elif self.settings['last_export_format'] == "ods": filter = "OpenDocument Spreadsheet (*.ods)" elif self.settings['last_export_format'] == "csv": filter = "CSV-File (*.csv)" name = self.current_result.station.name.value dir = self.settings["export_dir"] + "/" + unicode(name).title( ).replace("'S", "'s") + '.' + self.settings['last_export_format'] + '"' file = QFileDialog.getSaveFileName( self, 'Save', dir, "CSV-File (*.csv);;OpenDocument Spreadsheet (*.ods);;Excel Workbook (*.xlsx)", filter) if not file: return if file.split(".")[-1] == "csv": self.settings.setValue('last_export_format', "csv") self.settings.sync() self.exportToCsv(self.tableToList(True), file) elif file.split(".")[-1] == "ods": self.settings.setValue('last_export_format', "ods") self.settings.sync() self.exportToOds(self.tableToList(True), file) elif file.split(".")[-1] == "xlsx": self.settings.setValue('last_export_format', "xlsx") self.settings.sync() self.exportToXlsx(self.tableToList(True), file)
def displayOutput(self,image): scene = QGraphicsScene() scene.addPixmap(QPixmap.fromImage(image)) self.analysisView.setScene(scene) print 'displayOutput'
class CoLocation(QMainWindow, Ui_MainWindow): flag = True categories = {} valid_images = ["jpg","png","tga", "pgm", "jpeg"] valid_videos = ["mp4", "avi"] edge_threshold = 100 to_disp = [] def __init__(self, ): super(CoLocation, self).__init__() #initialise from the ui designed by Designer App self.setupUi(self) self.setupUi_custom() def update_categories(self): #update selected categories for radiobox in self.findChildren(QtGui.QRadioButton): self.categories[radiobox.text()] = radiobox.isChecked() def setupUi_custom(self,): self.scene = QGraphicsScene() self.scene2 = QGraphicsScene() #TODO [WEIRD PROBLEM] QPixmap needs to be called at least once with JPG image before tensorFlow, otherwise program crashes self.scene.addPixmap(QPixmap(os.getcwd()+"/demo.jpg").scaled(self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) self.graphicsView.setScene(self.scene) import Yolo_module as yolo self.classifier = yolo.YOLO_TF() #Create thread for heavy processing and tensorflow, pass the instance of itself to modify GUI self.image_thread = ImageThread(self, self.classifier) #add connect SIGNAL here self.pushButton.clicked.connect(self.selectFile) self.horizontalSlider.valueChanged.connect(self.updateLCD) self.pushButton_2.clicked.connect(self.image_thread.disp_graph) self.pushButton_3.clicked.connect(self.selectFile_from_folder) #Add blank canvas initially fig1 = Figure() self.addmpl(fig1) def updateLCD(self): #update edge_threshold variable based on slider self.edge_threshold = self.horizontalSlider.value() self.lcdNumber.display(self.edge_threshold) def selectFile(self): #Clear previous image displays self.scene.clear() self.scene2.clear() self.update_categories() filename = QFileDialog.getOpenFileName(directory = '/home/yash/Downloads/Pascal VOC 2012/samples') self.lineEdit.setText(filename) if filename.split('.')[1] in self.valid_videos: self.image_thread.temp = filename #disp_video(filename) self.image_thread.start() elif filename.split('.')[1] in self.valid_images: self.image_thread.disp_img(filename = filename) self.image_thread.disp_graph() else: print("Invalid file format") def selectFile_from_folder(self): #Read all the images in the folder path = QFileDialog.getExistingDirectory(None, 'Select a folder:', '/home/yash/Downloads/Pascal VOC 2012', QtGui.QFileDialog.ShowDirsOnly) self.lineEdit_2.setText(path) for f in os.listdir(path): #list all the files in the folder ext = f.split('.')[1] #get the file extension if ext.lower() not in self.valid_images: #check if the extension is valid for the image continue filename = path+'/'+f #create the path of the image print(filename) self.image_thread.tag_image(filename, batch = True) #clear the image regions during batch upload self.scene.clear() self.scene2.clear() self.image_thread.disp_graph(batch = True) def addmpl(self, fig): #Add figure to canvas and widget self.canvas = FigureCanvas(fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() def rmmpl(self,): #remove the canvas and widget self.mplvl.removeWidget(self.canvas) self.canvas.close()
class GeorefDialog(QDialog, Ui_GeorefDialogBase): def __init__(self, types, parent=None): super(GeorefDialog, self).__init__(parent) self.setupUi(self) # Internal variables self._closeOnDone = False self._types = {} self._georeferencer = None self._types = types self._scene = QGraphicsScene(self) self._georeferencer = Georeferencer(self) self._georeferencer.status.connect(self._updateStatus) self._georeferencer.error.connect(self._updateError) # Init the gui for group in self._types: self.typeCombo.addItem(self._types[group]['name'], group) self.typeCombo.setCurrentIndex(0) for scale in Scale.Scale: self.scaleCombo.addItem(Scale.Label[scale], scale) self.scaleCombo.setCurrentIndex(Scale.OneToTwenty) self.processButton.clicked.connect(self._process) self.saveButton.clicked.connect(self._save) self.runButton.clicked.connect(self._run) self.closeButton.clicked.connect(self._close) self.siteEdit.textChanged.connect(self._updateGeoreference) self.typeCombo.currentIndexChanged.connect(self._updateGeoreference) self.scaleCombo.currentIndexChanged.connect(self._updateGeoreference) self.numberSpin.valueChanged.connect(self._updateGeoreference) self.suffixEdit.textChanged.connect(self._updateGeoreference) self.eastSpin.valueChanged.connect(self._updateGeoreference) self.northSpin.valueChanged.connect(self._updateGeoreference) def loadImage(self, inputFile): self._setStatusLabel('load', ProcessStatus.Running) if (not inputFile.exists()): self._showStatus('ERROR: Input file not found! File path was ' + inputFile.absoluteFilePath()) self._setStatusLabel('load', ProcessStatus.Failure) return False self._inputFile = inputFile pixmap = QPixmap(self._inputFile.absoluteFilePath()) if pixmap.isNull(): self._signalError('Loading of raw image failed.') return pixmap = QPixmap(self._inputFile.absoluteFilePath()) w = pixmap.width() h = pixmap.height() self._scene.addPixmap(pixmap) self._scene.setSceneRect(QRectF(0, 0, w, h)) self.planView.setSceneView(self._scene, QRectF(0, 0, w, h)) self.headerView.setSceneView(self._scene, QRectF(0, 0, w, 200)) self.footerView.setSceneView(self._scene, QRectF(100, h - 600, w - 200, 500)) self.gcpWidget1.setScene(self._scene, 250, 100, 2) self.gcpWidget2.setScene(self._scene, 250, 3050, 2) self.gcpWidget3.setScene(self._scene, 3200, 3050, 2) self.gcpWidget4.setScene(self._scene, 3200, 100, 2) self.inputFileNameLabel.setText(self._inputFile.baseName()) drawing = Drawing(self._inputFile) if drawing.isValid(): self.siteEdit.setText(drawing.item().siteCode()) self.typeCombo.setCurrentIndex( self.typeCombo.findData(drawing.item().classCode())) self.numberSpin.setValue(int(drawing.item().itemId()) or 0) self.eastSpin.setValue(drawing.easting() or 0) self.northSpin.setValue(drawing.northing() or 0) self.suffixEdit.setText(drawing.suffix()) self._updateFileNames(drawing) self._updateGeoPoints() pointFile = self.pointFileInfo() if pointFile.exists(): self._loadGcp(pointFile.absoluteFilePath()) self._setStatusLabel('load', ProcessStatus.Success) QCoreApplication.processEvents() return True return False def _loadGcp(self, path): gc = Georeferencer.loadGcpFile(path) gcTo = Transform() for index in gc.points(): gcp = gc.point(index) if gcp.map() == self.gcpWidget1.gcp().map(): gcTo.setPoint(1, gcp) elif gcp.map() == self.gcpWidget2.gcp().map(): gcTo.setPoint(2, gcp) elif gcp.map() == self.gcpWidget3.gcp().map(): gcTo.setPoint(3, gcp) elif gcp.map() == self.gcpWidget4.gcp().map(): gcTo.setPoint(4, gcp) if gcTo.isValid() and len(gcTo.points()) == 4: self.gcpWidget1.setRaw(gcTo.point(1).raw()) self.gcpWidget2.setRaw(gcTo.point(2).raw()) self.gcpWidget3.setRaw(gcTo.point(3).raw()) self.gcpWidget4.setRaw(gcTo.point(4).raw()) def _updateGeoPoints(self): mapUnits = Scale.Factor[self.drawingScale()] local1 = QPointF(self.eastSpin.value(), self.northSpin.value() + mapUnits) local2 = QPointF(self.eastSpin.value(), self.northSpin.value()) local3 = QPointF(self.eastSpin.value() + mapUnits, self.northSpin.value()) local4 = QPointF(self.eastSpin.value() + mapUnits, self.northSpin.value() + mapUnits) if self.drawingType() == 'sec': self.gcpWidget1.setGeo(local1, QgsPoint(local1)) self.gcpWidget2.setGeo(local2, QgsPoint(local2)) self.gcpWidget3.setGeo(local3, QgsPoint(local3)) self.gcpWidget4.setGeo(local4, QgsPoint(local4)) return typ = self._type() gridLayer = typ['grid'] features = gridLayer.getFeatures() localX = gridLayer.fieldNameIndex(typ['local_x']) localY = gridLayer.fieldNameIndex(typ['local_y']) for feature in features: local = QPoint(feature.attributes()[localX], feature.attributes()[localY]) map = geometry.toPoint(feature.geometry().geometry()) if local == local1: self.gcpWidget1.setGeo(local, map) elif local == local2: self.gcpWidget2.setGeo(local, map) elif local == local3: self.gcpWidget3.setGeo(local, map) elif local == local4: self.gcpWidget4.setGeo(local, map) def _updateGeoreference(self): self._updateFileNames(self.drawing()) self._updateGeoPoints() def _updateFileNames(self, drawing): self.rawFileNameLabel.setText(drawing.baseName()) self.geoFileNameLabel.setText(drawing.baseName() + self._type()['suffix']) def _toggleUi(self, status): self.processButton.setEnabled(status) self.saveButton.setEnabled(status) self.runButton.setEnabled(status) self.closeButton.setEnabled(status) self.siteEdit.setEnabled(status) self.typeCombo.setEnabled(status) self.numberSpin.setEnabled(status) self.suffixEdit.setEnabled(status) self.eastSpin.setEnabled(status) self.northSpin.setEnabled(status) self.cropCheck.setEnabled(status) self.addToMapCheck.setEnabled(status) self.gcpWidget1.setEnabled(status) self.gcpWidget2.setEnabled(status) self.gcpWidget3.setEnabled(status) self.gcpWidget4.setEnabled(status) self.planView.setEnabled(status) if (status): self.progressBar.setRange(0, 100) else: self.progressBar.setRange(0, 0) def drawing(self): return Drawing(self.item(), self.easting(), self.northing(), self.suffix(), self.rawFileName()) def item(self): return Item(self.siteCode(), self.classCode(), self.itemId()) def siteCode(self): return self.siteEdit.text().strip() def classCode(self): return self.drawingType() def itemId(self): return unicode(self.numberSpin.value()) def drawingType(self): return self.typeCombo.itemData(self.typeCombo.currentIndex()) def drawingScale(self): return self.scaleCombo.itemData(self.scaleCombo.currentIndex()) def easting(self): return self.eastSpin.value() def northing(self): return self.northSpin.value() def suffix(self): return self.suffixEdit.text().strip() def inputFileName(self): return self.inputFileNameLabel.text().strip() def rawFileName(self): return self.rawFileNameLabel.text().strip() def rawFileInfo(self): return QFileInfo(self._type()['raw'], self.rawFileName() + '.' + self._inputFile.suffix()) def pointFileInfo(self): return QFileInfo( self._type()['raw'], self.rawFileName() + '.' + self._inputFile.suffix() + '.points') def geoFileName(self): return self.geoFileNameLabel.text().strip() def geoFileInfo(self): return QFileInfo(self._type()['geo'], self.geoFileName() + '.tif') def _type(self): return self._types[self.drawingType()] def _updateStatus(self, step, status): self._setStatusLabel(step, status) self._showStatus(Georeferencer.Label[step] + ': ' + ProcessStatus.Label[status]) if step == Georeferencer.Stop and status == ProcessStatus.Success: if self._closeOnDone: self._close() else: self._toggleUi(True) def _updateError(self, step, msg): self._setStatusLabel(step, ProcessStatus.Failure) self._showStatus(msg) self._toggleUi(True) def _showStatus(self, text): self.statusBar.showMessage(text) def _save(self): self._copyInputFile() self._saveGcp() self._close() def _copyInputFile(self): if self.inputFileName() != self.rawFileName() or self._inputFile.dir( ) != self._type()['raw']: QFile.copy(self._inputFile.absoluteFilePath(), self.rawFileInfo().absoluteFilePath()) def _saveGcp(self): gc = self._gc() if (gc.isValid()): Georeferencer.writeGcpFile(gc, self.pointFileInfo().absoluteFilePath()) def _run(self): self._runGeoreference(False) def _process(self): self._runGeoreference(True) def _close(self): if (self._georeferencer.step() == Georeferencer.Stop): self.accept() else: self.reject() def _gc(self): gc = Transform() gc.crs = self._type()['crs'] gc.setPoint(1, self.gcpWidget1.gcp()) gc.setPoint(2, self.gcpWidget2.gcp()) gc.setPoint(3, self.gcpWidget3.gcp()) gc.setPoint(4, self.gcpWidget4.gcp()) return gc def _runGeoreference(self, closeOnDone): self._closeOnDone = closeOnDone gc = self._gc() if (not gc.isValid()): self._showStatus('ERROR: Please set all 4 Ground Control Points!') return self._toggleUi(False) self._copyInputFile() QCoreApplication.processEvents() self._georeferencer.run(gc, self.rawFileInfo(), self.pointFileInfo(), self.geoFileInfo()) def _finished(self, step, status): if step == Georeferencer.Stop and status == ProcessStatus.Success and self._closeOnDone: self._close() else: self._toggleUi(True) def _setStatusLabel(self, step, status): if step == 'load': label = self.loadStatusLabel elif step == Georeferencer.Crop: label = self.cropStatusLabel elif step == Georeferencer.Translate: label = self.translateStatusLabel elif step == Georeferencer.Warp: label = self.warpStatusLabel elif step == Georeferencer.Overview: label = self.overviewStatusLabel else: return if status == ProcessStatus.Success: label.setPixmap(QPixmap(':/plugins/ark/georef/success.png')) elif status == ProcessStatus.Failure: label.setPixmap(QPixmap(':/plugins/ark/georef/failure.png')) elif status == ProcessStatus.Running: label.setPixmap(QPixmap(':/plugins/ark/georef/running.png')) else: label.setPixmap(QPixmap(':/plugins/ark/georef/unknown.png'))
class SpotguideShowImageDlg(QtGui.QDialog, FORM_CLASS): def __init__(self, theCanvas, theLayer, selFeatureIds, parent=None): super(SpotguideShowImageDlg, self).__init__(parent) self.setupUi(self) self.mTheCanvas = theCanvas self.mTheLayer = theLayer self.mSelFeatureIds = selFeatureIds self.mAllFeatureIds = [] self.highlightList = [] # members shown in graphic view. self.mScene = QGraphicsScene() self.graphicsViewShowImage.setScene(self.mScene) self.mPixmapList = [] featureIter = self.mTheLayer.getFeatures(QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry)) inti = 0 theFeature = QgsFeature() while (featureIter.nextFeature(theFeature) and inti < 512): inti += 1 self.mAllFeatureIds.append(theFeature.id()) self.spinBoxFeatureIndex.setValue(1) self.spinBoxFeatureIndex.setMinimum(1) self.spinBoxFeatureIndex.setMaximum(inti) errMsg = [''] self.initComboBoxOutlinkid() self.selectFeatureById(errMsg, self.mSelFeatureIds[0], bZoomToSelected=False) self.comboBoxOutlinkid.setFocus() self.pushButtonPrev.clicked.connect(self.onPushButtonPrev) self.pushButtonNext.clicked.connect(self.onPushButtonNext) self.connect(self.comboBoxOutlinkid, QtCore.SIGNAL('activated(QString)'), self.comboBoxOutlinkidChanged) def resizeEvent(self, event): self.showImageInGraphicsView() return def disableAllControls(self): self.pushButtonPrev.setEnabled(False) self.pushButtonPrev.setEnabled(False) self.comboBoxOutlinkid.setEnabled(False) self.textEditFeatureInfo.setEnabled(False) return def initComboBoxOutlinkid(self): while (self.comboBoxOutlinkid.count() > 0): self.comboBoxOutlinkid.removeItem(0) for oneFeatureId in self.mSelFeatureIds: featureIter = self.mTheLayer.getFeatures( QgsFeatureRequest(oneFeatureId).setFlags( QgsFeatureRequest.NoGeometry)) theFeature = QgsFeature() if featureIter.nextFeature(theFeature) == False: return if self.mIsMyFeature(theFeature): self.comboBoxOutlinkid.addItem( str(theFeature.attribute('out_link_id'))) def showFeatureDetail(self, errMsg, theFeature): strFeatureInfo = self.getFeatureInfoString(theFeature) self.textEditFeatureInfo.setText(strFeatureInfo) if self.mIsMyFeature(theFeature) == False: return errMsg = [''] pattern_dat, arrow_dat = self.getSpotguidePictures( errMsg, self.mTheLayer, theFeature) if errMsg[0] != '': #QMessageBox.information(self, "Show Spotguide", errMsg[0]) return self.mPixmapList = [] if pattern_dat is not None: patternDatParser = DatParser() patternDatParser.initFromMemory(errMsg, pattern_dat) # pattern picture patternPixmap = QPixmap() patternPixmap.loadFromData( patternDatParser.getDatContentByIndex(errMsg, 0)) self.mPixmapList.append(patternPixmap) if arrow_dat is not None: arrowDatParser = DatParser() arrowDatParser.initFromMemory(errMsg, arrow_dat) # arrow picture arrowPixmap = QPixmap() arrowPixmap.loadFromData( arrowDatParser.getDatContentByIndex(errMsg, 0)) if arrowDatParser.hasPointlist(): # draw the point list on the arrow picture vecCoors = arrowDatParser.getPointListCoordinatesByIndex( errMsg, arrowDatParser.getPointlistIndex()) if errMsg[0] != '': QMessageBox.information(self, "Show Spotguide", errMsg[0]) return with QPainter(arrowPixmap) as thePainter: for oneXYPair in vecCoors: thePainter.setPen(QPen(QColor(255, 0, 0))) thePainter.drawPoint(oneXYPair[0], oneXYPair[1]) thePainter.drawPoint(oneXYPair[0] - 1, oneXYPair[1]) thePainter.drawPoint(oneXYPair[0] + 1, oneXYPair[1]) thePainter.drawPoint(oneXYPair[0], oneXYPair[1] - 1) thePainter.drawPoint(oneXYPair[0], oneXYPair[1] + 1) # append pointlist information to the text box. strPointList = arrowDatParser.getPointListStringByIndex( errMsg, arrowDatParser.getPointlistIndex()) if errMsg[0] != '': QMessageBox.information(self, "Show Spotguide", errMsg[0]) return strTemp = self.textEditFeatureInfo.toPlainText() strTemp += """\n\npointlist:\n""" strTemp += strPointList self.textEditFeatureInfo.setText(strTemp) self.mPixmapList.append(arrowPixmap) self.showImageInGraphicsView() return def showImageInGraphicsView(self): # remove all items in member QGraphicsScene. for oneItem in self.mScene.items(): self.mScene.removeItem(oneItem) for onePixmap in self.mPixmapList: self.mScene.addPixmap( self.getPixMapSizedByWidgt(onePixmap, self.graphicsViewShowImage)) self.mScene.setSceneRect(0, 0, self.graphicsViewShowImage.width() - 5, self.graphicsViewShowImage.height() - 5) return def getFeatureInfoString(self, theFeature): fieldList = theFeature.fields() attrList = theFeature.attributes() strFeatureInfo = "field count: %d\n" % len(fieldList) for oneField, oneAttr in zip(fieldList, attrList): if isinstance(oneAttr, float): strFeatureInfo += "%s: %.0f\n" % (oneField.name(), oneAttr) else: strFeatureInfo += "%s: %s\n" % (oneField.name(), oneAttr) return strFeatureInfo # result[0] is pattern dat # result[1] is arrow dat def getSpotguidePictures(self, errMsg, layer, theFeature): try: uri = QgsDataSourceURI(layer.source()) conn = psycopg2.connect('''host='%s' dbname='%s' user='******' password='******' ''' %\ (uri.host(), uri.database(), uri.username(), uri.password())) pg = conn.cursor() # all these lane's keys must be found # if anyone is not found, a 'KeyError' exception will be thrown. in_link_id = theFeature.attribute('in_link_id') node_id = theFeature.attribute('node_id') out_link_id = theFeature.attribute('out_link_id') passlink_count = theFeature.attribute('passlink_count') pattern_id = theFeature.attribute('pattern_id') arrow_id = theFeature.attribute('arrow_id') # spotguide record filter. strFilter = '''in_link_id=%s and node_id=%s and out_link_id=%s and passlink_count=%s and pattern_id=%s and arrow_id=%s''' % \ (in_link_id, node_id, out_link_id, passlink_count, pattern_id, arrow_id) sqlcmd = \ """SET bytea_output TO escape; select pattern_dat, arrow_dat from %s where %s """ % (uri.table(), strFilter) pg.execute(sqlcmd) row = pg.fetchone() return row[0], row[1] except KeyError, kErr: errMsg[0] = """Selected feature is not a rdb spotguide feature.""" return None, None except Exception, ex: errMsg[0] = ex.message return None, None
class EliteOCR(QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.setupTable() self.settings = Settings(self) self.ocr_all_set = False self.fields = [self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply] self.canvases = [self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img] #setup buttons self.add_button.clicked.connect(self.addFiles) self.remove_button.clicked.connect(self.removeFile) self.save_button.clicked.connect(self.addItemToTable) self.skip_button.clicked.connect(self.nextLine) self.ocr_button.clicked.connect(self.performOCR) self.ocr_all.clicked.connect(self.runOCRAll) self.export_button.clicked.connect(self.exportTable) self.clear_table.clicked.connect(self.clearTable) QObject.connect(self.actionHow_to_use, SIGNAL('triggered()'), self.howToUse) QObject.connect(self.actionAbout, SIGNAL('triggered()'), self.About) QObject.connect(self.actionOpen, SIGNAL('triggered()'), self.addFiles) QObject.connect(self.actionPreferences, SIGNAL('triggered()'), self.openSettings) QObject.connect(self.actionCalibrate, SIGNAL('triggered()'), self.openCalibrate) self.error_close = False if not isfile("./tessdata/big.traineddata"): QMessageBox.critical(self,"Error", "OCR training data not found!\n"+\ "Make sure tessdata directory exists and contains big.traineddata.") self.error_close = True #set up required items for nn self.training_image_dir = self.settings.app_path +"\\nn_training_images\\" def howToUse(self): QMessageBox.about(self, "How to use", "Click \"+\" and select your screenshots. Select "+\ "multiple files by holding CTRL or add them one by one. Select one file and click "+\ "the OCR button. Check if the values have been recognised properly. Optionally "+\ "correct them and click on \"Add and Next\" to continue to next line. You can edit "+\ "the values in the table by double clicking on the entry.\n\nAfter processing one "+\ "screenshot you can "+\ "click on the next file on the list and click the ORC Button again. Should there be r"+\ "epeated entry, you can click \"Skip\" to continue to next line without adding curren"+\ "t one to the list.\n\nWhen finished click on \"Export\" to save your results to a cs"+\ "v-file(separated by ; ). CSV can be opened by most spreadsheet editors like Excel, L"+\ "ibreOffice Calc etc.") def About(self): QMessageBox.about(self,"About", "EliteOCR\nVersion 0.3.2\n\n"+\ "Contributors:\n"+\ "Seeebek, CapCap\n\n"+\ "EliteOCR is capable of reading the entries in Elite: Dangerous markets screenshots.\n\n"+\ "Best results are achieved with screenshots of 3840 by 2160 pixel (4K) or more. "+\ "You can make screenshots in game by pressing F10. You find them usually in\n"+\ "C:\Users\USERNAME\Pictures\Frontier Developments\Elite Dangerous\n"+\ "Screenshots made with ALT+F10 have lower recognition rate!\n\n"+\ "Owners of Nvidia video cards can use DSR technology to increase the resolution "+\ "for screenshots and revert it back to normal without leaving the game.") def setupTable(self): """Add columns and column names to the table""" self.result_table.setColumnCount(10) self.result_table.setHorizontalHeaderLabels(['station', 'commodity', 'sell', 'buy', 'demand', 'dem', 'supply', 'sup', 'timestamp','system']) self.result_table.setColumnHidden(8, True) def openSettings(self): """Open settings dialog and reload settings""" settingsDialog = SettingsDialog(self.settings) settingsDialog.exec_() def openCalibrate(self, dir=None): """Open calibrate dialog and reload settings""" if dir == None: image = QFileDialog.getOpenFileName(self, "Open", self.settings['screenshot_dir']) else: image = QFileDialog.getOpenFileName(self, "Open", dir) if image != "": calibrateDialog = CalibrateDialog(self, image) calibrateDialog.exec_() self.settings.sync() def addFiles(self): """Add files to the file list.""" files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir']) if files == []: return first_item = None for file in files: item = CustomQListWidgetItem(split(str(file))[1], file, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) self.file_list.itemClicked.connect(self.selectFile) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) #self.cleanAllFields() #self.cleanAllSnippets() if first_item !=None: self.selectFile(first_item) if self.ocr_button.isEnabled() and self.file_list.count() > 1: self.ocr_all.setEnabled(True) self.cleanAllFields() self.cleanAllSnippets() def removeFile(self): """Remove selected file from file list.""" item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.file_list.currentItem(): self.selectFile(self.file_list.currentItem()) if self.file_list.count() == 0: self.remove_button.setEnabled(False) self.ocr_button.setEnabled(False) if self.file_list.count() < 2: self.ocr_all.setEnabled(False) def selectFile(self, item): """Select clicked file and shows prewiev of the selected file.""" self.ocr_all_set = False self.file_list.setCurrentItem(item) self.file_label.setText(item.text()) self.setPreviewImage(item.preview_image) self.remove_button.setEnabled(True) self.ocr_button.setEnabled(True) if self.file_list.count() > 1: self.ocr_all.setEnabled(True) def setPreviewImage(self, image): """Show image in self.preview.""" pix = image.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show() def runOCRAll(self): self.ocr_all_set = True self.performOCR() def performOCR(self): """Send image to OCR and process the results""" self.OCRline = 0 busyDialog = BusyDialog(self) busyDialog.show() QApplication.processEvents() #self.current_result = OCR(self.file_list.currentItem().color_image) try: self.current_result = OCR(self.file_list.currentItem().color_image) except: QMessageBox.critical(self,"Error", "Error while performing OCR.\nPlease report the "+\ "problem to the developers through github, sourceforge or forum and provide the "+\ "screenshot which causes the problem.") return if self.current_result.station == None: QMessageBox.critical(self,"Error", "Screenshot not recognized.\n"+\ "Make sure you use a valid screenshot from the commodieties market. Should the "+\ "problem persist, please recalibrate the OCR areas with Settings->Calibrate.") return self.drawOCRPreview() self.markCurrentRectangle() self.drawStationName() self.skip_button.setEnabled(True) self.save_button.setEnabled(True) self.processOCRLine() def addItemToTable(self): """Adds items from current OCR result line to the result table.""" tab = self.result_table res_station = self.current_result.station.name.value row_count = tab.rowCount() self.export_button.setEnabled(True) self.clear_table.setEnabled(True) #check for duplicates duplicate = False if self.settings["remove_dupli"]: for i in range(row_count): station = tab.item(i, 0).text() com1 = tab.item(i, 1).text() com2 = self.fields[0].currentText().replace(',', '') if station == res_station and com1 == com2: duplicate = True if not duplicate: tab.insertRow(row_count) newitem = QTableWidgetItem(res_station) tab.setItem(row_count, 0, newitem) for n, field in enumerate(self.fields): newitem = QTableWidgetItem(str(field.currentText()).replace(',', '')) tab.setItem(row_count, n+1, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().timestamp) tab.setItem(row_count, 8, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().system) tab.setItem(row_count, 9, newitem) tab.resizeColumnsToContents() tab.resizeRowsToContents() if self.settings['create_nn_images']: self.saveValuesForTraining() self.nextLine() def saveValuesForTraining(self): """Get OCR image/user values and save them away for later processing, and training neural net""" cres = self.current_result res = cres.commodities[self.OCRline] if not exists(self.training_image_dir): makedirs(self.training_image_dir) w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) for index, field, canvas, item in zip(range(0, len(self.canvases) - 1), self.fields, self.canvases, res.items): if index in [1, 2, 3, 5]: val = str(field.currentText()).replace(',', '') if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + val + '_' + str(w) + 'x' + str(h) +\ '-' + str(int(time.time())) + '-' +\ str(random.randint(10000, 100000)) + '.png' cv2.imwrite(imageFilepath, snippet) def nextLine(self): """Process next OCR result line.""" self.markCurrentRectangle(QPen(Qt.green)) self.OCRline += 1 if len(self.previewRects) > self.OCRline: self.markCurrentRectangle() self.processOCRLine() else: self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.ocr_all_set: self.nextFile() def nextFile(self): """OCR next file""" if self.file_list.currentRow() < self.file_list.count()-1: self.file_list.setCurrentRow(self.file_list.currentRow() + 1) self.performOCR() def clearTable(self): """Empty the result table.""" self.result_table.setRowCount(0) self.clear_table.setEnabled(False) self.export_button.setEnabled(False) def processOCRLine(self): """Process current OCR result line.""" if len(self.current_result.commodities) > self.OCRline: res = self.current_result.commodities[self.OCRline] autofill = True if self.settings["auto_fill"]: for item in res.items: if item == None: continue if not item.confidence > 0.84: autofill = False for field, canvas, item in zip(self.fields, self.canvases, res.items): if item != None: field.clear() field.addItems(item.optional_values) field.setEditText(item.value) if not(self.settings["auto_fill"] and autofill): self.setConfidenceColor(field, item) self.drawSnippet(canvas, item) else: self.cleanSnippet(canvas) self.cleanField(field) if self.settings["auto_fill"] and autofill: self.addItemToTable() def setConfidenceColor(self, field, item): c = item.confidence if c > 0.84: color = "#ffffff" if c <= 0.84 and c >0.67: color = "#ffffbf" if c <= 0.67 and c >0.5: color = "#fff2bf" if c <= 0.5 and c >0.34: color = "#ffe6bf" if c <= 0.34 and c >0.17: color = "#ffd9bf" if c <= 0.17: color = "#ffccbf" field.lineEdit().setStyleSheet("QLineEdit{background: "+color+";}") def drawOCRPreview(self): """Draw processed file preview and show recognised areas.""" res = self.current_result name = res.station.name img = self.file_list.currentItem().preview_image old_h = img.height() old_w = img.width() pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h/float(new_h) ratio_w = old_w/float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) self.previewRects = [] pen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, pen) pen = QPen(Qt.yellow) for line in res.commodities: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) self.previewRects.append(rect) self.previewSetScene(self.scene) def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect((item.x1/item.scale)/ratio_w -3,(item.y1/item.scale)/ratio_h - 3, item.w/item.scale/ratio_w +7, item.h/item.scale/ratio_h +6, pen) return rect def markCurrentRectangle(self, pen=QPen(Qt.blue)): self.previewRects[self.OCRline].setPen(pen) def cutImage(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1/item.scale - 5:item.y2/item.scale + 5, item.x1/item.scale - 5:item.x2/item.scale + 5] return snippet def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) #cv2.imwrite('snippets/'+str(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) if graphicsview.height() < pix.height(): pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name self.station_name.setEditText(name.value) img = self.cutImage(res.contrast_station_img, name) processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show() def cleanAllFields(self): for field in self.fields: self.cleanField(field) self.cleanField(self.station_name) def cleanField(self, field): field.setEditText('') field.lineEdit().setStyleSheet("") field.clear() def cleanAllSnippets(self): for field in self.canvases: self.cleanSnippet(field) self.cleanSnippet(self.station_name_img) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene) def exportTable(self): res = self.current_result name = res.station.name.value dir = self.settings["export_dir"]+"/"+name.title()+'.csv"' file = QFileDialog.getSaveFileName(self, 'Save', dir) if not file: return allRows = self.result_table.rowCount() towrite = '' for row in xrange(0, allRows): line = self.result_table.item(row,0).text()+";"+\ self.result_table.item(row,1).text()+";"+\ self.result_table.item(row,2).text()+";"+\ self.result_table.item(row,3).text()+";"+\ self.result_table.item(row,4).text()+";"+\ self.result_table.item(row,5).text()+";"+\ self.result_table.item(row,6).text()+";"+\ self.result_table.item(row,7).text()+";"+\ self.result_table.item(row,8).text()+";"+\ self.result_table.item(row,9).text()+";\n" towrite += line csv_file = open(file, "w") csv_file.write(towrite) csv_file.close()
class CVViewModel(object): """docstring for View""" def __init__(self, ): super(CVViewModel, self).__init__() self.scence = QGraphicsScene() self.graphicsView.setScene(self.scence) self.beginTestCV.clicked.connect( partial(self.beginTestCV.setEnabled, False)) self.reporterCV.clicked.connect(self.writeReporterCV) self.updateCVData.clicked.connect(self.write_cv_result_to_db) # if hasattr(self,"updateOPData"): # self.updateOPData.clicked.connect(self.write_cv_result_to_db) self.updata_CV_method = update_cv_data self.db_parameters,self.pdf_parameters = config.DB_PARAMETER,config.PDF_PARAMETER self.insert_widgets() self.emit_fibertype_in_items = PyTypeSignal() self.last_save = {} self._last_data_init() self.emit_close_event = PyTypeSignal() self.to_report = ReporterPdfs def insert_widgets(self): self.relative_index_canvas = RefractCanvas(QWidget(self.extendwidget), width=5, height=2, dpi=100) self.cvOperatorLayout.insertWidget(2, self.relative_index_canvas) def _last_data_init(self): load = load_pickle_nor_json("setting\\userdata") types = load.get("fiberTypes") self.fiberTypeBox.addItems(types) # now = self.fiberTypeBox.currentText() self.emit_fibertype_in_items.emit() try: self.olddata = WriteReadJson('setting\\old.json') self.last_save = self.olddata.load() except ValueError: return if self.last_save: self.fiberLength.setText(self.last_save['fiberLength']) self.Worker.setText(self.last_save['worker']) self.factory.setText(self.last_save['producer']) self.fiberNumber.setText(self.last_save['fiberNo']) def updatePixmap(self, arr, sharp, light): height, width, bytesPerComponent = arr.shape bytesPerLine = bytesPerComponent * width img = QImage(arr.data, width, height, bytesPerLine, QImage.Format_RGB888) pximapimg = QPixmap.fromImage(img) self.scence.clear() self.scence.addPixmap(pximapimg) self.dynamicSharp.setText(sharp) self.light.setText(light) def enable_move_button(self, is_move=True): collections = ("move_down", "move_up", "next_state", "move_right", "move_left", "reset") moves = {getattr(self, c) for c in collections} for move in moves: move.setEnabled(is_move) def closeEvent(self, event, *args, **kwargs): # if 'olddata' in SETTING().keys(): # self.olddata.save(SETTING()['olddata']) logger.info('get last save\n' + str(self.last_save)) # print(self.last_save) self.olddata.save(self.last_save) self.emit_close_event.emit() super(CVViewModel, self).closeEvent(event) def updateCVShow(self, str_, ): if str_: self.resultShowCV.setText(str_) # self.resultShowCV.setStyleSheet("QTextBrowser{font-family: \"Microsoft YaHei\";}") self.beginTestCV.setEnabled(True) def writeReporterCV(self): para = {} para['fiberLength'] = str(self.fiberLength.text()) para['worker'] = str(self.Worker.text()) para['producer'] = str(self.factory.text()) para['fiberNo'] = str(self.fiberNumber.text()) para['fibertype'] = str(self.fiberTypeBox.currentText()) para['fibertypeindex'] = str(self.fiberTypeBox.currentIndex()) para['date'] = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S') para['title'] = para['fibertype'] + '光纤端面几何测试报告' self.pdf_parameters.update(para) # PDF_PARAMETER.update(para) self.last_save.update(para) self.to_report(self) # print 'get in session' self.db_parameters.update(para) # dbpara = SETTING()['dbpara'] def write_cv_result_to_db(self): para = {} para['fiberLength'] = str(self.fiberLength.text()) para['worker'] = str(self.Worker.text()) para['producer'] = str(self.factory.text()) para['fiberNo'] = str(self.fiberNumber.text()) para['fibertype'] = str(self.fiberTypeBox.currentText()) para['fibertypeindex'] = str(self.fiberTypeBox.currentIndex()) para['date'] = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S') para['sharpindex'] = float(self.dynamicSharp.text()) self.db_parameters.update(para) # session_add_by_account(DB_PARAMETER) self.updata_CV_method(self.db_parameters) # def getCoreLight(self, coreLight, cladLight): # if hasattr(self, "coreLight"): # self.coreLight.setText(coreLight) # if hasattr(self, "cladLight"): # self.cladLight.setText(cladLight) def relative_index_show(self, plots): self.relative_index_canvas.update_figure(*plots)
class CoLocation(QMainWindow, Ui_MainWindow): flag = True categories = {} valid_images = ["jpg", "png", "tga", "pgm", "jpeg"] valid_videos = ["mp4", "avi"] edge_threshold = 100 to_disp = [] stop = False framerate = 20 export_name = '' def __init__(self, ): super( CoLocation, self).__init__() #initialise from the ui designed by Designer App self.setupUi(self) self.setupUi_custom() Help = QtGui.QAction(QtGui.QIcon('images/info.png'), 'Help', self) Help.triggered.connect(self.show_help) Settings = QtGui.QAction(QtGui.QIcon('images/settings.png'), 'Settings', self) Settings.triggered.connect(self.show_settings) Export = QtGui.QAction(QtGui.QIcon('images/export.png'), 'Export', self) Export.triggered.connect(self.show_export) ##To set up the toolbar self.toolbar = self.addToolBar('Help') self.toolbar.addAction(Help) self.toolbar = self.addToolBar('Settings') self.toolbar.addAction(Settings) self.toolbar = self.addToolBar('Export') self.toolbar.addAction(Export) def show_help(self): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Co-Location Visualisation") f = open('How-To/how-to-Co-Location.txt', 'r') msg.setInformativeText( "Developed by Yash Chandak, under supervision of Prof. Babiga Birregah, University of Technology, Troyes" ) msg.setWindowTitle("About Us") msg.setDetailedText(f.read()) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() def show_settings(self): framerate, ok = QtGui.QInputDialog.getInt( self, 'Settings', 'Enter Frame Rate for Videos:') self.framerate = framerate def show_export(self): name, ok = QtGui.QInputDialog.getText(self, 'Export to Gephi format', 'Enter file name :') self.export_name = name + '.gefx' def update_categories(self): #update selected categories for radiobox in self.findChildren(QtGui.QRadioButton): self.categories[radiobox.text()] = radiobox.isChecked() def setupUi_custom(self, ): self.scene = QGraphicsScene() self.scene2 = QGraphicsScene() self.pushButton.clicked.connect(self.selectFile) self.horizontalSlider.valueChanged.connect(self.updateLCD) self.pushButton_2.clicked.connect(self.disp_graph) self.pushButton_3.clicked.connect(self.selectFile_from_folder) self.stop_button.clicked.connect(self.set_stop) #TODO [WEIRD PROBLEM] QPixmap needs to be called at least once with JPG image before tensorFlow, otherwise program crashes self.scene.addPixmap( QPixmap(os.getcwd() + "/images/demo.jpg").scaled( self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) self.graphicsView.setScene(self.scene) #Add blank canvas initially fig1 = Figure() self.addmpl(fig1) def set_stop(self): self.stop = True def updateLCD(self): #update edge_threshold variable based on slider self.edge_threshold = self.horizontalSlider.value() self.lcdNumber.display(self.edge_threshold) def tag_image(self, filename=None, batch=False, image=None): #importing TensorFlow on top causes segmentation fault (official bug #2034) #importing here helps in working around the problem #Python modules could be con)sidered as singletons... so no matter how many times they are imported, they get initialized only once import Yolo_module as yolo if (self.flag): #initialise the model, only once self.classifier = yolo.YOLO_TF() self.flag = False self.classifier.batch = batch if not image == None: self.classifier.detect_from_cvmat(image) else: self.classifier.detect_from_file( filename) #execute Yolo on the image return self.classifier.tagged_image def disp_img(self, filename=None, img=None): if not img == None: img_rgb = img.copy() cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img_rgb) img_rgb = QtGui.QImage(img_rgb, img_rgb.shape[1], img_rgb.shape[0], img_rgb.shape[1] * 3, QtGui.QImage.Format_RGB888) self.scene.addPixmap( QPixmap(img_rgb).scaled(self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) image = self.tag_image(image=img) else: #DO this step before calling tensorflow self.scene.addPixmap( QPixmap(filename).scaled(self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) #Dislplay tagged image image = self.tag_image(filename=filename) image = QtGui.QImage( image, image.shape[1], image.shape[0], image.shape[1] * 3, QtGui.QImage.Format_RGB888) #convert to Qt image format self.scene2.addPixmap( QPixmap(image).scaled(self.graphicsView_3.size(), QtCore.Qt.KeepAspectRatio)) self.graphicsView.setScene(self.scene) self.graphicsView_3.setScene(self.scene2) def disp_graph(self, result=[], graph_name=''): import graph_module as gm self.update_categories() self.rmmpl() #remove previous graph if result != [] and result != False: self.to_disp = result #Display graph fig = Figure() fig.set_facecolor('w') axf = fig.add_subplot(111) axf.set_axis_off() gm.co_location(self.to_disp, axf, self.edge_threshold, self.categories, graph_name) #get updated graph self.addmpl(fig) print("graph added") def disp_video(self, filename, skip=20): cap = cv2.VideoCapture(filename) count = 0 self.stop = False while True: #TODO: Better method - https://nikolak.com/pyqt-threading-tutorial/ QtCore.QCoreApplication.processEvents() ret, img = cap.read() if (not ret) or self.stop: print("Ending video...") #+ str(ret) + str(self.stop)) break if count % skip == 0: img = cv2.resize(img, (640, 480)) self.disp_img(img=img) self.disp_graph([self.classifier.result ]) #list of 1 resultant list count = 0 count += 1 def selectFile(self): #Clear previous image displays self.scene.clear() self.scene2.clear() self.update_categories() filename = QFileDialog.getOpenFileName( directory='/home/yash/Downloads/Pascal VOC 2012/samples') self.lineEdit.setText(filename) #check if file is valid video if filename.split('.')[1] in self.valid_videos: self.disp_video(filename, self.framerate) #check if the file is valid elif filename.split('.')[1] in self.valid_images: self.disp_img(filename=filename) self.disp_graph([self.classifier.result ]) #list of 1 resultant list else: print("Invalid file format") def selectFile_from_folder(self): #Read all the images in the folder path = QFileDialog.getExistingDirectory( None, 'Select a folder:', '/home/yash/Downloads/Pascal VOC 2012', QtGui.QFileDialog.ShowDirsOnly) self.lineEdit_2.setText(path) self.batch_results = [] for f in os.listdir(path): #list all the files in the folder ext = f.split('.')[1] #get the file extension if ext.lower( ) not in self.valid_images: #check if the extension is valid for the image continue filename = path + '/' + f #create the path of the image print(filename) self.tag_image(filename, batch=True) self.batch_results.append( self.classifier.result) #list of all resultant lists #clear the image regions during batch upload self.scene.clear() self.scene2.clear() self.disp_graph(self.batch_results, self.export_name) def addmpl(self, fig): #Add figure to canvas and widget self.canvas = FigureCanvas(fig) self.mplvl.addWidget(self.canvas) self.canvas.draw() def rmmpl(self, ): #remove the canvas and widget self.mplvl.removeWidget(self.canvas) self.canvas.close()
class QtImageViewer(QGraphicsView): """ PyQt image viewer widget for a QPixmap in a QGraphicsView scene with mouse zooming and panning. Displays a QImage or QPixmap (QImage is internally converted to a QPixmap). To display any other image format, you must first convert it to a QImage or QPixmap. Some useful image format conversion utilities: qimage2ndarray: NumPy ndarray <==> QImage (https://github.com/hmeine/qimage2ndarray) ImageQt: PIL Image <==> QImage (https://github.com/python-pillow/Pillow/blob/master/PIL/ImageQt.py) """ # Mouse button signals emit image scene (x, y) coordinates. # !!! For image (row, column) matrix indexing, row = y and column = x. hover = pyqtSignal(float, float) leftMouseButtonPressed = pyqtSignal(float, float, object) rightMouseButtonPressed = pyqtSignal(float, float) leftMouseButtonReleased = pyqtSignal(float, float) leftMouseButtonDoubleClicked = pyqtSignal(float, float) rightMouseButtonDoubleClicked = pyqtSignal(float, float) areaSelected = pyqtSignal(float, float, float, float) pixelSelected = pyqtSignal(float, float) def __init__(self, parent=None, center=None, thumbnail=False): QGraphicsView.__init__(self, parent) # Image is displayed as a QPixmap in a QGraphicsScene attached to this QGraphicsView. self.scene = QGraphicsScene() self.setScene(self.scene) # Store a local handle to the scene's current image pixmap. self._pixmapHandle = None # Image aspect ratio mode. # !!! ONLY applies to full image. Aspect ratio is always ignored when zooming. # Qt.IgnoreAspectRatio: Scale image to fit viewport. # Qt.KeepAspectRatio: Scale image to fit inside viewport, preserving aspect ratio. # Qt.KeepAspectRatioByExpanding: Scale image to fill the viewport, preserving aspect ratio. self.aspectRatioMode = Qt.KeepAspectRatio # Scroll bar behaviour. # Qt.ScrollBarAlwaysOff: Never shows a scroll bar. # Qt.ScrollBarAlwaysOn: Always shows a scroll bar. # Qt.ScrollBarAsNeeded: Shows a scroll bar only when zoomed. self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # Stack of QRectF zoom boxes in scene coordinates. self.zoomStack = [] self.dragSelect = False # Flags for enabling/disabling mouse interaction. self.canZoom = True self.canPan = True self.center = center self.thumbnail = thumbnail def hasImage(self): """ Returns whether or not the scene contains an image pixmap. """ return self._pixmapHandle is not None def clearImage(self): """ Removes the current image pixmap from the scene if it exists. """ if self.hasImage(): self.scene.removeItem(self._pixmapHandle) self.scene.clear() self._pixmapHandle = None def pixmap(self): """ Returns the scene's current image pixmap as a QPixmap, or else None if no image exists. :rtype: QPixmap | None """ if self.hasImage(): return self._pixmapHandle.pixmap() return None def image(self): """ Returns the scene's current image pixmap as a QImage, or else None if no image exists. :rtype: QImage | None """ if self.hasImage(): return self._pixmapHandle.pixmap().toImage() return None def setImage(self, image): """ Set the scene's current image pixmap to the input QImage or QPixmap. Raises a RuntimeError if the input image has type other than QImage or QPixmap. :type image: QImage | QPixmap """ if type(image) is QPixmap: pixmap = image elif type(image) is QImage: pixmap = QPixmap.fromImage(image) else: raise RuntimeError( "ImageViewer.setImage: Argument must be a QImage or QPixmap.") if self.hasImage(): self._pixmapHandle.setPixmap(pixmap) else: self._pixmapHandle = self.scene.addPixmap(pixmap) self.setSceneRect(QRectF( pixmap.rect())) # Set scene size to image size. self.updateViewer() def loadImageFromFile(self, fileName=""): """ Load an image from file. Without any arguments, loadImageFromFile() will popup a file dialog to choose the image file. With a fileName argument, loadImageFromFile(fileName) will attempt to load the specified image file directly. """ if len(fileName) == 0: if QT_VERSION_STR[0] == '4': fileName = QFileDialog.getOpenFileName(self, "Open image file.") elif QT_VERSION_STR[0] == '5': fileName, dummy = QFileDialog.getOpenFileName( self, "Open image file.") if len(fileName) and os.path.isfile(fileName): image = QImage(fileName) self.setImage(image) def updateViewer(self): """ Show current zoom (if showing entire image, apply current aspect ratio mode). """ if not self.hasImage(): return if len(self.zoomStack) and self.sceneRect().contains( self.zoomStack[-1]): self.fitInView(self.zoomStack[-1], Qt.IgnoreAspectRatio ) # Show zoomed rect (ignore aspect ratio). else: self.zoomStack = [ ] # Clear the zoom stack (in case we got here because of an invalid zoom). if self.thumbnail == True: self.fitInView( self.sceneRect(), self.aspectRatioMode ) # Show entire image (use current aspect ratio mode). def resizeEvent(self, event): """ Maintain current zoom on resize. """ self.updateViewer() def mouseMoveEvent(self, event): if self.hasImage(): scenePos = self.mapToScene(event.pos()) self.hover.emit(scenePos.x(), scenePos.y()) if event.buttons() == Qt.RightButton: self.rightMouseButtonPressed.emit(scenePos.x(), scenePos.y()) else: pass QGraphicsView.mouseMoveEvent(self, event) def mousePressEvent(self, event): """ Start mouse pan or zoom mode. """ scenePos = self.mapToScene(event.pos()) if event.button() == Qt.LeftButton: if self.canPan: self.setDragMode(QGraphicsView.ScrollHandDrag) if self.hasImage(): self.leftMouseButtonPressed.emit(scenePos.x(), scenePos.y(), self) elif event.button() == Qt.RightButton: if self.dragSelect: if self.hasImage(): self.setDragMode(QGraphicsView.RubberBandDrag) self.viewport().setCursor(QCursor(Qt.CrossCursor)) self.rightMouseButtonPressed.emit(scenePos.x(), scenePos.y()) QGraphicsView.mousePressEvent(self, event) def mouseReleaseEvent(self, event): """ Stop mouse pan or zoom mode (apply zoom if valid). """ QGraphicsView.mouseReleaseEvent(self, event) scenePos = self.mapToScene(event.pos()) if event.button() == Qt.LeftButton: self.setDragMode(QGraphicsView.NoDrag) if self.hasImage(): self.leftMouseButtonReleased.emit(scenePos.x(), scenePos.y()) elif event.button() == Qt.RightButton: self.setDragMode(QGraphicsView.NoDrag) if self.hasImage(): self.viewport().setCursor(QCursor(Qt.OpenHandCursor)) if self.dragSelect: viewBBox = self.zoomStack[-1] if len( self.zoomStack) else self.sceneRect() selectionBBox = self.scene.selectionArea().boundingRect( ).intersected(viewBBox) print(selectionBBox) self.areaSelected.emit(selectionBBox.x(), selectionBBox.y(), selectionBBox.width(), selectionBBox.height()) else: self.pixelSelected.emit(scenePos.x(), scenePos.y()) def mouseDoubleClickEvent(self, event): """ Show entire image. """ scenePos = self.mapToScene(event.pos()) if event.button() == Qt.LeftButton: self.leftMouseButtonDoubleClicked.emit(scenePos.x(), scenePos.y()) elif event.button() == Qt.RightButton: if self.canZoom: self.zoomStack = [] # Clear zoom stack. self.updateViewer() self.rightMouseButtonDoubleClicked.emit(scenePos.x(), scenePos.y()) QGraphicsView.mouseDoubleClickEvent(self, event) def wheelEvent(self, event): try: if self.thumbnail == True: return zoomInFactor = 1.2 zoomOutFactor = .8 # Zoom if event.angleDelta().y() > 0: zoomFactor = zoomInFactor else: zoomFactor = zoomOutFactor self.scale(zoomFactor, zoomFactor) # Get the new position newPos = self.mapToScene(event.pos()) self.centerOn(newPos) except Exception as e: logging.info(e) def zoomToArea(self, center, scale): if self.hasImage(): self.setTransform(QTransform()) pos = QPoint(center[0], center[1]) self.centerOn(pos) self.scale(scale, scale) def resetZoom(self): self.setTransform(QTransform()) self.fitInView(self.sceneRect(), self.aspectRatioMode ) # Show entire image (use current aspect ratio mode). def showEvent(self, event): self.resetZoom()
class EliteOCR(QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__( self) #QMainWindow.__init__(self, None, Qt.FramelessWindowHint) self.setupUi(self) self.appversion = appversion self.setupTable() self.settings = Settings(self) self.export = Export(self) self.actionPublic_Mode.setChecked(self.settings["public_mode"]) self.factor.setValue(self.settings["zoom_factor"]) self.ocr_all_set = False self.color_image = None self.preview_image = None self.current_result = None self.newupd = None self.zoom = False self.minres = 0 self.fields = [ self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply ] self.canvases = [ self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img ] #setup buttons self.add_button.clicked.connect(self.addFiles) self.remove_button.clicked.connect(self.removeFile) self.remove_all_button.clicked.connect(self.removeAllFiles) self.add_all_button.clicked.connect(self.addAllScreenshots) self.save_button.clicked.connect(self.addItemToTable) self.skip_button.clicked.connect(self.nextLine) self.continue_button.clicked.connect(self.continueOCR) self.ocr_button.clicked.connect(self.performOCR) self.ocr_all.clicked.connect(self.runOCRAll) self.export_button.clicked.connect(self.export.exportToFile) self.bpc_button.clicked.connect(self.export.bpcExport) self.eddn_button.clicked.connect(self.export.eddnExport) self.clear_table.clicked.connect(self.clearTable) self.zoom_button.clicked.connect(self.drawOCRPreview) QObject.connect(self.actionHelp, SIGNAL('triggered()'), self.openHelp) QObject.connect(self.actionUpdate, SIGNAL('triggered()'), self.openUpdate) QObject.connect(self.actionAbout, SIGNAL('triggered()'), self.About) QObject.connect(self.actionOpen, SIGNAL('triggered()'), self.addFiles) QObject.connect(self.actionPreferences, SIGNAL('triggered()'), self.openSettings) QObject.connect(self.actionPublic_Mode, SIGNAL('triggered()'), self.toggleMode) QObject.connect(self.actionCommodity_Editor, SIGNAL('triggered()'), self.openEditor) self.error_close = False #set up required items for nn self.training_image_dir = unicode( self.settings.app_path.decode( 'windows-1252')) + u"\\nn_training_images\\" self.loadPlugins() self.restorePos() self.eddnthread = EDDNExport(self) QObject.connect(self.eddnthread, SIGNAL('finished(QString)'), self.export.eddnFinished) QObject.connect(self.eddnthread, SIGNAL('update(int,int)'), self.export.eddnUpdate) self.checkupadte = self.settings["updates_check"] self.thread = Worker() self.connect(self.thread, SIGNAL("output(QString, QString)"), self.showUpdateAvailable) if self.checkupadte: self.thread.check(self.appversion) if not self.settings.reg.contains('info_accepted'): self.infoDialog = InfoDialog() self.infoDialog.exec_() else: if not self.settings['info_accepted']: self.infoDialog = InfoDialog() self.infoDialog.exec_() def showUpdateAvailable(self, dir, appversion): self.newupd = (dir, appversion) self.statusbar.showMessage( unicode( _translate( "EliteOCR", "New version of EliteOCR available: %s To download it go to Help > Update", None)) % appversion, 0) def restorePos(self): self.settings.reg.beginGroup("MainWindow") self.resize(self.settings.reg.value("size", QSize(400, 400)).toSize()) self.move(self.settings.reg.value("pos", QPoint(200, 200)).toPoint()) self.settings.reg.endGroup() def closeEvent(self, event): self.settings.reg.beginGroup("MainWindow") self.settings.reg.setValue("size", self.size()) self.settings.reg.setValue("pos", self.pos()) self.settings.reg.endGroup() self.settings.reg.setValue("public_mode", self.actionPublic_Mode.isChecked()) self.settings.reg.setValue("zoom_factor", self.factor.value()) self.settings.reg.sync() event.accept() def toggleMode(self): if self.actionPublic_Mode.isChecked(): msg = _translate( "EliteOCR", "Switching to public mode will clear the result table! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, _translate("EliteOCR", "Yes", None), _translate("EliteOCR", "No", None)) if reply == 0: self.clearTable() self.cleanAllFields() self.cleanAllSnippets() else: self.actionPublic_Mode.setChecked(False) else: msg = _translate( "EliteOCR", "Switching to private mode will disable BPC and EDDN Export! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.bpc_button.setEnabled(False) self.eddn_button.setEnabled(False) else: self.actionPublic_Mode.setChecked(True) def loadPlugins(self): """Load known plugins""" #Trade Dangerous Export by gazelle (bgol) if isfile(self.settings.app_path + "\\plugins\\TD_Export\\TD_Export.py"): plugin2 = imp.load_source('TD_Export', self.settings.app_path+\ "\\plugins\\TD_Export\\TD_Export.py") self.tdexport = plugin2.TD_Export( self, self.settings.app_path.decode('windows-1252')) self.tdexport_button = QPushButton(self.centralwidget) self.tdexport_button.setText("Trade Dangerous Export") self.tdexport_button.setEnabled(False) self.horizontalLayout_2.addWidget(self.tdexport_button) self.tdexport_button.clicked.connect(lambda: self.tdexport.run( self.export.tableToList(False, True))) def enablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.tdexport_button.setEnabled(True) def disablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.tdexport_button.setEnabled(False) def About(self): QMessageBox.about(self,"About", "EliteOCR\nVersion "+self.appversion+"\n\n"+\ "Contributors:\n"+\ "Seeebek, CapCap, Gazelle, GMib, Ph.Baumann\n\n"+\ "EliteOCR is capable of reading the entries in Elite: Dangerous markets screenshots.\n\n") def setupTable(self): """Add columns and column names to the table""" """ "self.result_table.setColumnCount(11) self.result_table.setHorizontalHeaderLabels(['station', 'commodity', 'sell', 'buy', 'demand', 'dem', 'supply', 'sup', 'timestamp','system','img_height']) """ self.result_table.setColumnHidden(8, True) self.result_table.setColumnHidden(10, True) #self.result_table.setColumnHidden(11, True) pass def openHelp(self): self.helpDialog = HelpDialog( self.settings.app_path.decode('windows-1252')) self.helpDialog.setModal(False) self.helpDialog.show() def openUpdate(self): self.updateDialog = UpdateDialog( self.settings.app_path.decode('windows-1252'), self.appversion, self.newupd) self.updateDialog.setModal(False) self.updateDialog.show() def openSettings(self): """Open settings dialog and reload settings""" settingsDialog = SettingsDialog(self.settings) settingsDialog.exec_() def openEditor(self): editorDialog = EditorDialog(self.settings) editorDialog.exec_() def addAllScreenshots(self): dir = unicode(self.settings['screenshot_dir']).encode('windows-1252') #gen = (join(dir, file).decode('windows-1252') for file in listdir(dir) if isfile(join(dir, file))) gen = [ join(dir, file).decode('windows-1252') for file in listdir(dir) if file.endswith('.bmp') ] files = [] for file in gen: files.append(file) self.addFiles(files) def addFiles(self, screenshots=None): """Add files to the file list.""" if screenshots: files = screenshots else: if self.settings["native_dialog"]: files = QFileDialog.getOpenFileNames( self, "Open", self.settings['screenshot_dir']) else: files = QFileDialog.getOpenFileNames( self, "Open", self.settings['screenshot_dir'], options=QFileDialog.DontUseNativeDialog) if files == []: return first_item = None self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(len(files)) self.progress_bar.setValue(0) counter = 0 for file in files: file1 = unicode(file).encode('windows-1252') item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) counter += 1 self.progress_bar.setValue(counter) self.progress_bar.setValue(0) self.file_list.itemClicked.connect(self.selectFile) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) #self.cleanAllFields() #self.cleanAllSnippets() if first_item != None: self.selectFile(first_item) if self.ocr_button.isEnabled() and self.file_list.count() > 1: self.ocr_all.setEnabled(True) self.cleanAllFields() self.cleanAllSnippets() def removeAllFiles(self): files = self.file_list.count() for i in xrange(files): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.zoom_button.setEnabled(False) def softRemoveFile(self): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item def removeFile(self): """Remove selected file from file list.""" item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.file_list.currentItem(): self.selectFile(self.file_list.currentItem()) if self.file_list.count() == 0: self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.zoom_button.setEnabled(False) if self.file_list.count() < 2: self.ocr_all.setEnabled(False) def selectFile(self, item): """Select clicked file and shows prewiev of the selected file.""" self.cleanAllFields() self.cleanAllSnippets() self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(20) self.progress_bar.setValue(0) self.color_image = item.loadColorImage() self.progress_bar.setValue(10) self.preview_image = item.loadPreviewImage(self.color_image, self) self.progress_bar.setValue(20) self.ocr_all_set = False font = QFont() font.setPointSize(11) self.system_not_found.setText("") if len(item.system) == 0: self.system_not_found.setText( _translate( "EliteOCR", "System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!", None)) self.system_name.setText(item.system) self.system_name.setFont(font) self.file_list.setCurrentItem(item) self.file_label.setText(item.text()) self.setPreviewImage(self.preview_image) self.remove_button.setEnabled(True) self.remove_all_button.setEnabled(True) self.continue_button.setEnabled(False) if not item.valid_market: self.system_not_found.setText( _translate( "EliteOCR", "File was not recognized as a valid market screenshot. If the file is valid please report the issue in the forum.", None)) self.progress_bar.setValue(0) return self.ocr_button.setEnabled(True) self.zoom_button.setEnabled(True) if self.file_list.count() > 1: self.ocr_all.setEnabled(True) self.progress_bar.setValue(0) def setPreviewImage(self, image): """Show image in self.preview.""" factor = self.factor.value() pix = image.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show() def runOCRAll(self): self.ocr_all_set = True self.performOCR() def performOCR(self): """Send image to OCR and process the results""" self.OCRline = 0 busyDialog = BusyDialog(self) busyDialog.show() QApplication.processEvents() if self.file_list.currentItem().valid_market: self.current_result = OCR(self, self.color_image, self.file_list.currentItem().ocr_areas, self.settings["ocr_language"], self.file_list.currentItem()) """ try: self.current_result = OCR(self.color_image) except: QMessageBox.critical(self,"Error", "Error while performing OCR.\nPlease report the "+\ "problem to the developers through github, sourceforge or forum and provide the "+\ "screenshot which causes the problem.") return if self.current_result.station == None: QMessageBox.critical(self,"Error", "Screenshot not recognized.\n"+\ "Make sure you use a valid screenshot from the commodieties market. Should the "+\ "problem persist, please recalibrate the OCR areas with Settings->Calibrate.") return """ self.drawOCRPreview() self.markCurrentRectangle() self.drawStationName() self.skip_button.setEnabled(True) self.save_button.setEnabled(True) self.processOCRLine() if self.settings['create_nn_images']: self.saveStationForTraining() else: self.nextFile() def addItemToTable(self): """Adds items from current OCR result line to the result table.""" tab = self.result_table res_station = unicode(self.station_name.currentText()).title() row_count = tab.rowCount() self.export_button.setEnabled(True) if self.actionPublic_Mode.isChecked(): self.bpc_button.setEnabled(True) self.eddn_button.setEnabled(True) self.enablePluginButtons() self.clear_table.setEnabled(True) #check for duplicates duplicate = False if self.settings["remove_dupli"]: for i in range(row_count): station = unicode(tab.item(i, 0).text()).title() com1 = unicode(tab.item(i, 1).text()).title() com2 = unicode(self.fields[0].currentText()).replace( ',', '').title() if station == res_station and com1 == com2: duplicate = True if not duplicate: self.current_result.station.name.value = self.station_name.currentText( ) tab.insertRow(row_count) newitem = QTableWidgetItem( unicode(res_station).title().replace("'S", "'s")) tab.setItem(row_count, 0, newitem) for n, field in enumerate(self.fields): newitem = QTableWidgetItem( unicode(field.currentText()).replace(',', '').title()) tab.setItem(row_count, n + 1, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().timestamp) tab.setItem(row_count, 8, newitem) newitem = QTableWidgetItem(self.system_name.text()) tab.setItem(row_count, 9, newitem) newitem = QTableWidgetItem( unicode(self.file_list.currentItem().market_width)) tab.setItem(row_count, 10, newitem) tab.resizeColumnsToContents() tab.resizeRowsToContents() if self.settings['create_nn_images']: self.saveValuesForTraining() self.nextLine() def saveValuesForTraining(self): """Get OCR image/user values and save them away for later processing, and training neural net""" cres = self.current_result res = cres.commodities[self.OCRline] if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir + "\\text"): makedirs(self.training_image_dir + "\\text") if not exists(self.training_image_dir + "\\numbers"): makedirs(self.training_image_dir + "\\numbers") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) for index, field, canvas, item in zip(range(0, len(self.canvases) - 1), self.fields, self.canvases, res.items): val = unicode(field.currentText()).replace(',', '') if field in [ self.sell, self.buy, self.demand_num, self.supply_num ]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + u'\\numbers\\' + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) elif field in [self.name]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + u'\\text\\' + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def saveStationForTraining(self): cres = self.current_result if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir + "\\text"): makedirs(self.training_image_dir + "\\text") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) snippet = self.cutImage(cres.contrast_station_img, cres.station.name) val = self.station_name.currentText() imageFilepath = self.training_image_dir + u'\\text\\' + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def cutImageForTraining(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1:item.y2, item.x1:item.x2] return snippet def continueOCR(self): if self.ocr_all_set: self.nextFile() else: if self.settings['delete_files']: print "Deleted (continueOCR 458):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() self.continue_button.setEnabled(False) def nextLine(self): """Process next OCR result line.""" self.markCurrentRectangle(QPen(Qt.green)) self.OCRline += 1 if len(self.previewRects) > self.OCRline: self.markCurrentRectangle() self.processOCRLine() else: self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.ocr_all_set: if self.settings['pause_at_end']: self.continue_button.setEnabled(True) else: self.nextFile() else: if self.settings['delete_files']: if self.settings['pause_at_end']: self.continue_button.setEnabled(True) else: print "Deleted (nextLine 486):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() def nextFile(self): """OCR next file""" if self.file_list.currentRow() < self.file_list.count() - 1: if self.settings['delete_files']: print "Deleted (nextFile 496):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() else: self.file_list.setCurrentRow(self.file_list.currentRow() + 1) self.color_image = self.file_list.currentItem().loadColorImage() self.preview_image = self.file_list.currentItem().loadPreviewImage( self.color_image, self) self.performOCR() font = QFont() font.setPointSize(11) if self.OCRline == 0: if len(self.file_list.currentItem().system) > 0: self.system_not_found.setText("") self.system_name.setText( self.file_list.currentItem().system) self.system_name.setFont(font) else: self.system_name.setText("") self.system_name.setFont(font) self.system_not_found.setText( _translate( "EliteOCR", "System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!", None)) self.system_name.setFocus() self.system_name.selectAll() else: if self.settings['delete_files']: print "Deleted (nextFile 520):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() def clearTable(self): """Empty the result table.""" self.result_table.setRowCount(0) self.clear_table.setEnabled(False) self.export_button.setEnabled(False) self.bpc_button.setEnabled(False) self.eddn_button.setEnabled(False) self.disablePluginButtons() def processOCRLine(self): """Process current OCR result line.""" if len(self.current_result.commodities) > self.OCRline: font = QFont() font.setPointSize(11) res = self.current_result.commodities[self.OCRline] if self.OCRline > 0: autofill = True else: autofill = False if self.settings["auto_fill"]: for item in res.items: if item == None: continue if not item.confidence > 0.83: autofill = False if res.items[0] is None: autofill = False if res.items[1] is None: autofill = False if self.file_list.currentItem( ).market_width < 1065 and self.actionPublic_Mode.isChecked(): autofill = False self.save_button.setEnabled(False) self.skip_button.setEnabled(True) QTimer.singleShot(1200, partial(self.save_button.setEnabled, True)) #QTimer.singleShot(1500, partial(self.skip_button.setEnabled, True)); for field, canvas, item in zip(self.fields, self.canvases, res.items): if item != None: field.clear() field.addItems(item.optional_values) field.setEditText(item.value) field.lineEdit().setFont(font) if not (self.settings["auto_fill"] and autofill): self.setConfidenceColor(field, item) self.drawSnippet(canvas, item) else: self.cleanSnippet(canvas) self.cleanField(field) if self.settings["auto_fill"] and autofill: self.addItemToTable() def setConfidenceColor(self, field, item): c = item.confidence if c > 0.83: color = "#ffffff" if c <= 0.83 and c > 0.67: color = "#ffffbf" if c <= 0.67 and c > 0.5: color = "#fff2bf" if c <= 0.5 and c > 0.34: color = "#ffe6bf" if c <= 0.34 and c > 0.17: color = "#ffd9bf" if c <= 0.17: color = "#ffccbf" field.lineEdit().setStyleSheet("QLineEdit{background: " + color + ";}") def drawOCRPreview(self): if self.current_result is None: self.setPreviewImage(self.preview_image) return factor = self.factor.value() res = self.current_result name = res.station img = self.preview_image old_h = img.height() old_w = img.width() pix = img.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h / float(new_h) ratio_w = old_w / float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, greenpen) counter = 0 for line in res.commodities: if counter < self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, greenpen) elif counter == self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, bluepen) else: if line.w < (0.02 * old_w): rect = self.addRect(self.scene, line, ratio_w, ratio_h, redpen) else: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) counter += 1 self.previewRects.append(rect) self.previewSetScene(self.scene) def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect(item.x1 / ratio_w - 3, item.y1 / ratio_h - 3, item.w / ratio_w + 7, item.h / ratio_h + 6, pen) return rect def markCurrentRectangle(self, pen=QPen(Qt.blue)): self.previewRects[self.OCRline].setPen(pen) def cutImage(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1 - 5:item.y2 + 5, item.x1 - 5:item.x2 + 5] return snippet def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) #cv2.imwrite('snippets/'+unicode(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) if graphicsview.height() < pix.height(): pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name self.station_name.clear() self.station_name.addItems(name.optional_values) self.station_name.setEditText(name.value) font = QFont() font.setPointSize(11) self.station_name.lineEdit().setFont(font) self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show() def cleanAllFields(self): for field in self.fields: self.cleanField(field) self.cleanField(self.station_name) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) def cleanField(self, field): field.setEditText('') field.lineEdit().setStyleSheet("") field.clear() def cleanAllSnippets(self): for field in self.canvases: self.cleanSnippet(field) self.cleanSnippet(self.station_name_img) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene)
class CBIR(QMainWindow, Ui_MainWindow): #class variables flag = True categories = {} classes = [ "Aeroplane", "Bicycle", "Bird", "Boat", "Bottle", "Bus", "Car", "Cat", "Chair", "Cow", "Dining Table", "Dog", "Horse", "Motorbike", "Person", "Potted plant", "Sheep", "Sofa", "Train", "Tv" ] mask = np.zeros(len(classes)) class2idx = {item: i for i, item in enumerate(classes)} valid_images = ["jpg", "png", "tga", "pgm", "jpeg"] valid_videos = ["mp4", "avi"] edge_threshold = 100 topk = 10 to_disp = [] stop = False database_path = '' thumbnail_size = 256 spacing = 40 images_per_row = 2 cached_db = {} cached_db_path = '' alpha = 16 beta = 0.8 def __init__(self, ): super( CBIR, self).__init__() #initialise from the ui designed by Designer App self.setupUi(self) self.setupUi_custom() def setupUi_custom(self, ): self.setWindowTitle('CBIR') #setup space to display selected image and it's tagged version self.scene = QGraphicsScene() self.scene2 = QGraphicsScene() #connect the buttons to their respective functions self.pushButton.clicked.connect(self.select_image) self.pushButton_2.clicked.connect(self.find_similar) self.pushButton_3.clicked.connect(self.select_database) self.horizontalSlider.valueChanged.connect(self.update_LCD) #TODO [WEIRD PROBLEM] QPixmap needs to be called at least once with JPG image before tensorFlow, otherwise program crashes self.scene.addPixmap( QPixmap(os.getcwd() + "/images/demo.jpg").scaled( self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) self.graphicsView.setScene(self.scene) #set-up toolbar items and link them to respective functions Help = QtGui.QAction(QtGui.QIcon('images/info.png'), 'Help', self) Help.triggered.connect(self.show_help) Settings = QtGui.QAction(QtGui.QIcon('images/settings.png'), 'Settings', self) Settings.triggered.connect(self.show_settings) Export = QtGui.QAction(QtGui.QIcon('images/export.png'), 'Export', self) Export.triggered.connect(self.show_export) ##To set up the toolbar self.toolbar = self.addToolBar('Help') self.toolbar.addAction(Help) self.toolbar = self.addToolBar('Settings') self.toolbar.addAction(Settings) self.toolbar = self.addToolBar('Export') self.toolbar.addAction(Export) def show_help(self): msg = QMessageBox() #setup title, main heading, about us info msg.setIcon(QMessageBox.Information) msg.setWindowTitle("About Us") msg.setText("Semantic Graph based Image matching") msg.setInformativeText( "Developed by Yash Chandak, under supervision of Prof. Babiga Birregah, University of Technology, Troyes" ) #Section for further details on how to use the software f = open('How-To/how-to-SGBIR.txt', 'r') msg.setDetailedText(f.read()) #setup return buttons msg.setStandardButtons(QMessageBox.Ok) msg.exec_() def show_settings(self): topk, ok = QtGui.QInputDialog.getInt(self, 'Settings', 'Number of results to display') self.topk = topk def show_export(self): #TODO gephi export name, ok = QtGui.QInputDialog.getText(self, 'Export to Gephi format', 'Enter file name :') self.exportname = name def select_database(self): #Read all the images in the folder path = QFileDialog.getExistingDirectory( None, 'Select a folder:', '/home/yash/Project/dataset/Pascal VOC 2012/', QtGui.QFileDialog.ShowDirsOnly) self.lineEdit_2.setText(path) self.database_path = path def update_categories(self): #update selected categories self.mask.fill(0) for radiobox in self.findChildren(QtGui.QRadioButton): self.categories[radiobox.text()] = radiobox.isChecked() if not radiobox.text() == 'All': self.mask[self.class2idx[ radiobox.text()]] = radiobox.isChecked() if self.categories.get('All', 0) == 1: self.mask.fill(1) def update_LCD(self): #update edge_threshold variable based on slider self.edge_threshold = self.horizontalSlider.value() self.lcdNumber.display(self.edge_threshold) def show_similar(self, pictures, base_dir=''): #set the table layout spacing self.tableWidget.setMinimumWidth((self.thumbnail_size + self.spacing) * self.images_per_row + (self.spacing * 2)) #set table row and column count based on similar images received rowCount = len(pictures) // self.images_per_row if len(pictures) % self.images_per_row: rowCount += 1 self.tableWidget.setRowCount(rowCount) row = -1 #set the pictures in the table cells for i, picture in enumerate(pictures): col = i % self.images_per_row if not col: row += 1 #self.tableWidget.setCellWidget(row, col, ImgWidget(imagePath = self.cached_db[picture][0], size=self.thumbnail_size)) self.tableWidget.setCellWidget( row, col, ImgWidget(imagePath=base_dir + '/' + picture, size=self.thumbnail_size)) def read_database(self): #Option to select database if self.database_path == '': print("Database file not selected") self.select_database() found = False if self.cached_db_path == self.database_path: #No need to re-read from cPickle if it's re-run on the same db found = True #Search for any pre-existing db file else: self.cached_db_path = self.database_path for file in os.listdir( self.database_path): #list all the files in the folder extension = file.split('.')[1] #get the file extension if extension.lower( ) == 'db': #check for pickled cached_db file self.cached_db = pickle.load( open(self.database_path + '/' + file, 'rb')) print("Cached database found!") found = True break #Create a new db if no exiting db is found if not found: self.cached_db = self.make_db(self.database_path) def count_diff(self, v1, v2): #alpha acts as a hyper-parameter that penalizes count differneces of #classes present only in one as compared to count differneces for classes #present in both. w = [self.alpha if i == 0 else 1 for i in v1] return np.sum(self.mask * w * np.power( (v1 - v2), 2)) #sum of weighted Squared error, masked by selected classes def loc_diff(self, query_edges, db_edges): total = 0 for e1 in query_edges: best = 99999 for e2 in db_edges: if e1[0] == e2[0]: diff = abs(e1[1] - e2[1]) best = diff if diff < best else best total += best #TODO: add the details return np.log(total) def score(self, edges, vec, db_img): #weighted score of location deifference and count difference #higher the score, higher is the difference, lesser the similarity return self.beta*self.count_diff(vec, self.cached_db['vec'][db_img]) \ + (1-self.beta)*self.loc_diff(edges, self.cached_db['edges'][db_img]) def get_vec_and_classes(self, results): #returns vector and all unique classes for the given image result. vec = np.zeros(len(self.classifier.classes)) classes_present = [] for result in results: vec[self.class2idx[result[0]]] += 1 classes_present.append(result[0]) return vec, set(classes_present) def order(self, c1, c2): #edge nodes concatenated in alphabetical order to create edge name if self.class2idx[c1] < self.class2idx[c2]: return c1 + c2 else: return c2 + c1 def get_edges_with_weights(self, results): #returns a list of (edge, weight) return [(self.order(results[i][0], results[j][0]), apx_distance(results[i], results[j])) \ for i in range(len(results)) for j in range(i, len(results))] def make_db(self, path): print("caching database..") inv_map = {c: [] for c in self.classes} edges = {} vec = {} for file in os.listdir(path): #list all the fileiles in the folder ext = file.split('.')[1] #get the file extension if ext.lower() in self.valid_images: print(file) full_path = path + '/' + file self.tag_image(filename=full_path) #store the all the edges and weights for the image edges[file] = self.get_edges_with_weights( self.classifier.result) #create the inverse map( class -> images ) v, classes_present = self.get_vec_and_classes( self.classifier.result) vec[file] = v for c in classes_present: inv_map[c].append(file) #Storage format = {dir, inv_map[class]->images, vectors[image]->vec, edges[image]->edges} cached_db = { 'dir': path, 'inv_map': inv_map, 'vec': vec, 'edges': edges } pickle.dump(cached_db, open(path + '/cache.db', 'wb')) return cached_db def find_similar(self, results): #do pattern matching on the images in retrieved cached_db #keep top 10 and display on right self.read_database() #get the edges, vector, classes_present in the query image edges = self.get_edges_with_weights(results) vec, classes_present = self.get_vec_and_classes(results) #get all the images having at least one occurence of the class present in query image imgs = set([ img for c in classes_present for img in self.cached_db['inv_map'][c] ]) #choose the topK similar images from the images retrieved from database best_matches = nsmallest(self.topk, imgs, key=lambda e: self.score(edges, vec, e)) self.show_similar(best_matches, self.cached_db['dir']) return best_matches[:5] def tag_image(self, filename=None, batch=False, image=None): #importing TensorFlow on top causes segmentation fault (official bug #2034) #importing here helps in working around the problem #Python modules could be con)sidered as singletons... so no matter how many times they are imported, they get initialized only once import Yolo_module as yolo if (self.flag): #initialise the model, only once self.classifier = yolo.YOLO_TF() self.flag = False self.classifier.batch = batch if not image == None: self.classifier.detect_from_cvmat(image) else: self.classifier.detect_from_file( filename) #execute Yolo on the image return self.classifier.tagged_image def disp_img(self, filename=None, img=None): if not img == None: img_rgb = img.copy() #convert image to PyQt display format cv2.cvtColor(img, cv2.COLOR_BGR2RGB, img_rgb) img_rgb = QtGui.QImage(img_rgb, img_rgb.shape[1], img_rgb.shape[0], img_rgb.shape[1] * 3, QtGui.QImage.Format_RGB888) self.scene.addPixmap( QPixmap(img_rgb).scaled(self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) image = self.tag_image(image=img) else: #DO this step before calling tensorflow self.scene.addPixmap( QPixmap(filename).scaled(self.graphicsView.size(), QtCore.Qt.KeepAspectRatio)) #Dislplay tagged image image = self.tag_image(filename=filename) image = QtGui.QImage( image, image.shape[1], image.shape[0], image.shape[1] * 3, QtGui.QImage.Format_RGB888) #convert to Qt image format self.scene2.addPixmap( QPixmap(image).scaled(self.graphicsView_3.size(), QtCore.Qt.KeepAspectRatio)) self.graphicsView.setScene(self.scene) self.graphicsView_3.setScene(self.scene2) def select_image(self): #Clear previous image displays self.scene.clear() self.scene2.clear() self.tableWidget.clearContents() self.update_categories( ) #update categories to incorporate any changes made #Change the file path to any default directory, as per need. filename = QFileDialog.getOpenFileName( directory='/home/yash/Project/dataset/Pascal VOC 2012/') self.lineEdit.setText(filename) if filename.split('.')[1] in self.valid_images: self.disp_img(filename=filename) self.file_tag = '/home/yash/Project/dataset/Pascal VOC 2012/report/' + ( filename.split('/')[-1]).split('.')[0] + "_" best_matches = self.find_similar(self.classifier.result) cv2.imwrite(self.file_tag + '.jpg', cv2.imread(filename, 1)) cv2.imwrite(self.file_tag + 'tagged.jpg', self.classifier.tagged_image_original) for idx, im in enumerate(best_matches): cv2.imwrite(self.file_tag + str(idx) + '.jpg', cv2.imread(self.cached_db['dir'] + '/' + im, 1)) #self.find_similar_using_vector(self.classifier.result) else: print("Invalid file format")
class EliteOCR(QMainWindow, Ui_MainWindow): def __init__(self, app): QMainWindow.__init__(self) #QMainWindow.__init__(self, None, Qt.FramelessWindowHint) self.setupUi(self) self.app = app self.settings = Settings(self) self.resizeElements() self.darkstyle = self.genDarkStyle() self.def_style = """ QWidget { font-size: 10pt; font-family: Consolas} QLineEdit { font-size: 13pt; font-family: Consolas} """ if self.settings["theme"] == "dark": self.dark_theme = True self.style = self.darkstyle else: self.dark_theme = False self.style = self.def_style self.app.setStyleSheet(self.style) self.appversion = appversion self.setupTable() self.export = Export(self) self.actionPublic_Mode.setChecked(self.settings["public_mode"]) self.factor.setValue(self.settings["zoom_factor"]) self.ocr_all_set = False self.color_image = None self.preview_image = None self.current_result = None self.newupd = None self.zoom = False self.minres = 0 self.busyDialog = None self.fields = [self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply] self.canvases = [self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img] #setup buttons self.add_button.clicked.connect(self.addFiles) self.remove_button.clicked.connect(self.removeFile) self.remove_all_button.clicked.connect(self.removeAllFiles) self.add_all_button.clicked.connect(self.addAllScreenshots) self.save_button.clicked.connect(self.addItemToTable) self.skip_button.clicked.connect(self.nextLine) self.continue_button.clicked.connect(self.continueOCR) self.ocr_button.clicked.connect(self.performOCR) self.ocr_all.clicked.connect(self.runOCRAll) self.export_button.clicked.connect(self.export.exportToFile) self.bpc_button.clicked.connect(self.export.bpcExport) self.eddn_button.clicked.connect(self.export.eddnExport) self.clear_table.clicked.connect(self.clearTable) self.zoom_button.clicked.connect(self.drawOCRPreview) QObject.connect(self.actionHelp, SIGNAL('triggered()'), self.openHelp) QObject.connect(self.actionUpdate, SIGNAL('triggered()'), self.openUpdate) QObject.connect(self.actionAbout, SIGNAL('triggered()'), self.About) QObject.connect(self.actionOpen, SIGNAL('triggered()'), self.addFiles) QObject.connect(self.actionPreferences, SIGNAL('triggered()'), self.openSettings) QObject.connect(self.actionPublic_Mode, SIGNAL('triggered()'), self.toggleMode) QObject.connect(self.actionCommodity_Editor, SIGNAL('triggered()'), self.openEditor) self.error_close = False #set up required items for nn self.training_image_dir = unicode(self.settings.app_path.decode('windows-1252'))+os.sep+u"nn_training_images"+os.sep self.loadPlugins() self.restorePos() self.eddnthread = EDDNExport(self) QObject.connect(self.eddnthread, SIGNAL('finished(QString)'), self.export.eddnFinished) QObject.connect(self.eddnthread, SIGNAL('update(int,int)'), self.export.eddnUpdate) self.thread = Worker() self.connect(self.thread, SIGNAL("output(QString, QString)"), self.showUpdateAvailable) self.thread.check(self.appversion) if not self.settings.reg.contains('info_accepted'): self.infoDialog = InfoDialog() self.infoDialog.exec_() else: if not self.settings['info_accepted']: self.infoDialog = InfoDialog() self.infoDialog.exec_() self.checkAppConfigXML() def checkAppConfigXML(self): path = unicode(self.settings['log_dir']).encode('windows-1252')+"\\..\\AppConfig.xml" if isfile(path): file = codecs.open(path, 'r', "utf-8") file_content = file.read() file.close() start = file_content.find("<Network") end = file_content.find("</Network>") position = file_content.lower().find('verboselogging="1"', start, end) if position == -1: msg = _translate("EliteOCR","You don't have \"Verbose Logging\" enabled in your AppConfig.xml. It is necessary for automatic system name recognition. Do you want EliteOCR to enable it for you?", None) reply = QMessageBox.question(self, 'Change File', msg, _translate("EliteOCR","Yes", None), _translate("EliteOCR","No", None)) if reply == 0: file = codecs.open(unicode(self.settings['log_dir']).encode('windows-1252')+"\\..\\AppConfig_backup.xml", 'w', "utf-8") file.write(file_content) file.close() newfile = file_content[:start+8] + '\n VerboseLogging="1"' + file_content[start+8:] file = codecs.open(path, 'w', "utf-8") file.write(newfile) file.close() QMessageBox.information(self,"Restart the Game", "Please restart the game to apply the change in AppConfig.xml") else: return def resizeElements(self): fields = [self.system_name, self.station_name, self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply, self.label_12, self.file_label, self.system_not_found] for field in fields: field.setMinimumSize(QSize(0, self.settings['input_size'])) field.setMaximumSize(QSize(16777215, self.settings['input_size'])) canvases = [self.station_name_img, self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img] for canvas in canvases: canvas.setMinimumSize(QSize(0, self.settings['snippet_size'])) canvas.setMaximumSize(QSize(16777215, self.settings['snippet_size'])) def genDarkStyle(self): style = """ QWidget {{ background-color: #000; font-size: 10pt; font-family: Consolas}} QLabel {{ color: {0};}} QCheckBox {{ color: {0}; }} QPushButton {{color: {2}; background-color: #000; border: 1px solid {3}; min-height: 13px; padding: 2px;}} QToolButton {{color: {2}; background-color: #000; border: 1px solid {3}; min-height: 12px; padding: 2px;}} QPushButton[enabled="false"]{{color: #555; border: 1px solid #555;}} QToolButton[enabled="false"]{{color: #555; border: 1px solid #555;}} QStatusBar {{ background-color: #000; color: {0};}} QMenuBar {{ background-color: #000; color: {0};}} QMenuBar::item {{ background-color: #000; color: {0};}} QMenuBar::item:selected {{ background-color: #888; color: {0};}} QMenu {{ background-color: #000; color: {0};}} QMenu::item {{ background-color: #000; color: {0};}} QMenu::item:selected {{ background-color: #888; color: {0};}} QListWidget {{ background-color: #000; min-width: 150px}} QFrame[frameShape="4"] {{ background-color: #888; }} QFrame[frameShape="5"] {{ background-color: #888; }} QGraphicsView {{ background-color: #000; border: 1px solid {4}}} QTableWidget {{ background-color: #000; color: {0}; border: 1px solid {4}}} QLineEdit {{ background-color: #000; border: 1px solid {4}; color: {1}; font-size: 13pt; font-family: Consolas}} QComboBox {{ background-color: #000; border: 1px solid {4}; color: {1};}} QComboBox:editable {{color: {1}; font-size: 11pt}} QComboBox::down-arrow {{ image: url(:/ico/arrow.png); }} QComboBox::drop-down:editable {{color: {1};}} QHeaderView::section {{ background-color: #000; color: {0}; border: 1px solid {4}; padding: 2px; }} QTableView QTableCornerButton::section {{ background: #000;}} QSplitter {{ background-color: #0a0; color: #a00; }} QProgressBar {{ border: 1px solid {4}; background-color: #000;}} QProgressBar::chunk {{ background-color: #0a0; width: 20px; }} QDoubleSpinBox {{ background-color: #888;}} QSpinBox {{ background-color: #888;}} QWebView {{ background-color: #888;}} QTreeView {{ color: {0}; border: 1px solid {4}}} QTabBar::tab {{ background-color: #000; color:{0}; border: 1px solid {4}; padding: 4px;}} QListView {{ color: {1}; border: 1px solid {4}}} """.format(str(self.settings['label_color']),str(self.settings['input_color']),str(self.settings['button_color']),str(self.settings['button_border_color']),str(self.settings['border_color'])) return style def showUpdateAvailable(self, dir, appversion): self.newupd = (dir, appversion) self.statusbar.showMessage(unicode(_translate("EliteOCR","New version of EliteOCR available: %s To download it go to Help > Update", None)) % appversion, 0) def restorePos(self): self.settings.reg.beginGroup("MainWindow") self.resize(self.settings.reg.value("size", QSize(400, 400)).toSize()) self.move(self.settings.reg.value("pos", QPoint(200, 200)).toPoint()) if self.settings.reg.value("maximized", False, type=bool): self.showMaximized() self.settings.reg.endGroup() def closeEvent(self, event): self.settings.reg.beginGroup("MainWindow") self.settings.reg.setValue("size", self.size()) self.settings.reg.setValue("pos", self.pos()) if self.windowState() == Qt.WindowMaximized: self.settings.reg.setValue("maximized", True) else: self.settings.reg.setValue("maximized", False) self.settings.reg.endGroup() self.settings.reg.setValue("public_mode", self.actionPublic_Mode.isChecked()) self.settings.reg.setValue("zoom_factor", self.factor.value()) self.settings.reg.sync() if not self.busyDialog is None: self.busyDialog.close() event.accept() def toggleMode(self): if self.actionPublic_Mode.isChecked(): msg = _translate("EliteOCR","Switching to public mode will clear the result table! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, _translate("EliteOCR","Yes", None), _translate("EliteOCR","No", None)) if reply == 0: self.clearTable() self.cleanAllFields() self.cleanAllSnippets() else: self.actionPublic_Mode.setChecked(False) else: msg = _translate("EliteOCR","Switching to private mode will disable BPC and EDDN Export! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.enableButton(self.bpc_button, False) self.enableButton(self.eddn_button,False) else: self.actionPublic_Mode.setChecked(True) def loadPlugins(self): """Load known plugins""" #Trade Dangerous Export by gazelle (bgol) if isfile(self.settings.app_path+os.sep+"plugins"+os.sep+"TD_Export"+os.sep+"TD_Export.py"): plugin2 = imp.load_source('TD_Export', self.settings.app_path+\ os.sep+"plugins"+os.sep+"TD_Export"+os.sep+"TD_Export.py") self.tdexport = plugin2.TD_Export(self, self.settings.app_path.decode('windows-1252')) self.tdexport_button = QPushButton(self.centralwidget) self.tdexport_button.setText("Trade Dangerous Export") self.enableButton(self.tdexport_button, False) self.horizontalLayout_4.addWidget(self.tdexport_button) self.tdexport_button.clicked.connect(lambda: self.tdexport.run(self.export.tableToList(False, True))) def enablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.enableButton(self.tdexport_button, True) def disablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.enableButton(self.tdexport_button, False) def About(self): QMessageBox.about(self,"About", "EliteOCR\nVersion "+self.appversion+"\n\n"+\ "Contributors:\n"+\ "Seeebek, CapCap, Gazelle, GMib, Ph.Baumann\n\n"+\ "EliteOCR is capable of reading the entries in Elite: Dangerous markets screenshots.\n\n") def setupTable(self): """Add columns and column names to the table""" """ "self.result_table.setColumnCount(11) self.result_table.setHorizontalHeaderLabels(['station', 'commodity', 'sell', 'buy', 'demand', 'dem', 'supply', 'sup', 'timestamp','system','img_height']) """ self.result_table.setColumnHidden(8, True) self.result_table.setColumnHidden(10, True) #self.result_table.setColumnHidden(11, True) pass def openHelp(self): self.helpDialog = HelpDialog(self.settings.app_path.decode('windows-1252')) self.helpDialog.setModal(False) self.helpDialog.show() def openUpdate(self): self.updateDialog = UpdateDialog(self.settings.app_path.decode('windows-1252'), self.appversion, self.newupd) self.updateDialog.setModal(False) self.updateDialog.show() def openSettings(self): """Open settings dialog and reload settings""" settingsDialog = SettingsDialog(self.settings) settingsDialog.exec_() if self.settings["theme"] == "dark": self.dark_theme = True self.darkstyle = self.genDarkStyle() self.style = self.darkstyle else: self.dark_theme = False self.style = self.def_style #self.app.setStyleSheet("") self.app.setStyleSheet(self.style) self.resizeElements() def openEditor(self): editorDialog = EditorDialog(self.settings) editorDialog.exec_() def addAllScreenshots(self): dir = unicode(self.settings['screenshot_dir']).encode('windows-1252') #gen = (join(dir, file).decode('windows-1252') for file in listdir(dir) if isfile(join(dir, file))) gen = [join(dir, file).decode('windows-1252') for file in listdir(dir) if file.endswith('.bmp')] files = [] for file in gen: files.append(file) self.addFiles(files) def addFiles(self, screenshots = None): """Add files to the file list.""" if screenshots: files = screenshots else: if self.settings["native_dialog"]: files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir']) else: files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir'], options = QFileDialog.DontUseNativeDialog) if files == []: return first_item = None self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(len(files)) self.progress_bar.setValue(0) counter = 0 for file in files: file1 = unicode(file).encode('windows-1252') item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) counter+=1 self.progress_bar.setValue(counter) self.progress_bar.setValue(0) self.file_list.itemClicked.connect(self.selectFile) self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) #self.cleanAllFields() #self.cleanAllSnippets() if first_item !=None: self.selectFile(first_item) if self.ocr_button.isEnabled() and self.file_list.count() > 1: self.enableButton(self.ocr_all, True) self.cleanAllFields() self.cleanAllSnippets() def removeAllFiles(self): files = self.file_list.count() for i in xrange(files): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.enableButton(self.zoom_button, False) def softRemoveFile(self): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item def removeFile(self): """Remove selected file from file list.""" item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) self.cleanAllFields() self.cleanAllSnippets() if self.file_list.currentItem(): self.selectFile(self.file_list.currentItem()) if self.file_list.count() == 0: self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.enableButton(self.zoom_button, False) if self.file_list.count() < 2: self.enableButton(self.ocr_all, False) def selectFile(self, item): """Select clicked file and shows prewiev of the selected file.""" self.cleanAllFields() self.cleanAllSnippets() self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(20) self.progress_bar.setValue(0) self.color_image = item.loadColorImage() self.progress_bar.setValue(10) self.preview_image = item.loadPreviewImage(self.color_image, self) self.progress_bar.setValue(20) self.ocr_all_set = False #font = QFont("Consolas", 11) self.system_not_found.setText("") if len(item.system) == 0: self.system_not_found.setText(_translate("EliteOCR","System name not found in log files. Please read Help for more info.", None)) self.system_name.setText(item.system) if not item.station is None: self.station_name.setText(item.station) #self.system_name.setFont(font) self.file_list.setCurrentItem(item) self.file_label.setText(item.text()) self.setPreviewImage(self.preview_image) self.remove_button.setEnabled(True) self.remove_all_button.setEnabled(True) self.enableButton(self.continue_button, False) if not item.valid_market: self.system_not_found.setText(_translate("EliteOCR","File was not recognized as a valid market screenshot. Please read Help for more info.", None)) self.progress_bar.setValue(0) return self.ocr_button.setEnabled(True) self.enableButton(self.zoom_button, True) if self.file_list.count() > 1: self.enableButton(self.ocr_all, True) self.progress_bar.setValue(0) def setPreviewImage(self, image): """Show image in self.preview.""" factor = self.factor.value() pix = image.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show() def runOCRAll(self): self.ocr_all_set = True self.performOCR() def performOCR(self): """Send image to OCR and process the results""" self.OCRline = 0 self.busyDialog = BusyDialog(self) self.busyDialog.show() QApplication.processEvents() if self.file_list.currentItem().valid_market: self.current_result = OCR(self, self.color_image, self.file_list.currentItem().ocr_areas, self.settings["ocr_language"], self.file_list.currentItem()) self.busyDialog.close() """ try: self.current_result = OCR(self.color_image) except: QMessageBox.critical(self,"Error", "Error while performing OCR.\nPlease report the "+\ "problem to the developers through github, sourceforge or forum and provide the "+\ "screenshot which causes the problem.") return if self.current_result.station == None: QMessageBox.critical(self,"Error", "Screenshot not recognized.\n"+\ "Make sure you use a valid screenshot from the commodieties market. Should the "+\ "problem persist, please recalibrate the OCR areas with Settings->Calibrate.") return """ if len(self.current_result.commodities) < 1: QMessageBox.critical(self,"Error", "No results found!\nYou might be using an unsupported HUD color. Please read help for more information.") return self.drawOCRPreview() self.markCurrentRectangle() self.drawStationName() self.skip_button.setEnabled(True) self.enableButton(self.save_button, True) self.processOCRLine() self.system_name.setFocus() if self.settings['create_nn_images']: self.saveStationForTraining() else: self.nextFile() def addItemToTable(self): """Adds items from current OCR result line to the result table.""" tab = self.result_table res_station = unicode(self.station_name.text()).title() row_count = tab.rowCount() self.export_button.setEnabled(True) if self.actionPublic_Mode.isChecked(): self.bpc_button.setEnabled(True) self.eddn_button.setEnabled(True) self.enablePluginButtons() self.enableButton(self.clear_table, True) # check if no stock and not purchased if self.demand_num.text() == "" and self.supply_num.text() == "": self.nextLine() return #check for duplicates duplicate = False if self.settings["remove_dupli"]: for i in range(row_count): station = unicode(tab.item(i, 0).text()).title() com1 = unicode(tab.item(i, 1).text()).title() com2 = unicode(self.fields[0].text()).replace(',', '').title() if station == res_station and com1 == com2: duplicate = True if not duplicate: self.current_result.station.name.value = self.station_name.text() tab.insertRow(row_count) newitem = QTableWidgetItem(unicode(res_station).title().replace("'S", "'s")) tab.setItem(row_count, 0, newitem) for n, field in enumerate(self.fields): newitem = QTableWidgetItem(unicode(field.text()).replace(',', '').title()) tab.setItem(row_count, n+1, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().timestamp) tab.setItem(row_count, 8, newitem) newitem = QTableWidgetItem(self.system_name.text()) tab.setItem(row_count, 9, newitem) newitem = QTableWidgetItem(unicode(self.file_list.currentItem().market_width)) tab.setItem(row_count, 10, newitem) tab.resizeColumnsToContents() tab.resizeRowsToContents() if self.settings['create_nn_images']: self.saveValuesForTraining() self.nextLine() def saveValuesForTraining(self): """Get OCR image/user values and save them away for later processing, and training neural net""" cres = self.current_result res = cres.commodities[self.OCRline] if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir+os.sep+"text"): makedirs(self.training_image_dir+os.sep+"text") if not exists(self.training_image_dir+os.sep+"numbers"): makedirs(self.training_image_dir+os.sep+"numbers") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) for index, field, canvas, item in zip(range(0, len(self.canvases) - 1), self.fields, self.canvases, res.items): val = unicode(field.text())#.replace(',', '') if field in [self.sell, self.buy, self.demand_num, self.supply_num]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + os.sep + u'numbers' + os.sep + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) elif field in [self.name]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + os.sep + u'text' + os.sep + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def saveStationForTraining(self): cres = self.current_result if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir+os.sep+"text"): makedirs(self.training_image_dir+os.sep+"text") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) snippet = self.cutImage(cres.contrast_station_img, cres.station.name) val = self.station_name.text() imageFilepath = self.training_image_dir + os.sep + u'text' + os.sep + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def cutImageForTraining(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1:item.y2, item.x1:item.x2] return snippet def continueOCR(self): if self.ocr_all_set: self.nextFile() else: if self.settings['delete_files']: print "Deleted (continueOCR 458):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() self.enableButton(self.continue_button, False) def nextLine(self): """Process next OCR result line.""" self.markCurrentRectangle(QPen(Qt.green)) self.OCRline += 1 if len(self.previewRects) > self.OCRline: self.markCurrentRectangle() self.processOCRLine() self.name.setFocus() else: self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) self.cleanAllFields() self.cleanAllSnippets() if self.ocr_all_set: if self.settings['pause_at_end']: self.enableButton(self.continue_button, True) else: self.nextFile() else: if self.settings['delete_files']: if self.settings['pause_at_end']: self.enableButton(self.continue_button, True) else: print "Deleted (nextLine 486):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() def nextFile(self): """OCR next file""" if self.file_list.currentRow() < self.file_list.count()-1: if self.settings['delete_files']: print "Deleted (nextFile 496):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() else: self.file_list.setCurrentRow(self.file_list.currentRow() + 1) self.color_image = self.file_list.currentItem().loadColorImage() self.preview_image = self.file_list.currentItem().loadPreviewImage(self.color_image, self) self.performOCR() #font = QFont("Consolas", 11) if self.OCRline == 0: if len(self.file_list.currentItem().system) > 0: self.system_not_found.setText("") self.system_name.setText(self.file_list.currentItem().system) if not self.file_list.currentItem().station is None: self.station_name.setText(self.file_list.currentItem().station) #self.system_name.setFont(font) else: self.system_name.setText("") #self.system_name.setFont(font) self.system_not_found.setText(_translate("EliteOCR","System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!",None)) #self.system_name.setFocus() #self.system_name.selectAll() else: if self.settings['delete_files']: print "Deleted (nextFile 520):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() def clearTable(self): """Empty the result table.""" self.result_table.setRowCount(0) self.clear_table.setEnabled(False) self.export_button.setEnabled(False) self.bpc_button.setEnabled(False) self.enableButton(self.eddn_button, False) self.disablePluginButtons() def processOCRLine(self): """Process current OCR result line.""" if len(self.current_result.commodities) > self.OCRline: #font = QFont("Consolas", 11) res = self.current_result.commodities[self.OCRline] if self.OCRline > 0: autofill = True else: autofill = False if self.settings["auto_fill"]: for item in res.items: if item == None: continue if not item.confidence > 0.83: autofill = False if res.items[0] is None: autofill = False if res.items[1] is None: autofill = False if self.file_list.currentItem().market_width < 1065 and self.actionPublic_Mode.isChecked(): autofill = False self.save_button.setEnabled(False) self.enableButton(self.skip_button, True) QTimer.singleShot(1200, partial(self.enableButton, self.save_button, True)); #QTimer.singleShot(1500, partial(self.skip_button.setEnabled, True)); for field, canvas, item in zip(self.fields, self.canvases, res.items): if item != None: #field.clear() #field.addItems(item.optional_values) field.setText(item.value) #field.lineEdit().setFont(font) if not(self.settings["auto_fill"] and autofill): self.setConfidenceColor(field, item) self.drawSnippet(canvas, item) else: self.cleanSnippet(canvas) self.cleanField(field) if self.settings["auto_fill"] and autofill: self.addItemToTable() def setConfidenceColor(self, field, item): c = item.confidence #c = random.random() if self.dark_theme: if c > 0.83: color = "#000" if c <= 0.83 and c >0.67: color = "#666600" if c <= 0.67 and c >0.5: color = "#665100" if c <= 0.5 and c >0.34: color = "#663e00" if c <= 0.34 and c >0.17: color = "#662900" if c <= 0.17: color = "#661500" else: if c > 0.83: color = "#ffffff" if c <= 0.83 and c >0.67: color = "#ffffbf" if c <= 0.67 and c >0.5: color = "#fff2bf" if c <= 0.5 and c >0.34: color = "#ffe6bf" if c <= 0.34 and c >0.17: color = "#ffd9bf" if c <= 0.17: color = "#ffccbf" field.setStyleSheet("background: "+color+";") def drawOCRPreview(self): if self.current_result is None: self.setPreviewImage(self.preview_image) return factor = self.factor.value() res = self.current_result name = res.station img = self.preview_image old_h = img.height() old_w = img.width() pix = img.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h/float(new_h) ratio_w = old_w/float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, greenpen) counter = 0 for line in res.commodities: if counter < self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, greenpen) elif counter == self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, bluepen) else: if line.w < (0.02*old_w): rect = self.addRect(self.scene, line, ratio_w, ratio_h, redpen) else: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) counter += 1 self.previewRects.append(rect) self.previewSetScene(self.scene) def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect(item.x1/ratio_w -3, item.y1/ratio_h -3, item.w/ratio_w +7, item.h/ratio_h +6, pen) return rect def markCurrentRectangle(self, pen=QPen(Qt.blue)): self.previewRects[self.OCRline].setPen(pen) def cutImage(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1 - 5:item.y2 + 5, item.x1 - 5:item.x2 + 5] return snippet def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) if self.dark_theme: snippet = 255 - snippet #cv2.imwrite('snippets/'+unicode(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) pix = pix.scaled(graphicsview.width(), graphicsview.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name #self.station_name.setText('') #self.station_name.clear() #self.station_name.addItems(name.optional_values) if not self.file_list.currentItem().station is None: self.station_name.setText(self.file_list.currentItem().station) else: self.station_name.setText(name.value) #font = QFont("Consolas", 11) #self.station_name.lineEdit().setFont(font) #self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) if self.dark_theme: img = 255 - img processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show() def cleanAllFields(self): for field in self.fields: self.cleanField(field) self.cleanField(self.station_name) self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) def cleanField(self, field): field.setText('') if self.dark_theme: field.setStyleSheet("background: #000;") else: field.setStyleSheet("background: #fff;") #field.lineEdit().setStyleSheet("") #field.clear() def cleanAllSnippets(self): for field in self.canvases: self.cleanSnippet(field) self.cleanSnippet(self.station_name_img) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene) def enableButton(self, button, switch): button.setEnabled(switch) if self.dark_theme: self.app.setStyleSheet("") self.app.setStyleSheet(self.style) self.repaint()
class Printer(object): """For printing in diferent card formats and sizes the associated deck, be it to the screen or pdfs or image files""" card_sizes = {"Jumbo":(3.5,5.5), "Tarot":(2.75,4.75), "Square":(3.5,3.5), "Poker":(2.5,3.5), "Bridge":(2.25,3.5), "Biz":(2,3.5), "Mini":(1.75,2.5), "Micro":(1.25,1.75)} paper_sizes = {"A0":(33.1,46.8), "A1":(23.4,33.1), "A2":(16.5,23.4), "A3":(11.7,16.5), "A4":(8.3,11.7), "A5":(5.8,8.3), "A6":(4.1,5.8)} #TODO paper margins when printing and centering the images def __init__(self, deck=None): self.deck = deck self.scene = QGraphicsScene() self.orientation = getattr(QPrinter, "Portrait") self.path = "output.pdf" self.paper = getattr(QPrinter, "A4") self.card_size = Printer.card_sizes["Poker"] def config(self, *args, **kwargs): """kwargs: deck, card_size, paper_size, orientation, print_path if card_size is present I have to join the elements of the deck following the premises""" if "orientation" in kwargs: self.orientation = kwargs["orientation"] if "card_size" in kwargs: self.card_size = Printer.card_sizes[kwargs["card_size"][:kwargs["card_size"].find(" ")]] if "print_path" in kwargs: self.path = kwargs["print_path"] if "paper_size" in kwargs: self.paper = kwargs["paper_size"] if "deck" in kwargs: self.deck = kwargs["deck"] def print_grid(self): if self.deck is not None: #Setting the printer printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(getattr(QPrinter, self.orientation)) printer.setOutputFileName(self.path) printer.setPaperSize(getattr(QPrinter, self.paper)) #Start printing with QPainter(printer) as paint: first = True for c in self.deck: if not first: printer.newPage() first = False self.preview_card(c) self.scene.render(paint) def max_cards(self): """Taking in count the card_size, paper_size returns the max number of cards per page, horientation and margins""" port = {} port["orientation"] = "Portrait" pw = self.paper_sizes[self.paper][0] ph = self.paper_sizes[self.paper][1] port["horizontal"] = int(pw//self.card_size[0]) port["vertical"] = int(ph//self.card_size[1]) port["max"] = port["horizontal"] * port["vertical"] port["margin_horizontal"] = (pw % self.card_size[0]) / 2.0 port["margin_vertical"] = (ph % self.card_size[1]) / 2.0 land = {} land["orientation"] = "Landscape" pw = self.paper_sizes[self.paper][1] ph = self.paper_sizes[self.paper][0] land["horizontal"] = int(pw//self.card_size[0]) land["vertical"] = int(ph//self.card_size[1]) land["max"] = land["horizontal"] * land["vertical"] land["margin_horizontal"] = (pw % self.card_size[0]) / 2.0 land["margin_vertical"] = (ph % self.card_size[1]) / 2.0 if land["max"] > port["max"]: return land else: return port def print_pdf(self): if self.deck is not None: #Setting the printer printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOrientation(getattr(QPrinter, "Portrait")) printer.setOutputFileName(self.path) printer.setPaperSize(getattr(QPrinter, self.paper)) printer.setFullPage(True) guide = self.max_cards() printer.setOrientation(getattr(QPrinter, guide["orientation"])) print guide, self.card_size #Start printing with QPainter(printer) as paint: ind = 0 resol = printer.resolution() for c in self.deck: c.resize(self.card_size[0], self.card_size[1]) if ind == guide["max"]: printer.newPage() ind = 0 col = ind % guide["horizontal"] fil = ind // guide["horizontal"] print ind, fil, col target = QRectF((col)*self.card_size[0]*resol, (fil)*self.card_size[1]*resol, self.card_size[0]*resol, self.card_size[1]*resol) self.preview_card(c) self.scene.render(paint, target=target, source=QRectF(0,0,c.width(),c.height())) ind += 1 def save_images(self): if self.deck is not None: num = 1 for c in self.deck: c.save_as("".join([str(self.path),str(num),".",c.format()])) num += 1 def preview_card(self, card): try: self.scene.clear() ret = self.scene.addPixmap(card.pixmap()) except: self.scene.clear() ret = self.scene.addText("Image not available") return ret
class ToastWidget(QGraphicsView): """ A widget to create toast messages to the user A friendly interface messages. (include image, and visual effects as blinking, fade etc) """ def __init__(self, parent=None, back_image=None, width=100, heigth=100): super(ToastWidget, self).__init__(parent) self.setWindowFlags(Qt.SplashScreen) self.scene = QGraphicsScene(self) self.timer = QTimer(self) self.setScene(self.scene) self.set_image(back_image) self.setGeometry(QRect(self.x(), self.y(), width, heigth)) self.show() def set_image(self, image): if image is None: return if not isinstance(image, QPixmap): raise Exception("Image must be of type QPixmap") self.scene.clear() self.scene.addPixmap(image.scaled(95, 95)) def move_random(self, x1=0, x2=1300, y1=0, y2=768): x, y = random.randrange(x1, x2), random.randrange(y1, y2) self.setGeometry(QRect(x, y, 100, 100)) return self def blink(self, time_limit=1000, time_interval=500): def _blink(): self.setWindowOpacity(1 - self.windowOpacity()) # self.timer.stop() # self.timer.setInterval(time_interval) # self.timer.timeout.connect(_blink) # self.timer.start_limited(time_interval, time_limit / time_interval) return self def fade(self, time=1500): """ :param time: the time to completely execute the fade in ms :param out: fade out or in. out by default """ steps = 100 self.timer.stop() self.setWindowOpacity(1) self.timer.timeout.connect( lambda: self.setWindowOpacity(self.windowOpacity() - 1.0 / steps)) self.timer.start(time * 1.0 / steps) # QTimer.singleShot(time, lambda: self.timer.stop()) return self def disappear(self, time=1000): """ """ self.timer.stop() self.setWindowOpacity(1) self.timer.singleShot(time, lambda: self.setWindowOpacity(0)) return self def vibrate(self, time_limit=1000): geometry = self.geometry() x, y = geometry.x(), geometry.y() def _move(): self.setGeometry( QRect(x + random.randrange(-3, 3), y + random.randrange(-3, 3), geometry.width(), geometry.height())) return self
class PreView(QGraphicsView): def __init__(self): QGraphicsView.__init__(self) self.zoom = 2 self.scale(self.zoom, self.zoom) self.lastSize = 0 self.setDragMode(QGraphicsView.ScrollHandDrag) # self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.installEventFilter(self) self.hudLayout = QVBoxLayout(self) self.hudLayout.setContentsMargins(0, 0, 0, 0) self.ellipseLabel = QLabel() self.ellipseLabel.setMinimumWidth(self.width()) self.hudLayout.addWidget(self.ellipseLabel) self.ellipseLabel.setAttribute(Qt.WA_TransparentForMouseEvents, True) def setPreviewImage(self, previewImage): self.grscene = QGraphicsScene() pixmapImage = QPixmap(previewImage) self.grscene.addPixmap(pixmapImage) self.setScene(self.grscene) def eventFilter(self, obj, event): if (event.type() == QEvent.Resize): self.ellipseLabel.setMinimumWidth(self.width()) self.updateFilledCircle(self.lastSize) return False def sizeHint(self): return QSize(200, 200) def setFilledBrsuh(self, size): self.updateFilledCircle(size) def updateCircle(self, s): size = s * self.zoom pixmap = QPixmap(self.width(), self.height()) pixmap.fill(Qt.transparent) #painter ellipse 1 painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing) pen = QPen(Qt.red) pen.setWidth(3) painter.setPen(pen) brush = QBrush(Qt.green) painter.setBrush(brush) painter.drawEllipse( QRect(self.width() / 2 - size / 2, self.height() / 2 - size / 2, size, size)) painter.end() #painter ellipse 2 painter2 = QPainter() painter2.begin(pixmap) painter2.setRenderHint(QPainter.Antialiasing) pen2 = QPen(Qt.green) pen2.setStyle(Qt.DotLine) pen2.setWidth(3) painter2.setPen(pen2) painter2.drawEllipse( QRect(self.width() / 2 - size / 2, self.height() / 2 - size / 2, size, size)) painter2.end() self.ellipseLabel.setPixmap(QPixmap(pixmap)) self.lastSize = s def updateFilledCircle(self, s): size = s * self.zoom pixmap = QPixmap(self.width(), self.height()) pixmap.fill(Qt.transparent) #painter filled ellipse p = QPalette() painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing) brush = QBrush(p.link().color()) painter.setBrush(brush) painter.setOpacity(0.4) painter.drawEllipse( QRect(self.width() / 2 - size / 2, self.height() / 2 - size / 2, size, size)) painter.end() #painter ellipse 2 painter2 = QPainter() painter2.begin(pixmap) painter2.setRenderHint(QPainter.Antialiasing) pen2 = QPen(Qt.green) pen2.setWidth(1) painter2.setPen(pen2) painter2.drawEllipse( QRect(self.width() / 2 - size / 2, self.height() / 2 - size / 2, size, size)) painter2.end() self.ellipseLabel.setPixmap(QPixmap(pixmap)) self.lastSize = s
class ImageGrabber(object): ''' classdocs ''' _config = mrConfigParser() _gui = GuiLoader() _img = None __sources = [] __grabTimer = QTimer() __scene = None __gview = None def __init__(self, gui=None, config=None): ''' Constructor ''' self._gui = GuiLoader() self._config = config if gui != None: self._gui = gui self.__initGui() def __initGui(self): ''' Initiates gui listeners ''' # initiate scene self.__gview = self._gui.getObj("imgVideo") self.__scene = QGraphicsScene() self.__gview.setScene(self.__scene) # add image size combobox items cmb = self._gui.getObj("cmbImgSize") cmb.addItem("320x240") cmb.addItem("640x480") cmb.addItem("800x600") cmb.addItem("1024x768") #cmb.addItem("1280x960") # not working with libdc1394 and avt stringray 125c # add conversion combobox items cmb = self._gui.getObj("cmbConversion") cmb.addItem("None") cmb.addItem("COLOR_BGR2RGB") cmb.addItem("COLOR_GRAY2RGB") cmb.addItem("COLOR_YUV2RGB") cmb.addItem("COLOR_HLS2RGB") # add listeners self._gui.connect("cmdStartVideo", "clicked()", self.startVideo) self._gui.connect("cmdStopVideo", "clicked()", self.stopVideo) self._gui.connect("cmdAddSource", "clicked()", self.__addCamSource) self._gui.connect("cmdAddFile", "clicked()", self.__addFileSource) self._gui.connect("cmdDelSource", "clicked()", self.__removeSourceFromList) self._gui.connect("cmbImgSize", "currentIndexChanged(QString)", self.__imageSizeChanged) self._gui.connect("cmdSaveImg", "clicked()", self.saveImg) def isActive(self): ''' @return: True if image grabbing is active ''' return self.__grabTimer.isActive() def startVideo(self): ''' Starts grabbing images ''' if self.__grabTimer.isActive(): self.__grabTimer.stop() self.__grabTimer = QTimer() self.__grabTimer.timeout.connect(self.__grabImage) self.__grabTimer.start(0) self._gui.status("Video started") def stopVideo(self): ''' Stops grabbing video ''' if self.__grabTimer.isActive(): self.__grabTimer.stop() self.__scene.clear() self.__gview.show() self._gui.status("Video stopped") sleep(1) def getImage(self): ''' Returns the last grabbed image @return: Image ''' return self._img def saveImg(self): ''' Saves image ''' if self._img != None: img = self._img # stop video active = self.isActive() self.stopVideo() # open file dialog options = copy(self._gui.dialogOptionsDef) options['type'] = self._gui.dialogTypes['FileSave'] options['filetypes'] = "JPG (*.jpg)" options['title'] = "Save current frame as" src = str(self._gui.dialog(options)) # check filepath and save if len(src) > 0: if not src.endswith(".jpg"): src = src + ".jpg" self._gui.status("write to " + src) cvtColor(img, COLOR_BGR2RGB) imwrite(src, img) # reset video streaming if active: self.startVideo() def __showImage(self): ''' Shows image on graphics view ''' if self._img != None: self.__scene.clear() self.__scene.addPixmap(imageToPixmap(self._img)) self.__gview.fitInView(self.__scene.sceneRect(), Qt.KeepAspectRatio) self.__gview.show() def __grabImage(self): ''' Graps image from sources ''' images = [] # grab all images for src in self.__sources: assert isinstance(src, AbstractSourceGrabber) images.append(src.getImg()) # join and convert images img = self.__joinImages(images) # convert image convert = eval(str(self._gui.getObj("cmbConversion").currentText())) if convert != None: try: img = cvtColor(img, convert) except: img = None # show results if type(img) == ndarray: # add image as new image self._img = img self.__showImage() else: # show message self.__scene.clear() self.__scene.addText("NO VIDEO") def __joinImages(self, images=[]): ''' Joins images ''' # TO-DO: Joining images if len(images) > 0: return images[0] return False def __imageSizeChanged(self, size="640x480"): ''' Changes image size ''' size = str(size).split("x") w = int(size[0]) h = int(size[1]) # set size for cam in self.__sources: if type(cam) == CamGrabber: assert isinstance(cam, CamGrabber) cam.setImgSize(w, h) def __addSourceToList(self, grabber=None): ''' Adds source to source list ''' assert isinstance(grabber, AbstractSourceGrabber) if grabber != None: # add grabber to list self.__sources.append(grabber) txt = None # get type of grabber if type(grabber) == CamGrabber: txt = "cam [" + str(grabber.getSource()) + "]" elif type(grabber) == FileGrabber: txt = "file [" + str(grabber.getSource()) + "]" # add text string to gui list if txt != None: self._gui.getObj("lstSources").addItem(txt) def __removeSourceFromList(self): ''' Removes selected source from list ''' for item in self._gui.getObj("lstSources").selectedItems(): # get item informationen txt = str(item.text()) if "[" in txt and "]" in txt: data = txt.split("[") iType = data[0].strip() iSource = data[1].replace(']', '') # search for grabber for grabber in self.__sources: assert isinstance(grabber, AbstractSourceGrabber) if str(grabber.getSource()) == iSource: if type(grabber) == CamGrabber and iType == "cam": self.__sources.remove(grabber) break elif type(grabber) == FileGrabber and iType == "file": self.__sources.remove(grabber) break # remove source from gui list item = self._gui.getObj("lstSources").takeItem( self._gui.getObj("lstSources").currentRow()) item = None def __addCamSource(self): ''' Adds camera as source ''' obj = self._gui.getObj("txtSource") source = int(obj.text()) grabber = CamGrabber(source) if grabber.isOpened(): self.__addSourceToList(grabber) self._gui.status("Added camera source [" + str(source) + "]") else: self._gui.status( "Could not add camera source [" + str(source) + "]", self._gui.msgTypes['ERROR']) def __addFileSource(self): ''' Adds file as source ''' self.stopVideo() options = copy(self._gui.dialogOptionsDef) options['filetypes'] = "Images (*.jpg *jpeg *gif *png *bmp *tif)" source = str(self._gui.dialog(options)) if len(source) > 0: grabber = FileGrabber(source) self.__addSourceToList(grabber) self._gui.status("Added file source [" + str(source) + "]")
class LeapFlow (QMainWindow): def __init__ (self): QMainWindow.__init__ (self) self.controller = Controller () self.listener = LeapListener (self) self.controller.add_listener (self.listener) self.mode = "gallery" self.scroll = False self.direction = "" self.direction_x = 0 self.scroll_velocity = 0 self.current_index = 0 # List containing images for the gallery self.list_view = QListWidget () self.list_view.setFlow (0) self.list_view.setHorizontalScrollMode (1) self.list_view.setMouseTracking (True) self.list_view.itemClicked.connect (self.show_image) # Setting the style of the ListView, background, item selected, etc self.list_view.setStyleSheet (""" QListWidget::item:hover {background: transparent;} QListWidget::item:disabled:hover {background: transparent;} QListWidget::item:hover:!active {background: transparent;} QListWidget::item:selected:active {background: transparent;} QListWidget::item:selected:!active {background: transparent;} QListWidget::item:selected:disabled {background: transparent;} QListWidget::item:selected:!disabled {background: transparent;} QListWidget {background: #2C3539} """) # Image viewer self.scene = QGraphicsScene () self.viewer = QGraphicsView (self.scene) self.stackedWidget = QStackedWidget () self.stackedWidget.addWidget (self.list_view) self.stackedWidget.addWidget (self.viewer) self.setCentralWidget (self.stackedWidget) self.resize (500, 400) self.showMaximized () scan = ScanLibrary ("/home/chris/Example") threads.append (scan) self.connect (scan, SIGNAL (scan.signal), self.add_images_to_list) scan.start () self.connect (self, SIGNAL ("scrollChanged(bool)"), self.scroll_view) def setScroll (self, scroll): """Emit signal to scroll the view""" if (self.scroll != scroll): self.scroll = scroll self.emit (SIGNAL("scrollChanged(bool)"), scroll) def scroll_view (self): """Scroll the view based on scroll velocity and direction""" x = self.direction_x * self.scroll_velocity / 100 bar_x = self.list_view.horizontalScrollBar ().value () self.list_view.horizontalScrollBar ().setValue (bar_x + x) def add_images_to_list (self): """To add a widget to the listview you must add a QListWidgetItem and replace with your widget""" for image in library: item = QListWidgetItem () pixmap = QPixmap.fromImage (QImage (library[image])) label = QLabel () label.setPixmap (pixmap.scaled (600, 400)) item.setSizeHint (label.sizeHint ()) item.setData (0, library[image]) self.list_view.addItem (item) self.list_view.setItemWidget (item, label) def show_image (self, item): """"Display the selected image""" self.current_index = self.list_view.indexFromItem (item).row () self.scene.addPixmap ((QPixmap.fromImage (QImage (item.text()))).scaled (self.viewer.size())) self.stackedWidget.setCurrentIndex (1) self.mode = "viewer" def previous_image (self): """Load previous image""" if self.current_index - 1 >= 0: self.current_index -= 1 self.load_image () def next_image (self): """Load next image""" if self.current_index + 1 <= len(library.keys ()) - 1: self.current_index += 1 self.load_image () def load_image (self): """Load the image in self.current_index""" self.scene.addPixmap (QPixmap.fromImage (QImage (library[library.keys()[self.current_index]])))
def setPreviewImage(self, image): """Show image in self.preview.""" pix = image.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene)
class PlotPreview(QDialog): def __init__(self, thread, parent): QDialog.__init__(self, parent) self.ui = Ui_PlotPreview() self.ui.setupUi(self) self.parent = parent icon = QIcon() icon.addPixmap(QPixmap(":/icons/reload.png"), QIcon.Normal, QIcon.Off) self.update_btn = QPushButton(icon, "Update") self.ui.buttonBox.addButton(self.update_btn, QDialogButtonBox.ApplyRole) self.update_btn.clicked.connect(self.render_image) self._pix = None self._image_list = None self._thread = thread self.scene = QGraphicsScene() self.scene.setSceneRect(0,0,1,1) self.ui.imageView.setScene(self.scene) self.pix_item = None self.ui.imageView.setEnabled(False) self.ui.imageView.setInteractive(False) self.ui.imageView.setDragMode(QGraphicsView.ScrollHandDrag) self.pic_w = None self.pic_c = None self.show_pic_w = None self.show_pic_c = None timer = QTimer(self) timer.setSingleShot(True) timer.setInterval(500) self.timer = timer timer.timeout.connect(self.render_image) if parameters.instance.use_OpenGL: self.ui.imageView.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers))) def __del__(self): self.ui.imageView.setScene(None) cleanQObject(self) @property def thread(self): '''Thread object drawing the img''' return self._thread @thread.setter def thread(self, value): if self._thread != value: self._thread = value @property def pix(self): '''Image to be previewed. :returntype: `QImage`''' return self._pix @pix.setter def pix(self, pix): self.ui.imageView.setEnabled(True) self._pix = pix if self.pix_item is not None: self.scene.removeItem(self.pix_item) self.pix_item = self.scene.addPixmap(QPixmap.fromImage(pix)) self.scene.setSceneRect(QRectF(self.pix.rect())) if self.show_pic_w: self.show_pic_w.close() self.show_pic_w = None if self.pic_w: self.show_pic_w = QLabel(self, Qt.Window) #self.show_pic_w.setAttribute(Qt.WA_DeleteOnClose) self.show_pic_w.setPicture(self.pic_w) self.show_pic_w.show() self.show_pic_w.raise_() if self.show_pic_c: self.show_pic_c.close() self.show_pic_c = None if self.pic_c: self.show_pic_c = QLabel(self, Qt.Window) #self.show_pic_c.setAttribute(Qt.WA_DeleteOnClose) self.show_pic_c.setPicture(self.pic_c) self.show_pic_c.show() self.show_pic_c.raise_() log_debug("Received image") @property def image_list(self): '''List of images to paint''' return tuple(self._image_list) @image_list.setter def image_list(self, value): value = list(value) if self._image_list != value: self._image_list = value self.ui.imageList.clear() for img in value: self.ui.imageList.addItem(img) self.ui.autoUpdate.setEnabled(True) self.ui.zoomIn.setEnabled(True) self.ui.zoomOut.setEnabled(True) self.ui.zoom1.setEnabled(True) self.ui.zoomFit.setEnabled(True) self.ui.imageList.setEnabled(True) @pyqtSignature("") def on_zoomIn_clicked(self): self.ui.imageView.scale(2,2) @pyqtSignature("") def on_zoomOut_clicked(self): self.ui.imageView.scale(.5,.5) @pyqtSignature("") def on_zoom1_clicked(self): self.ui.imageView.setTransform(QTransform()) @pyqtSignature("") def on_zoomFit_clicked(self): self.ui.imageView.fitInView(QRectF(self.pix.rect()), Qt.KeepAspectRatio) @pyqtSignature("") def request_render_image(self): if self.isVisible(): if parameters.instance.use_thread: self.timer.start() else: self.render_image() @pyqtSignature("") def render_image(self): if self.isVisible(): i = self.ui.imageList.currentIndex() log_debug("Launch computing for image %d" % i) if self.thread.render_single(i) is None: QMessageBox.information(self, "Failed rendering image", "The renderer is busy and could not render the image.\nTry again later") else: self.ui.imageView.setEnabled(False) @pyqtSignature("int") def on_imageList_currentIndexChanged(self, value): self.render_image() @pyqtSignature("bool") def on_autoUpdate_toggled(self, value): self.parent.auto_update = value if value: self.request_render_image() def showEvent(self, event): self.render_image() def reject(self): self.close() def closeEvent(self, event): self.parent.preview_button.setChecked(False) if self.show_pic_w is not None: self.show_pic_w.close() self.show_pic_w = None if self.show_pic_c is not None: self.show_pic_c.close() self.show_pic_c = None
class Canvas(QGraphicsView): def __init__(self, window, resultDict, imagePath): QGraphicsView.__init__(self) self.window = window self.pen = QPen(QColor("red")) self.pen.setWidth(0.5) self.canvasScene = QGraphicsScene() self.setScene(self.canvasScene) self.resultDict = resultDict self.imagePath = imagePath self.setBackgroundBrush(QBrush(Qt.black, Qt.SolidPattern)) def drawImage(self, imageFile): """Draw an image on the canvas""" image = QPixmap(imageFile) self.canvasScene.addPixmap(image) return image def drawFeaturePoint(self, pointList): """Draw a feature point on the canvas""" radius = 0.5 width, height = 2, 2 x1, y1, x2, y2 = pointList #Draw ellipse and bounding rect. Is a hacked version! self.canvasScene.addEllipse(x1 - radius + 5, y1 - radius + 3, 2 * radius, 2 * radius, self.pen) self.canvasScene.addEllipse(x2 - radius + self.imageWidth + 10, y2 - radius + 3, 2 * radius, 2 * radius, self.pen) self.canvasScene.addRect(x1 - width / 2. + 5, y1 - height / 2. + 3, width, height, self.pen) self.canvasScene.addRect(x2 - width / 2. + self.imageWidth + 10, y2 - height / 2. + 3, width, height, self.pen) def drawFeatureImages(self, imageFile): """Draw two consecutive images on the screen""" #Load image files path, file_ = os.path.split(imageFile) image1 = QPixmap(os.path.join(path, 'first_' + file_)) image2 = QPixmap(os.path.join(path, 'second_' + file_)) self.imageWidth = image1.width() #Add pixmaps image1Map = self.canvasScene.addPixmap(image1) image2Map = self.canvasScene.addPixmap(image2) #Shift pixmaps to the right position image1Map.setOffset(QPointF(5, 3)) image2Map.setOffset(QPointF(10 + image1.width(), 3)) def drawPolygon(self, Polygon): """Draw a polygon on the canvas""" polygon = QPolygonF() for point in Polygon: polygon.append(QPointF(point[0], point[1])) self.canvasScene.addPolygon(polygon, self.pen) def getWorkerId(self): return self.resultDict.values()[self.index][0][0] def getAssignmentId(self): return self.resultDict.keys()[self.index] def nextImage(self): """Load next image""" self.index += 1 self.canvasScene.clear() if self.index > len(self.resultDict) - 1 or len(self.resultDict) <= 0: self.canvasScene.addText("No annotations to review") self.window.reviewFlag = False self.window.updateTable() else: #Draw Image and Polygon assignmentId = self.resultDict.keys()[self.index] result = self.resultDict[assignmentId] image = result[0][1] pointList = result[0][2] if self.window.segmentation_mode: pointList = [round(float(point), 3) for point in pointList] pointList = zip(*[iter(pointList)] * 2) self.drawImage(os.path.join(self.imagePath, image)) self.drawPolygon(pointList) else: pointList = [round(float(point), 3) for point in pointList] pointList = zip(*[iter(pointList)] * 4) self.drawFeatureImages(os.path.join(self.imagePath, image)) for point in pointList: self.drawFeaturePoint(point) #update scene self.window.setWindowTitle("MTurk Review Tool ({0}/{1}) Rejected: {2} Approved: {3}".format(self.index + 1, len(self.resultDict), len(self.window.rejected), len(self.window.approved))) self.canvasScene.setSceneRect(self.canvasScene.itemsBoundingRect()) self.fitInView(0, 0, self.canvasScene.width(), self.canvasScene.height(), 1) self.canvasScene.update(0, 0, self.canvasScene.width(), self.canvasScene.height())
class NostraIllustCheckDlg(QtGui.QDialog, FORM_CLASS): def __init__(self, theCanvas, theLayer, selFeatureIds, parent=None): super(NostraIllustCheckDlg, self).__init__(parent) self.setupUi(self) self.mTheCanvas = theCanvas self.mTheLayer = theLayer self.mSelFeatureIds = selFeatureIds self.mAllFeatureIds = [] self.highlightList = [] uri = QgsDataSourceURI(self.mTheLayer.source()) self.conn = psycopg2.connect('''host='%s' dbname='%s' user='******' password='******' ''' %\ (uri.host(), uri.database(), uri.username(), uri.password())) self.pg = self.conn.cursor() # members shown in graphic view. self.mScene = QGraphicsScene() self.graphicsViewShowImage.setScene(self.mScene) self.mPixmapList = [] featureIter = self.mTheLayer.getFeatures(QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry)) inti = 0 theFeature = QgsFeature() while (featureIter.nextFeature(theFeature)): inti += 1 self.mAllFeatureIds.append(theFeature.id()) self.spinBoxFeatureIndex.setValue(1) self.spinBoxFeatureIndex.setMinimum(1) self.spinBoxFeatureIndex.setMaximum(inti) errMsg = [''] self.initComboBoxOutlinkid() self.selectFeatureById(errMsg, self.mSelFeatureIds[0], bZoomToSelected=False) self.comboBoxOutlinkid.setFocus() self.pushButtonPrev.clicked.connect(self.onPushButtonPrev) self.pushButtonNext.clicked.connect(self.onPushButtonNext) self.connect(self.comboBoxOutlinkid, QtCore.SIGNAL('activated(QString)'), self.comboBoxOutlinkidChanged) def resizeEvent(self, event): self.showImageInGraphicsView() return def disableAllControls(self): self.pushButtonPrev.setEnabled(False) self.pushButtonPrev.setEnabled(False) self.comboBoxOutlinkid.setEnabled(False) self.textEditFeatureInfo.setEnabled(False) return def initComboBoxOutlinkid(self): while (self.comboBoxOutlinkid.count() > 0): self.comboBoxOutlinkid.removeItem(0) for oneFeatureId in self.mSelFeatureIds: featureIter = self.mTheLayer.getFeatures( QgsFeatureRequest(oneFeatureId).setFlags( QgsFeatureRequest.NoGeometry)) theFeature = QgsFeature() if featureIter.nextFeature(theFeature) == False: return if self.mIsMyFeature(theFeature): strTemp = "%.0f, %.0f" % (theFeature.attribute('arc1'), theFeature.attribute('arc2')) self.comboBoxOutlinkid.addItem(strTemp) def showFeatureDetail(self, errMsg, theFeature): strFeatureInfo = self.getFeatureInfoString(theFeature) self.textEditFeatureInfo.setText(strFeatureInfo) if self.mIsMyFeature(theFeature) == False: return errMsg = [''] day_pic = theFeature.attribute('day_pic') arrowimg = theFeature.attribute('arrowimg') basePath = r"\\tangpinghui\20151010_nostra_junctionview\output_jpg_and_png" day_pic_path = os.path.join(basePath, day_pic + ".psd\Main_Day.jpg") arrowimg_path = '' tempPath = os.path.join(basePath, day_pic + ".psd") for curDir, subDirs, fileNames in os.walk(tempPath): for oneFile in fileNames: if oneFile.find(arrowimg) != -1 and oneFile.find('_en') != -1: arrowimg_path = os.path.join(curDir, oneFile) self.mPixmapList = [] patternPixmap = QPixmap() patternPixmap.load(day_pic_path) self.mPixmapList.append(patternPixmap) arrowPixmap = QPixmap() arrowPixmap.load(arrowimg_path) self.mPixmapList.append(arrowPixmap) self.showImageInGraphicsView() return def showImageInGraphicsView(self): # remove all items in member QGraphicsScene. for oneItem in self.mScene.items(): self.mScene.removeItem(oneItem) for onePixmap in self.mPixmapList: self.mScene.addPixmap( self.getPixMapSizedByWidgt(onePixmap, self.graphicsViewShowImage)) self.mScene.setSceneRect(0, 0, self.graphicsViewShowImage.width() - 5, self.graphicsViewShowImage.height() - 5) return def getFeatureInfoString(self, theFeature): fieldList = theFeature.fields() attrList = theFeature.attributes() strFeatureInfo = "field count: %d\n" % len(fieldList) for oneField, oneAttr in zip(fieldList, attrList): if isinstance(oneAttr, float): strFeatureInfo += "%s: %.0f\n" % (oneField.name(), oneAttr) else: strFeatureInfo += "%s: %s\n" % (oneField.name(), oneAttr) return strFeatureInfo def comboBoxOutlinkidChanged(self, txt): errMsg = [''] inti = self.comboBoxOutlinkid.currentIndex() self.selectFeatureById(errMsg, self.mSelFeatureIds[inti], bZoomToSelected=False) if errMsg[0] <> '': QMessageBox.information(self, "Nostra Illust Check", """error:\n%s""" % errMsg[0]) return return def onPushButtonPrev(self): self.spinBoxFeatureIndex.setValue(self.spinBoxFeatureIndex.value() - 1) prevFeatureId = self.mAllFeatureIds[self.spinBoxFeatureIndex.value() - 1] errMsg = [''] self.selectFeatureById(errMsg, prevFeatureId) if errMsg[0] <> '': QMessageBox.information(self, "Nostra Illust Check", """error:\n%s""" % errMsg[0]) return return def onPushButtonNext(self): self.spinBoxFeatureIndex.setValue(self.spinBoxFeatureIndex.value() + 1) nextFeatureId = self.mAllFeatureIds[self.spinBoxFeatureIndex.value() - 1] errMsg = [''] self.selectFeatureById(errMsg, nextFeatureId) if errMsg[0] <> '': QMessageBox.information(self, "Nostra Illust Check", """error:\n%s""" % errMsg[0]) return return def selectFeatureById(self, errMsg, featureId, bZoomToSelected=True): self.mTheLayer.removeSelection() self.mTheLayer.select(featureId) theFeature = self.mTheLayer.selectedFeatures()[0] self.showFeatureDetail(errMsg, theFeature) if errMsg[0] <> '': return if bZoomToSelected == True: center = self.mTheCanvas.panToSelected(self.mTheLayer) self.mTheCanvas.refresh() self.clearHighlight() arc1 = "%.0f" % theFeature.attribute('arc1') sqlcmd = """ SET bytea_output TO escape; select st_asbinary(the_geom) from temp_topo_link where routeid=%s """ % arc1 self.pg.execute(sqlcmd) rows = self.pg.fetchall() for row in rows: qgsGeometry = QgsGeometry() qgsGeometry.fromWkb(str(row[0])) self.highlightByGeometry(qgsGeometry, QColor(249, 27, 15, 168)) arc2 = "%.0f" % theFeature.attribute('arc2') sqlcmd = """ SET bytea_output TO escape; select st_asbinary(the_geom) from temp_topo_link where routeid=%s """ % arc2 self.pg.execute(sqlcmd) rows = self.pg.fetchall() for row in rows: qgsGeometry = QgsGeometry() qgsGeometry.fromWkb(str(row[0])) self.highlightByGeometry(qgsGeometry, QColor(22, 151, 0, 168)) new_arc1 = "%.0f" % theFeature.attribute('new_arc1') if new_arc1 is not None and new_arc1 <> arc1: sqlcmd = """ SET bytea_output TO escape; select st_asbinary(the_geom) from temp_topo_link where routeid=%s """ % new_arc1 self.pg.execute(sqlcmd) rows = self.pg.fetchall() for row in rows: qgsGeometry = QgsGeometry() qgsGeometry.fromWkb(str(row[0])) self.highlightByGeometry(qgsGeometry, QColor(253, 158, 153, 128)) new_arc2 = "%.0f" % theFeature.attribute('new_arc2') if new_arc2 is not None and new_arc2 <> arc2: sqlcmd = """ SET bytea_output TO escape; select st_asbinary(the_geom) from temp_topo_link where routeid=%s """ % new_arc2 self.pg.execute(sqlcmd) rows = self.pg.fetchall() for row in rows: qgsGeometry = QgsGeometry() qgsGeometry.fromWkb(str(row[0])) self.highlightByGeometry(qgsGeometry, QColor(147, 255, 155, 128)) return def getPixMapSizedByWidgt(self, pixmap, theWidgt): pixmapWidth = pixmap.width() pixmapHeight = pixmap.height() gpViewWidth = theWidgt.width() gpViewHeight = theWidgt.height() destWidth = 0 destHeight = 0 if pixmapWidth > gpViewWidth - 5: destWidth = gpViewWidth - 5 else: destWidth = pixmapWidth if pixmapHeight > gpViewHeight - 5: destHeight = gpViewHeight - 5 else: destHeight = pixmapHeight return pixmap.scaled(destWidth, destHeight, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation) def mIsMyFeature(self, theFeature): return NostraIllustCheckDlg.isMyFeature(theFeature) @staticmethod def isMyFeature(theFeature): try: gid = theFeature.attribute('gid') arc1 = theFeature.attribute('arc1') arc2 = theFeature.attribute('arc2') day_pic = theFeature.attribute('day_pic') night_pic = theFeature.attribute('night_pic') arrowimg = theFeature.attribute('arrowimg') lon = theFeature.attribute('lon') lat = theFeature.attribute('lat') new_arc1 = theFeature.attribute('new_arc1') new_arc2 = theFeature.attribute('new_arc2') except KeyError, kErr: return False except Exception, ex: return False
class GeorefDialog(QDialog, Ui_GeorefDialogBase): def __init__(self, types, parent=None): super(GeorefDialog, self).__init__(parent) self.setupUi(self) # Internal variables self._closeOnDone = False self._types = {} self._georeferencer = None self._types = types self._scene = QGraphicsScene(self) self._georeferencer = Georeferencer(self) self._georeferencer.status.connect(self._updateStatus) self._georeferencer.error.connect(self._updateError) # Init the gui for group in self._types: self.typeCombo.addItem(self._types[group]['name'], group) self.typeCombo.setCurrentIndex(0) for scale in Scale.Scale: self.scaleCombo.addItem(Scale.Label[scale], scale) self.scaleCombo.setCurrentIndex(Scale.OneToTwenty) self.processButton.clicked.connect(self._process) self.saveButton.clicked.connect(self._save) self.runButton.clicked.connect(self._run) self.closeButton.clicked.connect(self._close) self.siteEdit.textChanged.connect(self._updateGeoreference) self.typeCombo.currentIndexChanged.connect(self._updateGeoreference) self.scaleCombo.currentIndexChanged.connect(self._updateGeoreference) self.numberSpin.valueChanged.connect(self._updateGeoreference) self.suffixEdit.textChanged.connect(self._updateGeoreference) self.eastSpin.valueChanged.connect(self._updateGeoreference) self.northSpin.valueChanged.connect(self._updateGeoreference) def loadImage(self, inputFile): self._setStatusLabel('load', ProcessStatus.Running) if (not inputFile.exists()): self._showStatus('ERROR: Input file not found! File path was ' + inputFile.absoluteFilePath()) self._setStatusLabel('load', ProcessStatus.Failure) return False self._inputFile = inputFile pixmap = QPixmap(self._inputFile.absoluteFilePath()) if pixmap.isNull(): self._signalError('Loading of raw image failed.') return pixmap = QPixmap(self._inputFile.absoluteFilePath()) w = pixmap.width() h = pixmap.height() self._scene.addPixmap(pixmap) self._scene.setSceneRect(QRectF(0, 0, w, h)) self.planView.setSceneView(self._scene, QRectF(0, 0, w, h)) self.headerView.setSceneView(self._scene, QRectF(0, 0, w, 200)) self.footerView.setSceneView(self._scene, QRectF(100, h - 600, w - 200, 500)) self.gcpWidget1.setScene(self._scene, 250, 100, 2) self.gcpWidget2.setScene(self._scene, 250, 3050, 2) self.gcpWidget3.setScene(self._scene, 3200, 3050, 2) self.gcpWidget4.setScene(self._scene, 3200, 100, 2) self.inputFileNameLabel.setText(self._inputFile.baseName()) drawing = Drawing(self._inputFile) if drawing.isValid(): self.siteEdit.setText(drawing.item().siteCode()) self.typeCombo.setCurrentIndex(self.typeCombo.findData(drawing.item().classCode())) self.numberSpin.setValue(int(drawing.item().itemId()) or 0) self.eastSpin.setValue(drawing.easting() or 0) self.northSpin.setValue(drawing.northing() or 0) self.suffixEdit.setText(drawing.suffix()) self._updateFileNames(drawing) self._updateGeoPoints() pointFile = self.pointFileInfo() if pointFile.exists(): self._loadGcp(pointFile.absoluteFilePath()) self._setStatusLabel('load', ProcessStatus.Success) QCoreApplication.processEvents() return True return False def _loadGcp(self, path): gc = Georeferencer.loadGcpFile(path) gcTo = Transform() for index in gc.points(): gcp = gc.point(index) if gcp.map() == self.gcpWidget1.gcp().map(): gcTo.setPoint(1, gcp) elif gcp.map() == self.gcpWidget2.gcp().map(): gcTo.setPoint(2, gcp) elif gcp.map() == self.gcpWidget3.gcp().map(): gcTo.setPoint(3, gcp) elif gcp.map() == self.gcpWidget4.gcp().map(): gcTo.setPoint(4, gcp) if gcTo.isValid() and len(gcTo.points()) == 4: self.gcpWidget1.setRaw(gcTo.point(1).raw()) self.gcpWidget2.setRaw(gcTo.point(2).raw()) self.gcpWidget3.setRaw(gcTo.point(3).raw()) self.gcpWidget4.setRaw(gcTo.point(4).raw()) def _updateGeoPoints(self): mapUnits = Scale.Factor[self.drawingScale()] local1 = QPointF(self.eastSpin.value(), self.northSpin.value() + mapUnits) local2 = QPointF(self.eastSpin.value(), self.northSpin.value()) local3 = QPointF(self.eastSpin.value() + mapUnits, self.northSpin.value()) local4 = QPointF(self.eastSpin.value() + mapUnits, self.northSpin.value() + mapUnits) if self.drawingType() == 'sec': self.gcpWidget1.setGeo(local1, QgsPoint(local1)) self.gcpWidget2.setGeo(local2, QgsPoint(local2)) self.gcpWidget3.setGeo(local3, QgsPoint(local3)) self.gcpWidget4.setGeo(local4, QgsPoint(local4)) return typ = self._type() gridLayer = typ['grid'] features = gridLayer.getFeatures() localX = gridLayer.fieldNameIndex(typ['local_x']) localY = gridLayer.fieldNameIndex(typ['local_y']) for feature in features: local = QPoint(feature.attributes()[localX], feature.attributes()[localY]) map = geometry.toPoint(feature.geometry().geometry()) if local == local1: self.gcpWidget1.setGeo(local, map) elif local == local2: self.gcpWidget2.setGeo(local, map) elif local == local3: self.gcpWidget3.setGeo(local, map) elif local == local4: self.gcpWidget4.setGeo(local, map) def _updateGeoreference(self): self._updateFileNames(self.drawing()) self._updateGeoPoints() def _updateFileNames(self, drawing): self.rawFileNameLabel.setText(drawing.baseName()) self.geoFileNameLabel.setText(drawing.baseName() + self._type()['suffix']) def _toggleUi(self, status): self.processButton.setEnabled(status) self.saveButton.setEnabled(status) self.runButton.setEnabled(status) self.closeButton.setEnabled(status) self.siteEdit.setEnabled(status) self.typeCombo.setEnabled(status) self.numberSpin.setEnabled(status) self.suffixEdit.setEnabled(status) self.eastSpin.setEnabled(status) self.northSpin.setEnabled(status) self.cropCheck.setEnabled(status) self.addToMapCheck.setEnabled(status) self.gcpWidget1.setEnabled(status) self.gcpWidget2.setEnabled(status) self.gcpWidget3.setEnabled(status) self.gcpWidget4.setEnabled(status) self.planView.setEnabled(status) if (status): self.progressBar.setRange(0, 100) else: self.progressBar.setRange(0, 0) def drawing(self): return Drawing(self.item(), self.easting(), self.northing(), self.suffix(), self.rawFileName()) def item(self): return Item(self.siteCode(), self.classCode(), self.itemId()) def siteCode(self): return self.siteEdit.text().strip() def classCode(self): return self.drawingType() def itemId(self): return unicode(self.numberSpin.value()) def drawingType(self): return self.typeCombo.itemData(self.typeCombo.currentIndex()) def drawingScale(self): return self.scaleCombo.itemData(self.scaleCombo.currentIndex()) def easting(self): return self.eastSpin.value() def northing(self): return self.northSpin.value() def suffix(self): return self.suffixEdit.text().strip() def inputFileName(self): return self.inputFileNameLabel.text().strip() def rawFileName(self): return self.rawFileNameLabel.text().strip() def rawFileInfo(self): return QFileInfo(self._type()['raw'], self.rawFileName() + '.' + self._inputFile.suffix()) def pointFileInfo(self): return QFileInfo(self._type()['raw'], self.rawFileName() + '.' + self._inputFile.suffix() + '.points') def geoFileName(self): return self.geoFileNameLabel.text().strip() def geoFileInfo(self): return QFileInfo(self._type()['geo'], self.geoFileName() + '.tif') def _type(self): return self._types[self.drawingType()] def _updateStatus(self, step, status): self._setStatusLabel(step, status) self._showStatus(Georeferencer.Label[step] + ': ' + ProcessStatus.Label[status]) if step == Georeferencer.Stop and status == ProcessStatus.Success: if self._closeOnDone: self._close() else: self._toggleUi(True) def _updateError(self, step, msg): self._setStatusLabel(step, ProcessStatus.Failure) self._showStatus(msg) self._toggleUi(True) def _showStatus(self, text): self.statusBar.showMessage(text) def _save(self): self._copyInputFile() self._saveGcp() self._close() def _copyInputFile(self): if self.inputFileName() != self.rawFileName() or self._inputFile.dir() != self._type()['raw']: QFile.copy(self._inputFile.absoluteFilePath(), self.rawFileInfo().absoluteFilePath()) def _saveGcp(self): gc = self._gc() if (gc.isValid()): Georeferencer.writeGcpFile(gc, self.pointFileInfo().absoluteFilePath()) def _run(self): self._runGeoreference(False) def _process(self): self._runGeoreference(True) def _close(self): if (self._georeferencer.step() == Georeferencer.Stop): self.accept() else: self.reject() def _gc(self): gc = Transform() gc.crs = self._type()['crs'] gc.setPoint(1, self.gcpWidget1.gcp()) gc.setPoint(2, self.gcpWidget2.gcp()) gc.setPoint(3, self.gcpWidget3.gcp()) gc.setPoint(4, self.gcpWidget4.gcp()) return gc def _runGeoreference(self, closeOnDone): self._closeOnDone = closeOnDone gc = self._gc() if (not gc.isValid()): self._showStatus('ERROR: Please set all 4 Ground Control Points!') return self._toggleUi(False) self._copyInputFile() QCoreApplication.processEvents() self._georeferencer.run(gc, self.rawFileInfo(), self.pointFileInfo(), self.geoFileInfo()) def _finished(self, step, status): if step == Georeferencer.Stop and status == ProcessStatus.Success and self._closeOnDone: self._close() else: self._toggleUi(True) def _setStatusLabel(self, step, status): if step == 'load': label = self.loadStatusLabel elif step == Georeferencer.Crop: label = self.cropStatusLabel elif step == Georeferencer.Translate: label = self.translateStatusLabel elif step == Georeferencer.Warp: label = self.warpStatusLabel elif step == Georeferencer.Overview: label = self.overviewStatusLabel else: return if status == ProcessStatus.Success: label.setPixmap(QPixmap(':/plugins/ark/georef/success.png')) elif status == ProcessStatus.Failure: label.setPixmap(QPixmap(':/plugins/ark/georef/failure.png')) elif status == ProcessStatus.Running: label.setPixmap(QPixmap(':/plugins/ark/georef/running.png')) else: label.setPixmap(QPixmap(':/plugins/ark/georef/unknown.png'))