Beispiel #1
0
 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()
Beispiel #2
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)
Beispiel #3
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 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()
Beispiel #5
0
 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_()
Beispiel #7
0
 def loadFile(self):
     global image
     
     path = QFileDialog.getOpenFileName()
     
     image = QImage(path) 
     
     scene = QGraphicsScene()
     scene.addPixmap(QPixmap(path))
     
     self.graphicsView.setScene(scene)
     print 'loading ' + path
Beispiel #8
0
 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()
Beispiel #9
0
 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()
Beispiel #10
0
Datei: 6.py Projekt: wsonv/Wonjun
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_())
Beispiel #11
0
 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()
Beispiel #12
0
 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()
Beispiel #13
0
    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.')
Beispiel #15
0
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)
Beispiel #16
0
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()
Beispiel #18
0
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
Beispiel #19
0
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]])))
Beispiel #20
0
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)
Beispiel #21
0
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()
Beispiel #22
0
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()
Beispiel #23
0
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)
Beispiel #24
0
 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()
Beispiel #26
0
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
Beispiel #28
0
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()
Beispiel #29
0
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()
Beispiel #32
0
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)
Beispiel #33
0
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")
Beispiel #34
0
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()
Beispiel #35
0
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
Beispiel #36
0
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
Beispiel #37
0
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
Beispiel #38
0
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) + "]")
Beispiel #39
0
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]])))
Beispiel #40
0
 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)
Beispiel #41
0
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
Beispiel #44
0
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'))