Beispiel #1
0
    def createcvtColorLayer(self):
        layerContent = Layers([])
        layerContent.name = 'cvtColor'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'low'
        tempChildren.value = 50
        tempChildren.note = 'threshold1'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #2
0
    def createHoughCirclesLayer(self):
        layerContent = Layers([])
        layerContent.name = 'HoughCircles'
        layerContent.children = []
        tempChildren = Layers([])

        tempChildren.name = 'dp'
        tempChildren.value = 1.5
        tempChildren.note = 'Inverse ratio'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'minDist'
        tempChildren.value = 100
        tempChildren.note = 'Minimum distance between two circles'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'param1'
        tempChildren.value = 100
        tempChildren.note = 'do not change'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'param2'
        tempChildren.value = 30
        tempChildren.note = 'do not change'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'minRadius'
        tempChildren.value = 10
        tempChildren.note = 'Minimum circle radius'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'maxRadius'
        tempChildren.value = 0
        tempChildren.note = 'Maximum circle radius'
        layerContent.children.append(deepcopy(tempChildren))

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #3
0
    def createthresholdLayer(self):
        layerContent = Layers([])
        layerContent.name = 'threshold'
        layerContent.children = []
        tempChildren = Layers([])
        layerContent.enable = 1

        tempChildren.name = 'thresh'
        tempChildren.value = 0
        tempChildren.note = 'thresh'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'maxval'
        tempChildren.value = 255
        tempChildren.note = 'maxval'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'triangle'
        tempChildren.value = 0
        tempChildren.note = '0=otsu,1=triangle'
        layerContent.children.append(deepcopy(tempChildren))

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #4
0
    def createHoughLinesPLayer(self):
        layerContent = Layers([])
        layerContent.name = 'HoughLinesP'
        layerContent.children = []
        tempChildren = Layers([])
        layerContent.enable = 1

        tempChildren.name = 'rho'
        tempChildren.value = 0.8
        tempChildren.note = 'Distance resolution'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'theta'
        tempChildren.value = 0.01
        tempChildren.note = 'Angle resolution'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'threshold'
        tempChildren.value = 100
        tempChildren.note = 'Accumulator threshold parameter'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'minLineLength'
        tempChildren.value = 10
        tempChildren.note = 'Minimum line length'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'maxLineGap'
        tempChildren.value = 500
        tempChildren.note = 'Maximum allowed gap'
        layerContent.children.append(deepcopy(tempChildren))

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #5
0
    def createHoughLinesLayer(self):
        layerContent = Layers([])
        layerContent.name = 'HoughLines'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'rho'
        tempChildren.value = 0.8
        tempChildren.note = 'Distance resolution'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'theta'
        tempChildren.value = 0.01
        tempChildren.note = 'Angle resolution'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'threshold'
        tempChildren.value = 100
        tempChildren.note = 'Accumulator threshold parameter'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #6
0
    def createfindContoursLayer(self):
        layerContent = Layers([])
        layerContent.name = 'findContours'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'RM'
        tempChildren.value = cv2.RETR_TREE
        tempChildren.note = 'RetrievalModes'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'CAM'
        tempChildren.value = cv2.CHAIN_APPROX_SIMPLE
        tempChildren.note = 'ContourApproximationModes'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #7
0
    def __init__(self, app):
        """
        Initialization of the Main window. This is directly called after the
        Logger has been initialized. The Function loads the GUI, creates the
        used Classes and connects the actions to the GUI.
        """
        QMainWindow.__init__(self)

        # Build the configuration window
        self.config_window = ConfigWindow(g.config.makeConfigWidgets(),
                                          g.config.var_dict,
                                          g.config.var_dict.configspec, self)
        self.config_window.finished.connect(self.updateConfiguration)

        self.app = app
        self.settings = QtCore.QSettings("py2cv", "py2cv")

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)
        self.showMaximized()

        self.cameraEnable = False

        self.canvas = self.ui.canvas
        self.canvas_scene = None

        self.TreeHandler = TreeHandler(self.ui)
        self.configuration_changed.connect(
            self.TreeHandler.updateConfiguration)

        if sys.version_info[0] == 2:
            error_message = QMessageBox(
                QMessageBox.Critical, 'ERROR',
                self.
                tr("Python version 2 is not supported, please use it with python version 3."
                   ))
            sys.exit(error_message.exec_())

        self.d2g = Project(self)

        self.createActions()
        self.connectToolbarToConfig()

        self.filename = ""

        # TCP Server
        if g.config.vars.Trigger.tcp_server_enable:
            self.server = QTcpServer()
            self.server.listen(QHostAddress.Any,
                               int(g.config.vars.Trigger.tcp_server_port))
            # Connection connect
            self.server.newConnection.connect(self.on_newConnection)
        self.entityRoot = None
        self.layerContents = Layers([])

        self.cont_dx = 0.0
        self.cont_dy = 0.0
        self.cont_rotate = 0.0
        self.cont_scale = 1.0

        self.restoreWindowState()

        if g.config.vars.AutoStart.autostart_enable:
            self.filename = qstr_encode(g.config.vars.AutoStart.autostart_dir)
            if len(self.filename) > 0:
                self.load()
Beispiel #8
0
    def createGaussianBlurLayer(self):
        layerContent = Layers([])
        layerContent.name = 'GaussianBlur'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'width'
        tempChildren.value = 3
        tempChildren.note = 'ksize.width'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'height'
        tempChildren.value = 3
        tempChildren.note = 'ksize.height'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'sigmaX'
        tempChildren.value = 0
        tempChildren.note = 'sigmaX'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'sigmaY'
        tempChildren.value = 0
        tempChildren.note = 'sigmaY'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)
Beispiel #9
0
class MainWindow(QMainWindow):
    """
    Main Class
    """

    # Define a QT signal that is emitted when the configuration changes.
    # Connect to this signal if you need to know when the configuration has
    # changed.
    configuration_changed = QtCore.pyqtSignal()

    def __init__(self, app):
        """
        Initialization of the Main window. This is directly called after the
        Logger has been initialized. The Function loads the GUI, creates the
        used Classes and connects the actions to the GUI.
        """
        QMainWindow.__init__(self)

        # Build the configuration window
        self.config_window = ConfigWindow(g.config.makeConfigWidgets(),
                                          g.config.var_dict,
                                          g.config.var_dict.configspec, self)
        self.config_window.finished.connect(self.updateConfiguration)

        self.app = app
        self.settings = QtCore.QSettings("py2cv", "py2cv")

        self.ui = Ui_MainWindow()

        self.ui.setupUi(self)
        self.showMaximized()

        self.cameraEnable = False

        self.canvas = self.ui.canvas
        self.canvas_scene = None

        self.TreeHandler = TreeHandler(self.ui)
        self.configuration_changed.connect(
            self.TreeHandler.updateConfiguration)

        if sys.version_info[0] == 2:
            error_message = QMessageBox(
                QMessageBox.Critical, 'ERROR',
                self.
                tr("Python version 2 is not supported, please use it with python version 3."
                   ))
            sys.exit(error_message.exec_())

        self.d2g = Project(self)

        self.createActions()
        self.connectToolbarToConfig()

        self.filename = ""

        # TCP Server
        if g.config.vars.Trigger.tcp_server_enable:
            self.server = QTcpServer()
            self.server.listen(QHostAddress.Any,
                               int(g.config.vars.Trigger.tcp_server_port))
            # Connection connect
            self.server.newConnection.connect(self.on_newConnection)
        self.entityRoot = None
        self.layerContents = Layers([])

        self.cont_dx = 0.0
        self.cont_dy = 0.0
        self.cont_rotate = 0.0
        self.cont_scale = 1.0

        self.restoreWindowState()

        if g.config.vars.AutoStart.autostart_enable:
            self.filename = qstr_encode(g.config.vars.AutoStart.autostart_dir)
            if len(self.filename) > 0:
                self.load()

    def on_newConnection(self):
        # Active clientConnection
        self.clientConnection = self.server.nextPendingConnection()
        # Receive Data
        self.clientConnection.readyRead.connect(self.on_readyRead)
        # Disconnected
        self.clientConnection.disconnected.connect(self.on_disConnect)

        logger.info(self.tr('New TCP Client Connected'))

        if g.config.vars.Camera.camera_enable:
            if len(g.config.vars.Camera.camera_num) > 2:
                # Local Camera Mode
                addr = g.config.vars.Camera.camera_num
            else:
                # RTSP Camera Mode
                addr = int(g.config.vars.Camera.camera_num)
            # Init Camera
            self.cap = cv2.VideoCapture(addr, cv2.CAP_DSHOW)
            logger.info(self.tr('Camera Initialize Finish'))
        pass

    def on_disConnect(self):
        # If TCP Disconnected, Release Camera
        logger.info(self.tr('TCP Client Disconnected'))
        if hasattr(self, 'cap'):
            self.cap.release()
            logger.info(self.tr('Camera Released'))

    def on_readyRead(self):
        # Incoming Data, Check with trigger word
        readData = self.clientConnection.readAll()
        readStr = str(readData, encoding='ascii')
        if readStr == g.config.vars.Trigger.tcp_server_letter:
            logger.info(self.tr('TCP Trigger Accepted'))
            # Got one frame and process
            self.startCameraShoot()
        pass

    def startCameraShoot(self):
        self.openCameraShoot()
        # FIXME Need add something return vars
        if hasattr(self.layerContents, 'result'):
            sendData = str(self.layerContents.result).encode()
        else:
            sendData = 'Error'.encode()
        self.clientConnection.write(sendData)
        pass

    def tr(self, string_to_translate):
        """
        Translate a string using the QCoreApplication translation framework
        @param: string_to_translate: a unicode string
        @return: the translated unicode string if it was possible to translate
        """
        return str(
            QtCore.QCoreApplication.translate('MainWindow',
                                              string_to_translate))

    def createActions(self):
        """
        Create the actions of the main toolbar.
        @purpose: Links the callbacks to the actions in the menu
        """

        # File
        self.ui.actionOpenFile.triggered.connect(self.open)
        self.ui.actionReload.triggered.connect(self.reload)
        self.ui.actionSaveProjectAs.triggered.connect(self.saveProject)
        self.ui.actionClose.triggered.connect(self.close)
        self.ui.actionOpenCamera.triggered.connect(self.openCamera)

        # Export
        self.ui.actionImageExport.triggered.connect(self.exportShapes)

        # Button
        self.ui.bOpenFile.clicked.connect(self.open)
        self.ui.bOpenCamera.clicked.connect(self.openCamera)
        self.ui.bAddLayout.clicked.connect(self.layerCreate)
        self.ui.bExport.clicked.connect(self.exportShapes)

        # Layout
        self.ui.layerCreatePushButton.clicked.connect(self.layerCreate)
        self.ui.layerDeletePushButton.clicked.connect(self.layerDelete)

        # View
        self.ui.actionAutoscale.triggered.connect(self.canvas.autoscale)

        # Options
        self.ui.actionConfiguration.triggered.connect(self.config_window.show)

        # Help
        self.ui.actionAbout.triggered.connect(self.about)

    def connectToolbarToConfig(self, project=False, block_signals=True):
        pass

    def keyPressEvent(self, event):
        """
        Rewritten KeyPressEvent to get other behavior while Shift is pressed.
        @purpose: Changes to ScrollHandDrag while Control pressed
        @param event:    Event Parameters passed to function
        """
        if event.isAutoRepeat():
            return
        if event.key() == QtCore.Qt.Key_Control:
            # Stop Camera Flow Mode
            self.cameraEnable = not self.cameraEnable
        elif event.key() == QtCore.Qt.Key_Shift:
            self.canvas.setDragMode(QGraphicsView.ScrollHandDrag)

    def keyReleaseEvent(self, event):
        """
        Rewritten KeyReleaseEvent to get other behavior while Shift is pressed.
        @purpose: Changes to RubberBandDrag while Control released
        @param event:    Event Parameters passed to function
        """
        if event.key() == QtCore.Qt.Key_Control:
            pass
        elif event.key() == QtCore.Qt.Key_Shift:
            self.canvas.setDragMode(QGraphicsView.NoDrag)

    def enableToolbarButtons(self, status=True):
        # File
        self.ui.actionReload.setEnabled(status)
        self.ui.actionSaveProjectAs.setEnabled(status)

        # Export
        self.ui.actionImageExport.setEnabled(status)

        # View
        self.ui.actionAutoscale.setEnabled(status)

        # Button
        self.ui.bAddLayout.setEnabled(status)
        self.ui.bExport.setEnabled(status)

    def exportShapes(self, status=False, saveas=None):
        if hasattr(self, 'imglist'):
            imageWrite = self.imglist[len(self.imglist) - 1]
            filename = self.showSaveDialog(self.tr('Export to file'),
                                           '*.jpg')[0]
            if len(filename) > 0:
                try:
                    cv2.imwrite(filename, imageWrite)
                    logger.info(self.tr("Export to FILE was successful"))
                except Exception as e:
                    logger.error(self.tr('Error with %s') % str(e))
                    QMessageBox.warning(g.window, self.tr("Error"),
                                        self.tr("Error with:\n%s") % str(e))

    def showSaveDialog(self, title, MyFormats):
        """
        This function is called by the menu "Export/Export Shapes" of the main toolbar.
        It creates the selection dialog for the exporter
        @return: Returns the filename of the selected file.
        """

        (beg, ende) = os.path.split(self.filename)
        (fileBaseName, fileExtension) = os.path.splitext(ende)

        default_name = os.path.join(os.path.dirname(self.filename),
                                    fileBaseName)
        #default_name = os.path.join(g.config.vars.Paths['output_dir'], fileBaseName)

        selected_filter = "*.jpg"
        filename = getSaveFileName(self, title, default_name, MyFormats,
                                   selected_filter)
        if len(filename[0]) > 0:
            logger.info(self.tr("File: %s selected") % filename[0])
            logger.info("<a href='%s'>%s</a>" % (filename[0], filename[0]))
        else:
            logger.info(self.tr("File Select Canceled"))
        return filename

    def about(self):
        """
        This function is called by the menu "Help/About" of the main toolbar and
        creates the About Window
        """

        message = self.tr(
            "<html>"
            "<h2><center>You are using</center></h2>"
            "<body bgcolor="
            "<center><h2>PY2CV - Python Opencv Industrial Vision</h2></center></body>"
            "<h2>Version:</h2>"
            "<body>%s: %s<br>"
            "Last change: %s<br>"
            "Changed by: %s<br></body>"
            "<h2>Where to get help:</h2>"
            "For more information and updates, "
            "please visit "
            "<a href='https://github.com/feecat/PY2CV'>https://github.com/feecat/PY2CV</a><br>"
            "<h2>License and copyright:</h2>"
            "<body>This program is written in Python and is published under the "
            "<a href='http://www.gnu.org/licenses/'>GNU GPLv3 license.</a><br>"
            "</body></html>") % (c.VERSION, c.REVISION, c.DATE, c.AUTHOR)

        AboutDialog(title=self.tr("About PY2CV"), message=message)

    def setMeasurementUnits(self, metric, refresh_ui=False):
        """
        Change the measurement units used in DXF file.
        Helps if py2cv was unable to detect the correct units.
        """

        if (g.config.metric != metric) or refresh_ui:
            logger.info(self.tr("Drawing units: Pixel"))

    def open(self):
        """
        This function is called by the menu "File/Load File" of the main toolbar.
        It creates the file selection dialog and calls the load function to
        load the selected file.
        """

        self.OpenFileDialog(self.tr("Open file"))

        # If there is something to load then call the load function callback
        if self.filename:
            self.cont_dx = 0.0
            self.cont_dy = 0.0
            self.cont_rotate = 0.0
            self.cont_scale = 1.0

            self.load()

    def OpenFileDialog(self, title):
        if len(self.filename) > 0:
            paths = os.path.dirname(self.filename)
        else:
            paths = g.config.vars.Paths['import_dir']
        self.filename, _ = getOpenFileName(
            self, title, paths,
            self.
            tr("All supported files (*.jpg *.jpeg *.jpe *.jfif *.bmp *.dib *.png *%s);;"
               "Project files (*%s);;"
               "JPEG files(*.jpg *.jpeg *.jpe *.jfif);;"
               "BMP files(*.bmp *.dib);;"
               "PNG files(*.png);;"
               "All types (*.*)") % (c.PROJECT_EXTENSION, c.PROJECT_EXTENSION))

        # If there is something to load then call the load function callback
        if self.filename:
            self.filename = qstr_encode(self.filename)
            logger.info(self.tr("File: %s selected") % self.filename)

    def openCamera(self):
        self.cameraEnable = True
        QMessageBox.warning(
            g.window, self.tr("Warning"),
            self.tr(
                "Will enter the streaming mode, press the CTRL key to exit."))
        if g.config.vars.Camera.camera_enable:
            if len(g.config.vars.Camera.camera_num) > 2:
                addr = g.config.vars.Camera.camera_num
            else:
                addr = int(g.config.vars.Camera.camera_num)
            if hasattr(self, 'cap'):
                self.cap.release()
            self.cap = cv2.VideoCapture(addr, cv2.CAP_DSHOW)
            while True:
                if self.cameraEnable:
                    #schdule.enter(0.1,1,self.openCameraContinueMode1,())
                    #schdule.run()
                    try:
                        self.openCameraShoot()
                    except Exception as e:
                        logger.error(self.tr('Error with %s') % str(e))
                        QMessageBox.warning(
                            g.window, self.tr("Error"),
                            self.tr("Error with:\n%s") % str(e))
                        self.cap.release()
                        return
                    time.sleep(0.05)
                else:
                    self.cap.release()
                    return

    def openCameraShoot(self):
        ret, frame = self.cap.read()
        # FIXME if only one cap.read() it just got the LAST frame, not actual frame. this can be test in tcp trigger mode.
        ret, frame = self.cap.read()
        if ret == False:
            raise AssertionError("None frame capture")
        self.setWindowTitle("PY2CV - [%s]" % self.filename)
        self.canvas.resetAll()
        logger.info(self.tr('Loading Video Frame'))
        self.img = frame
        self.imglist = []
        self.imglist.append(self.img)
        self.imgshow()
        if len(self.layerContents) > 0:
            # self.TreeHandler.buildEntitiesTree(self.layerContents)
            self.updateOpencv()
        self.app.processEvents()

    def load(self, plot=True):
        """
        Loads the file given by self.filename.  Also calls the command to
        make the plot.
        @param plot: if it should plot
        """
        if len(self.filename) < 1:
            self.setWindowTitle("PY2CV - [%s]" % self.filename)
            self.canvas.resetAll()
            self.app.processEvents()
            if len(self.layerContents) > 0:
                self.TreeHandler.buildEntitiesTree(self.layerContents)
                self.updateOpencv()
            self.unsetCursor()
            return True
        if not QtCore.QFile.exists(self.filename):
            logger.info(self.tr("Cannot locate file: %s") % self.filename)
            self.OpenFileDialog(
                self.tr("Manually open file: %s") % self.filename)
            if not self.filename:
                return False  # cancelled

        self.setCursor(QtCore.Qt.WaitCursor)
        self.setWindowTitle("PY2CV - [%s]" % self.filename)
        self.canvas.resetAll()
        self.app.processEvents()

        (name, ext) = os.path.splitext(self.filename)

        if ext.lower() == c.PROJECT_EXTENSION:
            self.loadProject(self.filename)
            return True  # kill this load operation - we opened a new one

        logger.info(self.tr('Loading file: %s') % self.filename)

        self.img = cv2.imread(self.filename)
        self.imglist = []
        self.imglist.append(self.img)
        if plot:
            self.imgshow()

        if len(self.layerContents) > 0:
            self.TreeHandler.buildEntitiesTree(self.layerContents)
            self.updateOpencv()
        return True

    def imgshow(self):
        # Populate the treeViews
        #self.TreeHandler.buildEntitiesTree(self.entityRoot)

        # Paint the canvas
        self.canvas_scene = MyGraphicsScene()
        self.canvas.setScene(self.canvas_scene)
        # show image
        self.canvas_scene.plotAll(self)
        self.canvas.show()
        self.canvas.setFocus()
        self.canvas.autoscale()

        # After all is plotted enable the Menu entities
        self.enableToolbarButtons()
        self.unsetCursor()

    def updateOpencv(self):
        #clean first
        if hasattr(self, 'img'):
            self.imglist.clear()
            self.imglist.append(self.img)
            if len(self.layerContents) > 0 and hasattr(self, 'img'):
                for layerContent in self.layerContents:
                    if layerContent.enable > 0:
                        try:
                            if layerContent.name == 'Canny':
                                self.imglist.append(
                                    cv2.Canny(
                                        self.imglist[len(self.imglist) - 1],
                                        layerContent.children[0].value,
                                        layerContent.children[1].value))
                            if layerContent.name == 'cvtColor':
                                self.imglist.append(
                                    cv2.cvtColor(
                                        self.imglist[len(self.imglist) - 1],
                                        cv2.COLOR_RGB2GRAY))
                            if layerContent.name == 'threshold':
                                if layerContent.children[2] == 1:
                                    ret, th = cv2.threshold(
                                        self.imglist[len(self.imglist) - 1],
                                        layerContent.children[0].value,
                                        layerContent.children[1].value,
                                        cv2.THRESH_BINARY +
                                        cv2.THRESH_TRIANGLE)
                                else:
                                    ret, th = cv2.threshold(
                                        self.imglist[len(self.imglist) - 1],
                                        layerContent.children[0].value,
                                        layerContent.children[1].value,
                                        cv2.THRESH_BINARY + cv2.THRESH_OTSU)
                                self.imglist.append(th)
                            if layerContent.name == 'GaussianBlur':
                                self.imglist.append(
                                    cv2.GaussianBlur(
                                        self.imglist[len(self.imglist) - 1],
                                        (layerContent.children[0].value,
                                         layerContent.children[1].value),
                                        layerContent.children[2].value))
                            if layerContent.name == 'findContours':
                                contours, hierarchy = cv2.findContours(
                                    self.imglist[len(self.imglist) - 1],
                                    cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
                                self.imglist.append(
                                    cv2.drawContours(self.imglist[0].copy(),
                                                     contours, -1,
                                                     (255, 0, 255), 2))
                                self.imglist[0] = self.img
                            if layerContent.name == 'HoughLines':
                                lines = []
                                lines.clear()
                                lines = cv2.HoughLines(
                                    self.imglist[len(self.imglist) - 1],
                                    layerContent.children[0].value,
                                    layerContent.children[1].value,
                                    layerContent.children[2].value)
                                if hasattr(lines, 'size'):
                                    self.imglist.append(self.imglist[0].copy())
                                    self.imglist[0] = self.img
                                    for line in lines:
                                        rho, theta = line[0]
                                        a = np.cos(theta)
                                        b = np.sin(theta)
                                        x0 = a * rho
                                        y0 = b * rho
                                        x1 = int(x0 + 1000 * (-b))
                                        y1 = int(y0 + 1000 * (a))
                                        x2 = int(x0 - 1000 * (-b))
                                        y2 = int(y0 - 1000 * (a))
                                        cv2.line(
                                            self.imglist[len(self.imglist) -
                                                         1], (x1, y1),
                                            (x2, y2), (0, 0, 255),
                                            2,
                                            lineType=cv2.LINE_AA)
                                    self.layerContents.result = lines
                            if layerContent.name == 'HoughLinesP':
                                lines = []
                                lines.clear()
                                lines = cv2.HoughLinesP(
                                    self.imglist[len(self.imglist) - 1],
                                    layerContent.children[0].value,
                                    layerContent.children[1].value,
                                    layerContent.children[2].value,
                                    minLineLength=layerContent.children[3].
                                    value,
                                    maxLineGap=layerContent.children[4].value)
                                if hasattr(lines, 'size'):
                                    self.imglist.append(self.imglist[0].copy())
                                    self.imglist[0] = self.img
                                    for line in lines:
                                        x1, y1, x2, y2 = line[0]
                                        cv2.line(
                                            self.imglist[len(self.imglist) -
                                                         1], (x1, y1),
                                            (x2, y2), (0, 255, 0),
                                            1,
                                            lineType=cv2.LINE_AA)
                                    self.layerContents.result = lines
                            if layerContent.name == 'HoughCircles':
                                circles = []
                                circles.clear()
                                circles = cv2.HoughCircles(
                                    self.imglist[len(self.imglist) - 1],
                                    cv2.HOUGH_GRADIENT,
                                    layerContent.children[0].value,
                                    layerContent.children[1].value,
                                    param1=layerContent.children[2].value,
                                    param2=layerContent.children[3].value,
                                    minRadius=int(
                                        layerContent.children[4].value),
                                    maxRadius=int(
                                        layerContent.children[5].value))
                                if hasattr(circles, 'size'):
                                    self.imglist.append(self.imglist[0].copy())
                                    self.imglist[0] = self.img
                                    for i in circles[0, :]:
                                        cv2.circle(
                                            self.imglist[len(self.imglist) -
                                                         1], (i[0], i[1]),
                                            int(i[2]), (0, 255, 0), 2)
                                        cv2.circle(
                                            self.imglist[len(self.imglist) -
                                                         1], (i[0], i[1]), 2,
                                            (0, 0, 255), 3)
                                    self.layerContents.result = circles
                        except Exception as e:
                            logger.error(self.tr('Error with %s') % str(e))
                            # Disable act layer and update tree view
                            layerContent.enable = 0
                            self.TreeHandler.buildEntitiesTree(
                                self.layerContents)
                            QMessageBox.warning(
                                g.window, self.tr("Error"),
                                self.tr("Error with:\n%s") % str(e))

            self.canvas_scene.plotAll(self)
            pass

    def layerCreate(self):
        """
        This function is called when the Option=>Move WP Zero Menu is clicked.
        """
        title = self.tr('Create CV2 Layer')
        #label = [self.tr("Offset %s axis :") % (g.config.vars.Axis_letters['ax1_letter']),
        #         self.tr("Offset %s axis :") % (g.config.vars.Axis_letters['ax2_letter'])]
        #value = [self.cont_dx, self.cont_dy]
        label = [
            self.tr("Canny"),
            self.tr("GaussianBlur"),
            self.tr("cvtColor"),
            self.tr("findContours"),
            self.tr("HoughLines"),
            self.tr("HoughLinesP"),
            self.tr("HoughCircles"),
            self.tr("threshold"),
        ]
        abc = 0
        value = [abc]

        layerCreateDialog = PopUpDialog(title, label, value, True)

        if layerCreateDialog.result is None:
            return

        if self.entityRoot == None:
            self.entityRoot = []

        if layerCreateDialog.result == 'Canny':
            self.createCannyLayer()
        elif layerCreateDialog.result == 'GaussianBlur':
            self.createGaussianBlurLayer()
        elif layerCreateDialog.result == 'cvtColor':
            self.createcvtColorLayer()
        elif layerCreateDialog.result == 'findContours':
            self.createfindContoursLayer()
        elif layerCreateDialog.result == 'HoughLines':
            self.createHoughLinesLayer()
        elif layerCreateDialog.result == 'HoughLinesP':
            self.createHoughLinesPLayer()
        elif layerCreateDialog.result == 'HoughCircles':
            self.createHoughCirclesLayer()
        elif layerCreateDialog.result == 'threshold':
            self.createthresholdLayer()

        self.updateOpencv()

    def createcvtColorLayer(self):
        layerContent = Layers([])
        layerContent.name = 'cvtColor'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'low'
        tempChildren.value = 50
        tempChildren.note = 'threshold1'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createCannyLayer(self):
        layerContent = Layers([])
        layerContent.name = 'Canny'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'low'
        tempChildren.value = 50
        tempChildren.note = 'threshold1'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'high'
        tempChildren.value = 100
        tempChildren.note = 'threshold2'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createGaussianBlurLayer(self):
        layerContent = Layers([])
        layerContent.name = 'GaussianBlur'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'width'
        tempChildren.value = 3
        tempChildren.note = 'ksize.width'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'height'
        tempChildren.value = 3
        tempChildren.note = 'ksize.height'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'sigmaX'
        tempChildren.value = 0
        tempChildren.note = 'sigmaX'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'sigmaY'
        tempChildren.value = 0
        tempChildren.note = 'sigmaY'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createfindContoursLayer(self):
        layerContent = Layers([])
        layerContent.name = 'findContours'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'RM'
        tempChildren.value = cv2.RETR_TREE
        tempChildren.note = 'RetrievalModes'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'CAM'
        tempChildren.value = cv2.CHAIN_APPROX_SIMPLE
        tempChildren.note = 'ContourApproximationModes'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createHoughLinesLayer(self):
        layerContent = Layers([])
        layerContent.name = 'HoughLines'
        layerContent.children = []
        layerContent.enable = 1

        tempChildren = Layers([])
        tempChildren.name = 'rho'
        tempChildren.value = 0.8
        tempChildren.note = 'Distance resolution'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'theta'
        tempChildren.value = 0.01
        tempChildren.note = 'Angle resolution'
        layerContent.children.append(tempChildren)

        tempChildren = Layers([])
        tempChildren.name = 'threshold'
        tempChildren.value = 100
        tempChildren.note = 'Accumulator threshold parameter'
        layerContent.children.append(tempChildren)

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createHoughLinesPLayer(self):
        layerContent = Layers([])
        layerContent.name = 'HoughLinesP'
        layerContent.children = []
        tempChildren = Layers([])
        layerContent.enable = 1

        tempChildren.name = 'rho'
        tempChildren.value = 0.8
        tempChildren.note = 'Distance resolution'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'theta'
        tempChildren.value = 0.01
        tempChildren.note = 'Angle resolution'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'threshold'
        tempChildren.value = 100
        tempChildren.note = 'Accumulator threshold parameter'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'minLineLength'
        tempChildren.value = 10
        tempChildren.note = 'Minimum line length'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'maxLineGap'
        tempChildren.value = 500
        tempChildren.note = 'Maximum allowed gap'
        layerContent.children.append(deepcopy(tempChildren))

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createthresholdLayer(self):
        layerContent = Layers([])
        layerContent.name = 'threshold'
        layerContent.children = []
        tempChildren = Layers([])
        layerContent.enable = 1

        tempChildren.name = 'thresh'
        tempChildren.value = 0
        tempChildren.note = 'thresh'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'maxval'
        tempChildren.value = 255
        tempChildren.note = 'maxval'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'triangle'
        tempChildren.value = 0
        tempChildren.note = '0=otsu,1=triangle'
        layerContent.children.append(deepcopy(tempChildren))

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def createHoughCirclesLayer(self):
        layerContent = Layers([])
        layerContent.name = 'HoughCircles'
        layerContent.children = []
        tempChildren = Layers([])

        tempChildren.name = 'dp'
        tempChildren.value = 1.5
        tempChildren.note = 'Inverse ratio'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'minDist'
        tempChildren.value = 100
        tempChildren.note = 'Minimum distance between two circles'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'param1'
        tempChildren.value = 100
        tempChildren.note = 'do not change'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'param2'
        tempChildren.value = 30
        tempChildren.note = 'do not change'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'minRadius'
        tempChildren.value = 10
        tempChildren.note = 'Minimum circle radius'
        layerContent.children.append(deepcopy(tempChildren))

        tempChildren.name = 'maxRadius'
        tempChildren.value = 0
        tempChildren.note = 'Maximum circle radius'
        layerContent.children.append(deepcopy(tempChildren))

        self.layerContents.append(layerContent)
        self.TreeHandler.buildEntitiesTree(self.layerContents)

    def layerDelete(self):
        if self.TreeHandler.ui.entitiesTreeView.selectionModel() != None:
            selectedRows = self.TreeHandler.ui.entitiesTreeView.selectionModel(
            ).selectedRows()
            if len(selectedRows) > 0:
                if selectedRows[0].parent().row() == -1:
                    # no parent
                    row = selectedRows[0].row()
                else:
                    # have parent
                    row = selectedRows[0].parent().row()
                self.layerContents.pop(row)
                self.TreeHandler.buildEntitiesTree(self.layerContents)
                logger.debug(self.tr("removed layer: %s" % str(row)))
                self.updateOpencv()
                return
        logger.debug(self.tr("nothing remove"))

    def layerMoveUp(self):
        pass

    def layerMoveDown(self):
        pass

    def reload(self):
        """
        This function is called by the menu "File/Reload File" of the main toolbar.
        It reloads the previously loaded file (if any)
        """
        if self.filename:
            logger.info(self.tr("Reloading file: %s") % self.filename)
            self.load()

    def updateConfiguration(self, result):
        """
        Some modification occured in the configuration window, we need to save these changes into the config file.
        Once done, the signal configuration_changed is emitted, so that anyone interested in this information can connect to this signal.
        """
        if result == ConfigWindow.Applied or result == ConfigWindow.Accepted:
            # Write the configuration into the config file (config.cfg)
            g.config.save_varspace()
            # Rebuild the readonly configuration structure
            g.config.update_config()

            # Assign changes to the menus (if no change occured, nothing
            # happens / otherwise QT emits a signal for the menu entry that has changed)
            self.connectToolbarToConfig(block_signals=False)

            # Inform about the changes into the configuration
            self.configuration_changed.emit()

    def loadProject(self, filename):
        """
        Load all variables from file
        """
        # since Py3 has no longer execfile -  we need to open it manually
        file_ = open(filename, 'r')
        str_ = file_.read()
        file_.close()
        self.d2g.load(str_)

    def saveProject(self):
        """
        Save all variables to file
        """
        prj_filename = self.showSaveDialog(
            self.tr('Save project to file'),
            "Project files (*%s)" % c.PROJECT_EXTENSION)
        save_prj_filename = qstr_encode(prj_filename[0])

        # If Cancel was pressed
        if not save_prj_filename:
            return

        (beg, ende) = os.path.split(save_prj_filename)
        (fileBaseName, fileExtension) = os.path.splitext(ende)

        if fileExtension != c.PROJECT_EXTENSION:
            if not QtCore.QFile.exists(save_prj_filename):
                save_prj_filename += c.PROJECT_EXTENSION

        pyCode = self.d2g.export()
        try:
            # File open and write
            f = open(save_prj_filename, "w")
            f.write(str_encode(pyCode))
            f.close()
            logger.info(self.tr("Save project to FILE was successful"))
        except IOError:
            QMessageBox.warning(g.window,
                                self.tr("Warning during Save Project As"),
                                self.tr("Cannot Save the File"))

    def closeEvent(self, e):
        logger.debug(self.tr("Closing"))
        self.saveWindowState()
        self.cameraEnable = False
        e.accept()

    def restoreWindowState(self):
        self.settings.beginGroup("MainWindow")
        geometry = self.settings.value("geometry")
        state = self.settings.value("state")
        self.settings.endGroup()
        if (geometry is not None) and (state is not None):
            self.restoreGeometry(geometry)
            self.restoreState(state)

    def saveWindowState(self):
        self.settings.beginGroup("MainWindow")
        self.settings.setValue("geometry", self.saveGeometry())
        self.settings.setValue("state", self.saveState())
        self.settings.endGroup()
Beispiel #10
0
    def load(self, content, compleet=True):
        match = re.match(
            Project.header.replace('+', '\+') % r'(\d+\.\d+)', content)
        if not match:
            raise Exception('Incorrect project file')
        version = float(match.groups()[0])
        if version not in Project.supported_versions:
            raise VersionMismatchError(match.group(), Project.version)

        execute(self, content)

        if compleet:
            self.parent.filename = self.file

            self.parent.connectToolbarToConfig(True)
            if not self.parent.load(False):
                self.parent.unsetCursor()
                return

        layers = []
        layer = Layers([])
        for parent_layer in self.layers:
            layer.name = parent_layer['name']
            layer.enable = parent_layer['enable']
            layer.children = []

            tempLayer = Layers([])
            for shape in parent_layer['shapes']:
                tempLayer.clear()
                tempLayer.name = shape['name']
                tempLayer.value = shape['value']
                tempLayer.note = shape['note']
                layer.children.append(deepcopy(tempLayer))

            layers.append(deepcopy(layer))

        self.parent.layerContents = Layers(layers)  # overwrite original
        self.parent.load()