示例#1
0
class waterfallWidget(QtGui.QWidget):
    """Widget for plotting a waterfall plot.
    """
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.layout = QtGui.QHBoxLayout(self)
        self.viewport = GraphicsLayoutWidget()
        self.view = self.viewport.addViewBox(colspan=3,
                                             rowspan=3,
                                             lockAspect=False,
                                             enableMenu=True)
        self.img = pg.ImageItem()
        self.view.addItem(self.img)

        # Get the colormap
        colormap = cm.get_cmap("jet")
        colormap._init()
        lut = (colormap._lut * 255).view(
            np.ndarray
        )  # Convert matplotlib colormap from 0-1 to 0 -255 for Qt
        # Apply the colormap
        self.img.setLookupTable(lut)

        self.h = self.viewport.addViewBox(enableMenu=False, colspan=3)
        self.hist = pg.HistogramLUTItem(image=self.img, fillHistogram=False)
        self.hist.setImageItem(self.img)
        self.h.addItem(self.hist)

        self.imv = pg.ImageView(view=self.view, imageItem=self.img)

        self.layout.addWidget(self.imv)
        self.setLayout(self.layout)
示例#2
0
class waterfallWidget(QtGui.QWidget):
    """Widget for plotting a waterfall plot.
    """
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.layout = QtGui.QHBoxLayout(self)
        self.viewport = GraphicsLayoutWidget()
        self.view = self.viewport.addViewBox(colspan=3,
                                             rowspan=3,
                                             lockAspect=False,
                                             enableMenu=True)
        self.img = pg.ImageItem()
        self.view.addItem(self.img)

        self.h = self.viewport.addViewBox(enableMenu=False, colspan=3)
        self.hist = pg.HistogramLUTItem(image=self.img, fillHistogram=False)
        self.hist.setImageItem(self.img)
        self.h.addItem(self.hist)

        self.imv = pg.ImageView(view=self.view, imageItem=self.img)

        self.layout.addWidget(self.imv)
        self.setLayout(self.layout)
示例#3
0
class viewerWidget(QtGui.QWidget):
    """Widget for holding the GUI elements of the viewer.
    """
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.layout = QtGui.QVBoxLayout(self)

        self.viewport = GraphicsLayoutWidget()
        self.view = self.viewport.addViewBox(enableMenu=True)
        self.img = pg.ImageItem()
        self.view.addItem(self.img)

        self.buttons = QtGui.QHBoxLayout()
        self.startButton = QtGui.QPushButton('Start')
        self.stopButton = QtGui.QPushButton('Stop')
        self.buttons.addWidget(self.startButton)
        self.buttons.addWidget(self.stopButton)

        self.setLayout(self.layout)
        self.layout.addWidget(self.viewport)
        self.layout.addLayout(self.buttons)
示例#4
0
    def create_sliders(self, width, height):
        """Creates the sliders, label for the slider, 
           text with value of slider and the percentage sign."""
        font = QtGui.QFont()

        x_pos = [int(width * x) for x in [0.05, 0.3, 0.55]]
        y_pos = [int(height * y) for y in [0.24, 0.33, 0.80]]
        wid = [int(width * x) for x in [0.15, 0.05, 0.04]]
        hei = [int(height * y) for y in [0.09, 0.44, 0.09]]
        i = 0

        for mode in self.mode:
            font.setPixelSize(int(height * 0.07))
            exec(f"self.{mode}_power_title = QtWidgets.QLabel(self)")
            exec(f"self.{mode}_power_title.setFont(font)")
            exec(
                f"self.{mode}_power_title.setAlignment(QtCore.Qt.AlignCenter)")
            exec(
                f"self.{mode}_power_title.setText('{self.mode_nl[self.mode.index(mode)]}')"
            )
            exec(
                f"self.{mode}_power_title.setGeometry(QtCore.QRect({x_pos[i]}, {y_pos[0]},"
                f"{wid[0]}, {hei[0]}))")

            font.setPixelSize(int(height * 0.03))
            exec(f"self.{mode}_power_value = QtWidgets.QLCDNumber(self)")
            exec(
                f"self.{mode}_power_value.setGeometry({x_pos[i]}, {y_pos[2]}, {wid[0]}, {hei[2]})"
            )
            exec(f"self.{mode}_power_value.setFont(font)")
            exec(f"self.{mode}_power_value.setDigitCount(3)")
            exec(f"self.{mode}_power_value.display(0)")

            exec(f"self.{mode}_power_slider = QtWidgets.QSlider(self)")
            exec(f"self.{mode}_power_slider.setMaximum(100)")
            exec(
                f"self.{mode}_power_slider.setOrientation(QtCore.Qt.Vertical)")
            exec(
                f"self.{mode}_power_slider.setGeometry({x_pos[i]}, {y_pos[1]},"
                f"{wid[0]}, {hei[1]})")
            exec(
                f"self.{mode}_power_slider.valueChanged.connect(self.{mode}_power_value.display)"
            )
            exec(
                f"self.{mode}_power_slider.sliderReleased.connect(self.update_data_manager)"
            )

            font.setPixelSize(int(height * 0.07))
            exec(f"self.{mode}_power_symb = QtWidgets.QLabel(self)")
            exec(
                f"self.{mode}_power_symb.setGeometry({x_pos[i] + int(width * 0.125)}, {y_pos[2]},"
                f"{wid[2]}, {hei[2]})")
            exec(f"self.{mode}_power_symb.setText('%')")
            exec(f"self.{mode}_power_symb.setFont(font)")

            i += 1

        font.setPixelSize(int(height * 0.07))
        self.opslag_title = QtWidgets.QLabel(self)
        self.opslag_title.setFont(font)
        self.opslag_title.setAlignment(QtCore.Qt.AlignCenter)
        self.opslag_title.setText('Opslaan')
        fac_scale = 0.2
        self.opslag_title.setGeometry(
            QtCore.QRect(int(width * 0.8 - hei[0] * fac_scale / 2), y_pos[0],
                         wid[0] * (1 + fac_scale), hei[0]))
        self.opslag_title.setStyleSheet(
            "QLabel { color : rgba(21, 255, 0, 255); }")

        self.bijspring_title = QtWidgets.QLabel(self)
        self.bijspring_title.setFont(font)
        self.bijspring_title.setAlignment(QtCore.Qt.AlignCenter)
        self.bijspring_title.setText('Verbruiken')
        self.bijspring_title.setGeometry(
            QtCore.QRect(int(width * 0.8 - hei[0] * fac_scale / 2), y_pos[2],
                         wid[0] * (1 + fac_scale), hei[0]))
        self.bijspring_title.setStyleSheet("QLabel {color : red; }")
        font.setPixelSize(int(height * 0.03))

        overhead3 = GraphicsLayoutWidget(self)
        overhead3.setGeometry(
            QtCore.QRect(int(width * 0.85), int(y_pos[1] + +0.49 * hei[1]),
                         int(width * 0.05), int(0.02 * hei[1])))
        overhead3.setBackground('w')

        self.h2_slide = QtWidgets.QSlider(self)
        self.h2_slide.setRange(-100, 100)
        self.h2_slide.setOrientation(QtCore.Qt.Vertical)
        self.h2_slide.setGeometry(int(width * 0.8), y_pos[1], wid[0], hei[1])
        self.h2_slide.setStyleSheet(
            """QSlider {background-color: rgba(255, 255, 255, 0)}
              QSlider::handle:vertical {
                                background: black;
                                margin: 0 -80px;
                                border: 1px solid;
                                height: 10px;
                                     }
              QSlider::groove:vertical {
                                background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0             
                                                         green, stop:1 
                                                         red);
                                width: 10px;
                                margin: 0 -5px;
                                
                                     }    """)
        overhead = GraphicsLayoutWidget(self)
        overhead.setGeometry(
            QtCore.QRect(int(width * 0.8), y_pos[1], wid[0], hei[1]))
        overhead.setBackground(None)
        overhead2 = overhead.addViewBox(enableMouse=False)
        overhead2.setBackgroundColor(None)
        overhead2.setAutoPan(False, False)

        self.data_manager.h2_slide = self.h2_slide
示例#5
0
class monitorMainWidget(QtGui.QWidget):
    """Widget for holding the images generated by the camera.
    """
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        # General layout of the widget to hold an image and a histogram
        self.layout = QtGui.QHBoxLayout(self)

        # Settings for the image
        self.viewport = GraphicsLayoutWidget()
        self.view = self.viewport.addViewBox(lockAspect=False, enableMenu=True)

        self.autoScale = QtGui.QAction("Auto Range", self.view.menu)
        self.autoScale.triggered.connect(self.doAutoScale)
        self.view.menu.addAction(self.autoScale)

        self.img = pg.ImageItem()
        self.view.addItem(self.img)
        self.imv = pg.ImageView(view=self.view, imageItem=self.img)

        # Add everything to the widget
        self.layout.addWidget(self.imv)
        self.setLayout(self.layout)

        self.showCrosshair = False
        self.showCrossCut = False

    def setup_overlay(self):
        # useful if one want to plot the recovered trajectory in the camera viewport
        self.img2 = pg.ImageItem()  # To overlay another image if needed.
        self.img2.setOpacity(0.4)
        self.img2.setZValue(1000)
        self.view.addItem(self.img2)

    def setup_cross_hair(self, max_size):
        """Sets up a cross hair."""
        self.crosshair = []
        self.crosshair.append(
            pg.InfiniteLine(angle=0,
                            movable=False,
                            pen={
                                'color': 124,
                                'width': 4
                            }))
        self.crosshair.append(
            pg.InfiniteLine(angle=90,
                            movable=False,
                            pen={
                                'color': 124,
                                'width': 4
                            }))
        self.crosshair[0].setBounds((1, max_size[1] - 1))
        self.crosshair[1].setBounds((1, max_size[0] - 1))

    def setup_cross_cut(self, max_size):
        """Set ups the horizontal line for the cross cut."""
        self.crossCut = pg.InfiniteLine(angle=0,
                                        movable=False,
                                        pen={
                                            'color': 'g',
                                            'width': 2
                                        })
        self.crossCut.setBounds((1, max_size))

    def setup_roi_lines(self, max_size):
        """Sets up the ROI lines surrounding the image.
        
        :param list max_size: List containing the maximum size of the image to avoid ROIs bigger than the CCD."""

        self.hline1 = pg.InfiniteLine(angle=0,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.hline2 = pg.InfiniteLine(angle=0,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.vline1 = pg.InfiniteLine(angle=90,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.vline2 = pg.InfiniteLine(angle=90,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })

        self.vline2.setValue(max_size[0] - 1)
        self.hline2.setValue(max_size[1] - 1)
        self.hline1.setBounds((1, max_size[1] - 1))
        self.hline2.setBounds((1, max_size[1] - 1))
        self.vline1.setBounds((1, max_size[0] - 1))
        self.vline2.setBounds((1, max_size[0] - 1))
        self.view.addItem(self.hline1)
        self.view.addItem(self.hline2)
        self.view.addItem(self.vline1)
        self.view.addItem(self.vline2)

    def setup_mouse_tracking(self):
        self.imv.setMouseTracking(True)
        self.imv.getImageItem().scene().sigMouseMoved.connect(self.mouseMoved)
        self.imv.getImageItem().scene().contextMenu = None

    def keyPressEvent(self, key):
        """Triggered when there is a key press with some modifier.
        Shift+C: Removes the cross hair from the screen
        Ctrl+C: Emits a specialTask signal
        Ctrl+V: Emits a stopSpecialTask signal
        These last two events have to be handeled in the mainWindow that implemented this widget."""
        modifiers = QtGui.QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.ShiftModifier:
            if key.key() == 67:  # For letter C of 'Clear
                if self.showCrosshair:
                    for c in self.crosshair:
                        self.view.removeItem(c)
                    self.showCrosshair = False
                if self.showCrossCut:
                    self.view.removeItem(self.crossCut)
                    self.showCrossCut = False
        elif modifiers == QtCore.Qt.ControlModifier:
            if key.key() == 67:  # For letter C of 'Clear
                self.emit(QtCore.SIGNAL('specialTask'))
            if key.key() == 86:  # For letter V
                self.emit(QtCore.SIGNAL('stopSpecialTask'))

    def mouseMoved(self, arg):
        """Updates the position of the cross hair. The mouse has to be moved while pressing down the Ctrl button."""
        # arg = evt.pos()
        modifiers = QtGui.QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.ControlModifier:
            if not self.showCrosshair:
                for c in self.crosshair:
                    self.view.addItem(c)
                self.showCrosshair = True
            self.crosshair[1].setValue(int(self.img.mapFromScene(arg).x()))
            self.crosshair[0].setValue(int(self.img.mapFromScene(arg).y()))
        elif modifiers == QtCore.Qt.AltModifier:
            if not self.showCrossCut:
                self.view.addItem(self.crossCut)
            self.showCrossCut = True
            self.crossCut.setValue(int(self.img.mapFromScene(arg).y()))

    def doAutoScale(self):
        h, y = self.img.getHistogram()
        self.imv.setLevels(min(h), max(h))
        # self.img.HistogramLUTItem.setLevels(min(h),max(h))

    def drawTargetPointer(self, image, location):
        """gets an image and draws a square around the target location"""
        w = 5
        x0 = np.int(location[0])
        y0 = np.int(location[1])
        newimage = image / 2
        for x in range(w):
            newimage[x0 + x, y0 - w + x, 1] = 3000
            newimage[x0 - x, y0 - w + x, 2] = 6000
            newimage[x0 + x, y0 + w - x, 2] = 6000
            newimage[x0 - x, y0 + w - x, 1] = 3000

        return newimage
示例#6
0
    def initGUI(self):
        self.plot = PlotWidget()
        self.sensorplot = PlotWidget()

        self.schemeplot = PlotWidget()
        self.scheme_plot = UTILS_QT.myplot(self.schemeplot,xlabel = ['time', 's'], ylabel =['',''],logmode=False)
        self.psp = UTILS_QT.pulses_scheme_plot(self.scheme_plot)


        date_axis = TimeAxisItem(orientation='bottom')
        #date_axis = pg.graphicsItems.DateAxisItem.DateAxisItem(orientation = 'bottom')
        self.sensorplot = PlotWidget(axisItems = {'bottom': date_axis})


        win = GraphicsLayoutWidget()
        win2 = PlotWidget()



        self.view = win.addViewBox(border = 'w', invertY = True)
        self.view.setAspectLocked(True)
        self.img = ImageItem()
        self.plotaxes = win2.getPlotItem()
        #self.view.addItem(self.img)
        #self.view.addItem(self.plotaxes)
        #self.view.


        data = np.random.normal(size=(1, 600, 600), loc=1024, scale=64).astype(np.uint16)
        self.img.setImage(data[0])
        self.plotaxes.getViewBox().addItem(self.img)


        # colormap
        pos = np.array([0., 1., 0.5, 0.25, 0.75])
        #pos2 = np.array([1.0,0.75,0.5,0.25,0.])
        pos2 = np.array([0.,0.25,0.5,0.75,1.0])
        color2 = np.array([[255,242,15,255], [245,124,15,255],[170,69,16,255],[91,50,0,255],[0,0,0,255]],dtype=np.ubyte)
        color = np.array([[0,255,255,255], [255,255,0,255], [0,0,0,255], (0, 0, 255, 255), (255, 0, 0, 255)], dtype=np.ubyte)
        cmap = pg.ColorMap(pos2, color2)
        lut = cmap.getLookupTable(0.0, 1.0, 256)
        self.img.setLookupTable(lut)
        #self.img.setLevels([-50,1])

        self.tw = QtGui.QTabWidget()
        self.tw.addTab(win2,'ESR data')
        self.tw.addTab(self.sensorplot,'B field')
        self.tw.addTab(self.schemeplot,'Scheme')

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.plot)
        #layout.addWidget(win2)
        layout.addWidget(self.tw)

        self.setLayout(layout)

        self.p1 = self.plot.getPlotItem()
        self.p2 = self.plot.getPlotItem()

        self.ps = self.sensorplot.getPlotItem()
        #self.p1.addLegend()
        self.p1data = self.p1.plot([0],pen = 'r')
        self.p2data = self.p1.plot([0],pen = 'g')
        self.psdata = self.ps.plot([],pen = 'w')
        self.ps.setLabel('left','Magnetic field', 'uT')

        self.vLine5 = pg.InfiniteLine(angle=90, movable=True)
        self.vLine6 = pg.InfiniteLine(angle=90, movable=True)
        self.plotaxes.addItem(self.vLine5, ignoreBounds=True)
        self.plotaxes.addItem(self.vLine6, ignoreBounds=True)
class PlotWindow(QWidget):

    img_dict = pyqtSignal(object)

    def __init__(self):
        super(PlotWindow, self).__init__()
        self.layout = QHBoxLayout(self)

        pg.setConfigOptions(imageAxisOrder='row-major')
        self.viewport = GraphicsLayoutWidget()
        self.video_view = self.viewport.addViewBox()
        self.video = pg.ImageItem()
        # self.video_view.clicked.connect(self.btn_state)
        self.video_view.addItem(self.video)
        self.video_view.setMouseEnabled(x=False, y=False)#make it can not move
        self.img_label = 'no image'
        self.viewport.setToolTip(str(self.img_label))
        self.setLayout(self.layout)

        self.layout.addWidget(self.viewport)

        # self.push_btn = QPushButton("sent", self)
        # self.push_btn.clicked.connect(self.btn_state)
        # self.save_btn = QPushButton("save", self)
        # self.save_btn.clicked.connect(self.save_image)
        # self.horizontalLayout = QVBoxLayout()
        # self.horizontalLayout.addWidget(self.push_btn)
        # self.horizontalLayout.addWidget(self.save_btn)
        # self.horizontalLayout.addWidget(self.img_label)
        # self.layout.addLayout(self.horizontalLayout)

        screen = QtGui.QDesktopWidget().screenGeometry()
        # print(screen)
        self.setFixedSize(screen.width() * 15 / 100, screen.width() * (9/16)*(14 / 100))

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.btn_state()

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.save_image()

    # def enterEvent(self, event):
    #     pass
    #
    # def leaveEvent(self, event):
    #     pass

    def btn_state(self):
        if self.video.image is None:
            print("have no image in window")
            # from MainWindow import TestMainWindow
            # TestMainWindow.path.setTitle(str('have no image in window'))
            return
        # img_analyse_setting.roi.setChecked(False)
        img_dict = {'img_data': np.array(self.video.image), 'img_name': self.img_label}
        settings.imgData["Img_data"] = img_dict['img_data']
        self.img_dict.emit(img_dict)

    def save_image(self):
        # try:
        if self.video.image is None:
            print("have no image in window")
            return
        fpath = IOHelper.get_config_setting('DATA_PATH')
        fpath = Path(fpath)
        dir_path = fpath.joinpath(str(datetime.datetime.now())[2:].split('.')[0].replace(' ', '').replace(':', '_'))
        if settings.m_path != []:
            dir_path = settings.m_path
        # print("save images to {}".format(dir_path))
        if not dir_path.exists():
            dir_path.mkdir()
        img_data = np.array(self.video.image)
        # load image name by path
        img_name2 = (self.img_label)[0:20].replace(' ', '~').replace(':', '').replace('-', '')
        img_name = str(img_name2)
        img_data = img_data[::-1]
        # img_data = Image.fromarray(img_data)
        # img_data.save(r"{}\{}.png".format(dir_path, img_name))
        import  numpy
        numpy.savetxt(r"{}\{}.data".format(dir_path, img_name), img_data, fmt='%.2e', delimiter=' ', newline='\n', header='', footer='', comments=' ',
                      encoding=None)
        print("save images to {}".format(dir_path))
            # print("images have saved.")
        # except OSError:
        #     print('Image cannot be saved.')

#############################################################3
    def img_plot(self, img_dict):
        # print(img_dict['img_data'].ndim)
        self.video.setImage(img_dict['img_data'])
        self.img_label = img_dict['img_name']
        self.viewport.setToolTip(str(self.img_label))

    def clear_win(self):
        self.video.clear()
        self.img_label = 'no image'
        self.viewport.setToolTip(str(self.img_label))
示例#8
0
class ImageTester(QtWidgets.QWidget):
    """Graphical interface for auditing image comparison tests.
    """
    def __init__(self):
        self.lastKey = None

        QtWidgets.QWidget.__init__(self)
        self.resize(1200, 800)
        #self.showFullScreen()

        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)

        self.view = GraphicsLayoutWidget()
        self.layout.addWidget(self.view, 0, 0, 1, 2)

        self.label = QtWidgets.QLabel()
        self.layout.addWidget(self.label, 1, 0, 1, 2)
        self.label.setWordWrap(True)
        font = QtGui.QFont("monospace", 14, QtGui.QFont.Weight.Bold)
        self.label.setFont(font)

        self.passBtn = QtWidgets.QPushButton('Pass')
        self.failBtn = QtWidgets.QPushButton('Fail')
        self.layout.addWidget(self.passBtn, 2, 0)
        self.layout.addWidget(self.failBtn, 2, 1)
        self.passBtn.clicked.connect(self.passTest)
        self.failBtn.clicked.connect(self.failTest)

        self.views = (self.view.addViewBox(row=0, col=0),
                      self.view.addViewBox(row=0, col=1),
                      self.view.addViewBox(row=0, col=2))
        labelText = ['test output', 'standard', 'diff']
        for i, v in enumerate(self.views):
            v.setAspectLocked(1)
            v.invertY()
            v.image = ImageItem(axisOrder='row-major')
            v.image.setAutoDownsample(True)
            v.addItem(v.image)
            v.label = TextItem(labelText[i])
            v.setBackgroundColor(0.5)

        self.views[1].setXLink(self.views[0])
        self.views[1].setYLink(self.views[0])
        self.views[2].setXLink(self.views[0])
        self.views[2].setYLink(self.views[0])

    def test(self, im1, im2, message):
        """Ask the user to decide whether an image test passes or fails.
        
        This method displays the test image, reference image, and the difference
        between the two. It then blocks until the user selects the test output
        by clicking a pass/fail button or typing p/f. If the user fails the test,
        then an exception is raised.
        """
        self.show()
        if im2 is None:
            message += '\nImage1: %s %s   Image2: [no standard]' % (im1.shape,
                                                                    im1.dtype)
            im2 = np.zeros((1, 1, 3), dtype=np.ubyte)
        else:
            message += '\nImage1: %s %s   Image2: %s %s' % (
                im1.shape, im1.dtype, im2.shape, im2.dtype)
        self.label.setText(message)

        self.views[0].image.setImage(im1)
        self.views[1].image.setImage(im2)
        diff = makeDiffImage(im1, im2)

        self.views[2].image.setImage(diff)
        self.views[0].autoRange()

        while True:
            QtWidgets.QApplication.processEvents()
            lastKey = self.lastKey

            self.lastKey = None
            if lastKey in ('f', 'esc') or not self.isVisible():
                raise Exception("User rejected test result.")
            elif lastKey == 'p':
                break
            time.sleep(0.03)

        for v in self.views:
            v.image.setImage(np.zeros((1, 1, 3), dtype=np.ubyte))

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key.Key_Escape:
            self.lastKey = 'esc'
        else:
            self.lastKey = str(event.text()).lower()

    def passTest(self):
        self.lastKey = 'p'

    def failTest(self):
        self.lastKey = 'f'
class PlotWindow(QWidget):

    img_dict = pyqtSignal(object)

    myserial = 5

    def __init__(self):
        super(PlotWindow, self).__init__()
        self.layout = QHBoxLayout(self)

        pg.setConfigOptions(imageAxisOrder='row-major')
        self.viewport = GraphicsLayoutWidget()
        self.video_view = self.viewport.addViewBox()
        self.video = pg.ImageItem()
        self.video_view.addItem(self.video)
        self.video_view.setMouseEnabled(x=False,
                                        y=False)  #make it can not move

        self.setLayout(self.layout)

        self.layout.addWidget(self.viewport)
        self.img_label = QLabel()

        # self.horizontalLayout = QVBoxLayout()
        # self.horizontalLayout.addWidget(self.img_label)
        # self.layout.addLayout(self.horizontalLayout)
        screen = QtGui.QDesktopWidget().screenGeometry()
        self.setFixedSize(screen.width() * 15 / 100,
                          screen.height() * 14.5 / 100)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            try:
                fpath = IOHelper.get_config_setting('DATA_PATH')

                img_fpath = QFileDialog.getOpenFileName(
                    self, "Open File", fpath)  # name path
                strimg_fpath = str(img_fpath)
                img_file = strimg_fpath[2:len(strimg_fpath) - 19]
                img_path = Path(img_file)

                file = open(img_path)
                linescontent = file.readlines(
                )  # Read the file as a behavior unit
                rows = len(linescontent)  # get the numbers fo line
                lines = len(linescontent[0].strip().split(' '))
                img_data = np.zeros((rows, lines))  # Initialization matrix
                row = 0
                for line in linescontent:
                    line = line.strip().split(' ')
                    img_data[row, :] = line[:]
                    row += 1
                file.close()

                img_data = img_data[::-1]
                img_name = img_path.stem
                img = {'img_name': img_name, 'img_data': img_data}
                settings.absimgDatas[self.myserial] = img_data

                self.img_plot(img)
            except TypeError:
                return
            except PermissionError:
                return

    def update_console(self, stri):
        MAX_LINES = 50
        stri = str(stri)
        new_text = self.prompt_dock.console_text() + '\n' + stri
        line_list = new_text.splitlines()
        N_lines = min(MAX_LINES, len(line_list))
        # limit output lines
        new_text = '\n'.join(line_list[-N_lines:])
        self.prompt_dock.console_text(new_text)
        self.prompt_dock.automatic_scroll()

    def save_image(self):
        try:
            if self.video.image is None:
                print("have no image in window")
                return
            fpath = IOHelper.get_config_setting('DATA_PATH')
            fpath = Path(fpath)
            dir_path = fpath.joinpath(
                str(datetime.datetime.now()).split('.')[0].replace(
                    ' ', '-').replace(':', '_'))
            # print("save images to {}".format(dir_path))
            if not dir_path.exists():
                dir_path.mkdir()
                img_data = np.array(self.video.image)
                # load image name by path
                img_name1 = settings.widget_params["Analyse Data Setting"][
                    "Prefix"]
                img_name2 = (self.img_label.text())[0:20].replace(
                    ' ', '~').replace(':', '').replace('-', '')
                img_name = str(img_name1) + str(img_name2)
                img_data = img_data[::-1]
                img_data = Image.fromarray(img_data)
                img_data.save(r"{}\{}.png".format(dir_path, img_name))
            print("save images to {}".format(dir_path))
            # print("images have saved.")
        except OSError:
            print('Only new version files can be saved.')

    def img_plot(self, img_dict):
        self.video.setImage(img_dict['img_data'])
        self.img_label.setText(img_dict['img_name'])

    def clear_win(self):
        self.video.clear()
        self.img_label.setText('')
示例#10
0
class CameraViewerWidget(QWidget):
    """Widget for holding the images generated by the camera.
    """
    specialTask = pyqtSignal()
    stopSpecialTask = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        # General layout of the widget to hold an image and a histogram
        self.layout = QHBoxLayout(self)

        # Settings for the image
        self.viewport = GraphicsLayoutWidget()
        self.view = self.viewport.addViewBox(lockAspect=False, enableMenu=True)

        self.autoScale = QAction("Auto Range", self.view.menu)
        self.autoScale.triggered.connect(self.do_auto_scale)
        self.view.menu.addAction(self.autoScale)

        self.img = pg.ImageItem()
        self.marker = pg.PlotDataItem(pen=None)
        self.marker.setBrush(255, 0, 0, 255)
        self.view.addItem(self.img)
        self.view.addItem(self.marker)
        self.imv = pg.ImageView(view=self.view, imageItem=self.img)

        # Add everything to the widget
        self.layout.addWidget(self.imv)
        self.setLayout(self.layout)

        self.showCrosshair = False
        self.showCrossCut = False
        self.rois = []
        self.radius_circle = 10  # The radius to draw around particles

        self.corner_roi = [0, 0]  # Initial ROI corner for the camera

        self.first_image = True

    def setup_roi_lines(self, max_size):
        """Sets up the ROI lines surrounding the image.
        
        :param list max_size: List containing the maximum size of the image to avoid ROIs bigger than the CCD."""

        self.hline1 = pg.InfiniteLine(angle=0,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.hline2 = pg.InfiniteLine(angle=0,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.vline1 = pg.InfiniteLine(angle=90,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.vline2 = pg.InfiniteLine(angle=90,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })

        self.hline1.setValue(0)
        self.vline1.setValue(0)
        self.vline2.setValue(max_size[0])
        self.hline2.setValue(max_size[1])
        self.hline1.setBounds((0, max_size[1]))
        self.hline2.setBounds((0, max_size[1]))
        self.vline1.setBounds((0, max_size[0]))
        self.vline2.setBounds((0, max_size[0]))
        self.view.addItem(self.hline1)
        self.view.addItem(self.hline2)
        self.view.addItem(self.vline1)
        self.view.addItem(self.vline2)
        self.corner_roi[0] = 0
        self.corner_roi[1] = 0

    def get_roi_values(self):
        """ Get's the ROI values in camera-space. It keeps track of the top left corner in order
        to update the values before returning.
        :return: Position of the corners of the ROI region assuming 0-indexed cameras.
        """
        y1 = round(self.hline1.value())
        y2 = round(self.hline2.value())

        x1 = round(self.vline1.value())
        x2 = round(self.vline2.value())

        X = np.sort((x1, x2))
        Y = np.sort((y1, y2))
        # Updates to the real values in camera space
        X += self.corner_roi[0]
        Y += self.corner_roi[1]
        X[1] -= 1
        Y[1] -= 1
        return X, Y

    def set_roi_lines(self, X, Y):
        self.corner_roi = [X[0], Y[0]]
        self.hline1.setValue(0)
        self.vline1.setValue(0)
        x2 = X[1] - X[0] + 1
        y2 = Y[1] - Y[0] + 1
        self.hline2.setValue(y2)  # To the last pixel
        self.vline2.setValue(x2)  # To the last pixel

    def setup_mouse_tracking(self):
        self.imv.setMouseTracking(True)
        self.imv.getImageItem().scene().sigMouseMoved.connect(self.mouseMoved)
        self.imv.getImageItem().scene().contextMenu = None

    def keyPressEvent(self, key):
        """Triggered when there is a key press with some modifier.
        Shift+C: Removes the cross hair from the screen
        Ctrl+C: Emits a specialTask signal
        Ctrl+V: Emits a stopSpecialTask signal
        These last two events have to be handeled in the mainWindow that implemented this widget."""
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ShiftModifier:
            if key.key() == 67:  # For letter C of 'Clear
                if self.showCrosshair:
                    for c in self.crosshair:
                        self.view.removeItem(c)
                    self.showCrosshair = False
                if self.showCrossCut:
                    self.view.removeItem(self.crossCut)
                    self.showCrossCut = False
        elif modifiers == Qt.ControlModifier:
            if key.key() == 67:  # For letter C of 'Clear
                self.specialTask.emit()
            if key.key() == 86:  # For letter V
                self.stopSpecialTask.emit()

    def mouseMoved(self, arg):
        """Updates the position of the cross hair. The mouse has to be moved while pressing down the Ctrl button."""
        # arg = evt.pos()
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ControlModifier:
            if not self.showCrosshair:
                for c in self.crosshair:
                    self.view.addItem(c)
                self.showCrosshair = True
            self.crosshair[1].setValue(int(self.img.mapFromScene(arg).x()))
            self.crosshair[0].setValue(int(self.img.mapFromScene(arg).y()))
        elif modifiers == Qt.AltModifier:
            if not self.showCrossCut:
                self.view.addItem(self.crossCut)
            self.showCrossCut = True
            self.crossCut.setValue(int(self.img.mapFromScene(arg).y()))

    def do_auto_scale(self):
        h, y = self.img.getHistogram()
        self.imv.setLevels(min(h), max(h))

    def draw_target_pointer(self, locations):
        """gets an image and draws a circle around the target locations.

        :param DataFrame locations: DataFrame generated by trackpy's locate method. It only requires columns `x` and `y` with coordinates.
        """
        if locations is None:
            return

        locations = locations[['y', 'x']].values
        brush = pg.mkBrush(color=(255, 0, 0))
        self.marker.setData(locations[:, 0],
                            locations[:, 1],
                            symbol='x',
                            symbolBrush=brush)

    def update_image(self, image):
        self.img.setImage(image.astype(int),
                          autoLevels=False,
                          autoRange=False,
                          autoHistogramRange=False)
        if self.first_image:
            self.do_auto_scale()
            self.first_image = False

    def setup_cross_hair(self, max_size):
        """Sets up a cross hair."""
        self.crosshair = []
        self.crosshair.append(
            pg.InfiniteLine(angle=0,
                            movable=False,
                            pen={
                                'color': 124,
                                'width': 4
                            }))
        self.crosshair.append(
            pg.InfiniteLine(angle=90,
                            movable=False,
                            pen={
                                'color': 124,
                                'width': 4
                            }))
        self.crosshair[0].setBounds((1, max_size[1] - 1))
        self.crosshair[1].setBounds((1, max_size[0] - 1))

    def setup_cross_cut(self, max_size):
        """Set ups the horizontal line for the cross cut."""
        self.crossCut = pg.InfiniteLine(angle=0,
                                        movable=False,
                                        pen={
                                            'color': 'g',
                                            'width': 2
                                        })
        self.crossCut.setBounds((1, max_size))
示例#11
0
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, host, port, path, parent=None):
        super().__init__(parent)

        self.path = path
        self.maze_files = sorted(
            fname.relative_to(self.path)
            for fname in self.path.glob('**/*.txt')
            if fname.is_file()
        )

        self.setWindowTitle('Micromouse maze simulator')
        self.resize(800, 600)

        self.history = []

        self.status = QStatusBar()
        self.setStatusBar(self.status)

        self.search = QLineEdit()
        self.search.textChanged.connect(self.filter_mazes)

        self.files = QListWidget()
        self.files.currentItemChanged.connect(self.list_value_changed)

        self.graphics = GraphicsLayoutWidget()
        viewbox = self.graphics.addViewBox()
        viewbox.setAspectLocked()
        self.maze = MazeItem()
        viewbox.addItem(self.maze)

        self.slider = QSlider(QtCore.Qt.Horizontal)
        self.slider.setSingleStep(1)
        self.slider.setPageStep(10)
        self.slider.setTickPosition(QSlider.TicksAbove)
        self.slider.valueChanged.connect(self.slider_value_changed)
        self.reset()

        files_layout = QVBoxLayout()
        files_layout.setContentsMargins(0, 0, 0, 0)
        files_layout.addWidget(self.search)
        files_layout.addWidget(self.files)
        files_widget = QWidget()
        files_widget.setLayout(files_layout)
        graphics_layout = QVBoxLayout()
        graphics_layout.setContentsMargins(0, 0, 0, 0)
        graphics_layout.addWidget(self.graphics)
        graphics_layout.addWidget(self.slider)
        graphics_widget = QWidget()
        graphics_widget.setLayout(graphics_layout)
        central_splitter = QSplitter()
        central_splitter.addWidget(files_widget)
        central_splitter.addWidget(graphics_widget)

        main_layout = QVBoxLayout()
        main_layout.addWidget(central_splitter)
        main_layout.setContentsMargins(4, 4, 4, 4)
        main_widget = QWidget()
        main_widget.setLayout(main_layout)

        self.setCentralWidget(main_widget)
        self.filter_mazes('')

        self.context = zmq.Context()
        self.reply = self.context.socket(zmq.PUSH)
        self.reply.connect('inproc://reply')

        self.thread = QtCore.QThread()
        self.zeromq_listener = ZMQListener(self.context, host=host, port=port)
        self.zeromq_listener.moveToThread(self.thread)

        self.thread.started.connect(self.zeromq_listener.loop)
        self.zeromq_listener.message.connect(self.signal_received)

        QtCore.QTimer.singleShot(0, self.thread.start)

    def filter_mazes(self, text):
        keywords = text.lower().split(' ')
        self.files.clear()
        for fname in self.maze_files:
            for key in keywords:
                if key not in str(fname).lower():
                    break
            else:
                self.files.addItem(str(fname))
        self.files.setCurrentRow(0)

    def list_value_changed(self, after, before):
        if not after:
            return
        self.set_maze(after.text())

    def set_maze(self, fname):
        template_file = Path(fname)
        template = load_maze(self.path / template_file)
        self.maze.reset(template)
        self.reset()

    def reset(self):
        self.history = []
        self.slider.setValue(-1)
        self.slider.setRange(-1, -1)
        self.status.showMessage('Ready')

    def slider_update(self):
        self.slider.setTickInterval(len(self.history) / 10)
        self.slider.setRange(0, len(self.history) - 1)
        self.status_set_slider(self.slider.value())

    def slider_value_changed(self, value):
        self.status_set_slider(value)
        if not len(self.history):
            return
        state = self.history[value]
        position = state[:3]
        discovery = state[3:]
        self.maze.update_position(position)
        self.maze.update_discovery(discovery)

    def status_set_slider(self, value):
        self.status.showMessage('{}/{}'.format(value, len(self.history) - 1))

    def signal_received(self, message):
        if message.startswith(b'W'):
            walls = self.maze.read_position_walls(message.lstrip(b'W'))
            self.reply.send(struct.pack('3B', *walls))
            return
        if message.startswith(b'S'):
            message = message.lstrip(b'S')
            self.history.append(message)
            self.reply.send(b'ok')
            self.slider_update()
            return
        if message == b'reset':
            self.reset()
            self.reply.send(b'ok')
            return
        if message == b'ping':
            self.reply.send(b'pong')
            return
        raise ValueError('Unknown message received! "{}"'.format(message))

    def closeEvent(self, event):
        self.zeromq_listener.running = False
        self.thread.quit()
        self.thread.wait()
示例#12
0
class PlotWindow(QWidget):

    img_dict = pyqtSignal(object)

    def __init__(self):
        super(PlotWindow, self).__init__()
        self.layout = QVBoxLayout(self)

        pg.setConfigOptions(imageAxisOrder='row-major')
        self.viewport = GraphicsLayoutWidget()
        self.video_view = self.viewport.addViewBox()
        self.video = pg.ImageItem()
        self.video_view.addItem(self.video)

        self.setLayout(self.layout)

        self.layout.addWidget(self.viewport)
        self.img_label = QLabel()

        self.push_btn = QPushButton("sent to main window", self)
        self.push_btn.clicked.connect(self.btn_state)
        self.save_btn = QPushButton("save", self)
        self.save_btn.clicked.connect(self.save_image)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addWidget(self.push_btn)
        self.horizontalLayout.addWidget(self.save_btn)
        self.horizontalLayout.addWidget(self.img_label)
        self.layout.addLayout(self.horizontalLayout)

    def btn_state(self):
        if self.video.image is None:
            print("have no image in window")
            return
        img_dict = {
            'img_data': np.array(self.video.image),
            'img_name': self.img_label.text()
        }
        self.img_dict.emit(img_dict)

    def save_image(self):
        if self.video.image is None:
            print("have no image in window")
            return
        fpath = IOHelper.get_config_setting('DATA_PATH')
        fpath = Path(fpath)
        dir_path = fpath.joinpath(
            str(datetime.datetime.now()).split('.')[0].replace(' ',
                                                               '-').replace(
                                                                   ':', '_'))
        print("save images to {}".format(dir_path))
        if not dir_path.exists():
            dir_path.mkdir()
            img_data = np.array(self.video.image)
            # load image name by path
            img_name = (self.img_label.text()).split('.')[0].replace(
                ' ', '-').replace(':', '_')
            img_data = Image.fromarray(img_data)
            img_data.save(r"{}\{}.png".format(dir_path, img_name))
        print("images have saved.")

    def img_plot(self, img_dict):
        self.video.setImage(img_dict['img_data'])
        self.img_label.setText(img_dict['img_name'])

    def clear_win(self):
        self.video.clear()
        self.img_label.setText('')
示例#13
0
class MainUI(object):
    def __init__(self, MainWindow, data_path):

        MainWindow.setWindowTitle('Tracking demo')
        MainWindow.resize(1000, 700)
        # data path
        self.gt_path = data_path
        self.path = data_path

        # Dataset Selection
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 150, 200))
        self.groupBox.setObjectName("groupBox")

        self.groupBox_legend = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_legend.setGeometry(QtCore.QRect(10, 220, 200, 300))
        self.groupBox_legend.setObjectName("groupBox_legend")

        # self.legend_label = QtWidgets.QLabel()
        self.legend_label = QtWidgets.QLabel(self.groupBox_legend)
        self.legend_label.setGeometry(QtCore.QRect(10, 20, 95, 20))
        self.legend_label.setText("Ground Trut ----")
        self.legend_label.setStyleSheet(
            " color: rgba(255, 0, 0); font-size: 10pt; font-weight: 300;")

        self.legend_label2 = QtWidgets.QLabel(self.groupBox_legend)
        self.legend_label2.setText("Tracking Result ----")
        self.legend_label2.setStyleSheet(
            " color: rgba(0,255, 0); font-size: 10pt; font-weight: 300;")

        self.radBtn_1 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_1.setGeometry(QtCore.QRect(10, 20, 95, 20))
        self.radBtn_1.setObjectName("panda_radBtn")
        self.radBtn_1.toggled.connect(self.setDataset)

        self.radBtn_2 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_2.setGeometry(QtCore.QRect(10, 40, 95, 20))
        self.radBtn_2.setObjectName("tiger_radBtn")
        self.radBtn_2.toggled.connect(self.setDataset)

        self.radBtn_3 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_3.setGeometry(QtCore.QRect(10, 60, 95, 20))
        self.radBtn_3.setObjectName("panda_radBtn")
        self.radBtn_3.toggled.connect(self.setDataset)

        self.radBtn_4 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_4.setGeometry(QtCore.QRect(10, 80, 95, 20))
        self.radBtn_4.setObjectName("tiger_radBtn")
        self.radBtn_4.toggled.connect(self.setDataset)

        self.radBtn_5 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_5.setGeometry(QtCore.QRect(10, 100, 95, 20))
        self.radBtn_5.setObjectName("panda_radBtn")
        self.radBtn_5.toggled.connect(self.setDataset)

        self.model_pulldown = QtGui.QComboBox(self.groupBox)
        self.model_pulldown.setGeometry(QtCore.QRect(15, 125, 93, 28))
        self.model_pulldown.setObjectName("model_pulldown")
        # self.model_pulldown.addItem("Select")
        self.model_pulldown.addItem("KCF")
        self.model_pulldown.addItem("MDNet")
        self.model_pulldown.addItem("SiamFC")
        self.img_root = self.path["KCF"]
        self.model_pulldown.activated.connect(self.setModel)

        self.display_Btn = QtWidgets.QPushButton(self.groupBox)
        self.display_Btn.setGeometry(QtCore.QRect(15, 155, 93, 28))
        self.display_Btn.setObjectName("display_Btn")

        # Set up GraphicsLayoutWidget for images
        self.graphicsWindow = GraphicsLayoutWidget(self.centralwidget,
                                                   border=True)
        self.graphicsWindow.setGeometry(QtCore.QRect(140, 10, 850, 600))
        self.graphicsWindow.setObjectName("graphicsWindow")
        MainWindow.setCentralWidget(self.centralwidget)

        self.score_box = self.graphicsWindow.addViewBox(0, 0, colspan=100)
        self.ref_box = self.graphicsWindow.addViewBox(0, 100, colspan=50)

        self.score_box.invertY(
            True)  # Images usually have their Y-axis pointing downward
        self.ref_box.invertY(True)
        self.score_box.setAspectLocked(True)
        self.ref_box.setAspectLocked(True)
        # image stuff
        self.score_map = pg.ImageItem(axisOrder='row-major')
        self.groundtruth_img = pg.ImageItem(axisOrder='row-major')
        self.ref_img = pg.ImageItem(axisOrder='row-major')

        # Set Image placeholders
        self.score_map.setImage(np.zeros((300, 230, 3)))
        self.groundtruth_img.setImage(np.zeros((300, 230, 3)))
        self.ref_img.setImage(np.zeros((300, 230, 3)))

        self.score_box.addItem(self.score_map)

        self.ref_box.addItem(self.ref_img)

        # laybels
        # Add the Labels to the images
        font = QtGui.QFont()
        font.setPointSize(4)

        # parameter for text display
        param_dict = {'color': (255, 255, 255), 'anchor': (0, 1)}
        label_score = pg.TextItem(text='Tracking Result', **param_dict)
        label_gt = pg.TextItem(text='Tracking Error', **param_dict)
        label_ref = pg.TextItem(text='Reference Image', **param_dict)

        font.setPointSize(16)
        label_score.setFont(font)
        label_gt.setFont(font)
        label_ref.setFont(font)
        label_score.setParentItem(self.score_map)
        label_gt.setParentItem(self.groundtruth_img)
        label_ref.setParentItem(self.ref_img)

        self.score_box.addItem(label_score)

        self.ref_box.addItem(label_ref)

        # display buttons
        self.display_Btn.clicked.connect(self.addImages)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.i = 0
        self.error = np.zeros((1))

        self.updateTime = ptime.time()
        self.fps = 0

        # display error plot
        self.error_plot = self.graphicsWindow.addPlot(3, 0, colspan=200)
        self.error_data = np.zeros((3, ))
        self.curve1 = self.error_plot.plot(self.error_data)

        MainWindow.show()

    def exit(self):
        sys.exit()

    def setDataset(self):
        if self.radBtn_1.isChecked():
            self.img_disp_path = "bolt1/"
            self.template_path = "bolt.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_2.isChecked():
            self.img_disp_path = "bolt2/"
            self.template_path = "bolt2.jpg"
            self.temp_img = self.load_temp()

            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_3.isChecked():
            self.img_disp_path = "football/"
            self.template_path = "football.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_4.isChecked():
            self.img_disp_path = "football1/"
            self.template_path = "football1.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_5.isChecked():
            self.img_disp_path = "mountainbike/"
            self.template_path = "mountainbike.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

    def setModel(self):
        if self.model_pulldown.currentText() == "KCF":
            self.error_plot.removeItem(self.curve1)
            self.img_root = self.path["KCF"]
        if self.model_pulldown.currentText() == "MDNet":
            self.error_plot.removeItem(self.curve1)

            self.img_root = self.path["MDNet"]

        if self.model_pulldown.currentText() == "SiamFC":
            self.error_plot.removeItem(self.curve1)
            self.img_root = self.path["SiamFC"]

    def addImages(self, MainWindow):

        self.i = 0

        self.data_set = self.load_data()
        self.error = np.zeros((1))
        self.curve1 = self.error_plot.plot(np.zeros((1, )))
        self.error_plot.removeItem(self.curve1)
        self.curve1 = self.error_plot.plot(np.zeros((1, )))

        self.updateData()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "Select Dataset"))
        self.radBtn_1.setText(_translate("MainWindow", "Bolt1"))
        self.radBtn_2.setText(_translate("MainWindow", "Bolt2"))

        self.radBtn_3.setText(_translate("MainWindow", "football"))

        self.radBtn_4.setText(_translate("MainWindow", "football1"))
        self.radBtn_5.setText(_translate("MainWindow", "mountainbike"))
        self.display_Btn.setText(_translate("MainWindow", "Display!"))

    def load_temp(self):
        imagePath = os.path.join(self.img_root + self.template_path)
        temp = cv2.imread(imagePath)
        temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)

        return temp

    def load_data(self):
        n_files = len(os.listdir(self.img_root + self.img_disp_path)) - 3
        image_set = []
        for i in range(1, n_files):

            imagePath = os.path.join(self.img_root + self.img_disp_path +
                                     "%08d.jpg" % i)
            frame = cv2.imread(imagePath)  # 1 for colored imaged
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            image_set.append(frame)

        return image_set

    def read_error(self):
        lineList = []

        filePath = os.path.join(self.img_root + self.img_disp_path +
                                "error.txt")
        with open(filePath, 'r') as file:
            for line in file:
                lines = [float(number) for number in line.strip().split()]
                lineList.append(lines[0])
        return np.array(lineList)

    def updateData(self):
        self.score_map.setImage(self.data_set[self.i])
        self.ref_img.setImage(self.temp_img)
        self.i = (self.i + 1) % len(self.data_set)
        now = ptime.time()

        fps2 = 1.0 / (now - self.updateTime)
        self.updateTime = now
        self.fps = self.fps * 0.9 + fps2 * 0.1
        time.sleep(0.01)
        QtCore.QTimer.singleShot(100, self.updateData)

        self.curve1.setData(self.error_data[0:self.i])
示例#14
0
class CameraViewerWidget(DataViewWidget):
    """ The Camera Viewer Widget is a wrapper around PyQtGraph ImageView. It adds some common methods for getting extra
    mouse interactions, such as performing an auto-range through right-clicking, it allows to drag and drop horizontal
    and vertical lines to define a ROI, and it allows to draw on top of the image. The core idea is to make these options
    explicit, in order to systematize them in one place.

    Signals
    -------
    clicked_on_image: Emits [float, float] with the coordinates where the mouse was clicked on the image. Does not
        distinguish between left/right clicks. Any further processing must be done downstream.

    Attributes
    ----------
    layout: QHBoxLayout, in case extra elements must be added
    viewport: GraphicsLayoutWidget
    view: ViewBox
    img: ImageItem
    imv: ImageView
    auto_levels: Whether to actualize the levels of the image every time they are refreshed
    """

    clicked_on_image = pyqtSignal([float, float])

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        # Settings for the image
        self.viewport = GraphicsLayoutWidget()
        self.view = self.viewport.addViewBox(lockAspect=False, enableMenu=True)

        self.img = pg.ImageItem()
        self.view.addItem(self.img)
        self.imv = pg.ImageView(view=self.view, imageItem=self.img)

        self.scene().sigMouseClicked.connect(self.mouse_clicked)

        # Add everything to the widget
        layout = self.get_layout()
        layout.addWidget(self.imv)

        self.show_roi_lines = False  # ROI lines are shown or not
        self.show_cross_hair = False  # Cross hair is shown or not
        self.show_cross_cut = False  # Cross cut is shown or not
        self.cross_hair_setup = False  # Cross hair was setup or not
        self.cross_cut_setup = False  # Cross cut was setup or not

        self.rois = []

        self.corner_roi = [0, 0]  # Initial ROI corner for the camera

        self.first_image = True

        self.logger = get_logger()

        self.last_image = None

        self.add_actions_to_menu()
        self.setup_mouse_tracking()

    def scene(self):
        """ Shortcut to getting the image scene"""
        return self.img.scene()

    def update_image(self,
                     image,
                     auto_range=False,
                     auto_histogram_range=False):
        """ Updates the image being displayed with some sensitive defaults, which can be over written if needed.
        """
        auto_levels = self.auto_levels_action.isChecked()
        self.logger.debug(f'Updating image with auto_levels: {auto_levels}')
        if image is not None:
            self.imv.setImage(image,
                              autoLevels=auto_levels,
                              autoRange=auto_range,
                              autoHistogramRange=auto_histogram_range)
            if self.first_image:
                self.do_auto_range()
                self.first_image = False
            self.last_image = image
        else:
            self.logger.debug(f'No new image to update')

    def setup_roi_lines(self, max_size=None):
        """Sets up the ROI lines surrounding the image.
        
        :param list max_size: List containing the maximum size of the image to avoid ROIs bigger than the CCD."""
        if self.last_image is None:
            return
        self.logger.info('Setting up ROI lines')

        if not isinstance(max_size, list):
            max_size = self.last_image.shape

        self.hline1 = pg.InfiniteLine(angle=0,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.hline2 = pg.InfiniteLine(angle=0,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.vline1 = pg.InfiniteLine(angle=90,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })
        self.vline2 = pg.InfiniteLine(angle=90,
                                      movable=True,
                                      hoverPen={
                                          'color': "FF0",
                                          'width': 4
                                      })

        self.hline1.setValue(0)
        self.vline1.setValue(0)
        self.vline2.setValue(max_size[0])
        self.hline2.setValue(max_size[1])
        self.hline1.setBounds((0, max_size[1]))
        self.hline2.setBounds((0, max_size[1]))
        self.vline1.setBounds((0, max_size[0]))
        self.vline2.setBounds((0, max_size[0]))
        self.view.addItem(self.hline1)
        self.view.addItem(self.hline2)
        self.view.addItem(self.vline1)
        self.view.addItem(self.vline2)
        self.corner_roi[0] = 0
        self.corner_roi[1] = 0

    def get_roi_values(self):
        """ Get's the ROI values in camera-space. It keeps track of the top left corner in order
        to update the values before returning.
        :return: Position of the corners of the ROI region assuming 0-indexed cameras.
        """
        y1 = round(self.hline1.value())
        y2 = round(self.hline2.value())

        x1 = round(self.vline1.value())
        x2 = round(self.vline2.value())

        width = np.abs(x1 - x2)
        height = np.abs(y1 - y2)
        x = np.min((x1, x2)) + self.corner_roi[0]
        y = np.min((y1, y2)) + self.corner_roi[1]
        return (x, width), (y, height)

    def set_roi_lines(self, X, Y):
        self.corner_roi = [X[0], Y[0]]
        self.hline1.setValue(0)
        self.vline1.setValue(0)
        self.hline2.setValue(Y[1])  # To the last pixel
        self.vline2.setValue(X[1])  # To the last pixel

    def setup_mouse_tracking(self):
        self.imv.setMouseTracking(True)
        self.imv.getImageItem().scene().sigMouseMoved.connect(self.mouseMoved)
        self.imv.getImageItem().scene().contextMenu = None

    def keyPressEvent(self, key):
        """Triggered when there is a key press with some modifier.
        Shift+C: Removes the cross hair from the screen
        These last two events have to be handeled in the mainWindow that implemented this widget."""
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ShiftModifier:
            if key.key() == 67:  # For letter C of 'Clear
                if self.show_cross_hair:
                    for c in self.crosshair:
                        self.view.removeItem(c)
                    self.show_cross_hair = False
                if self.show_cross_cut:
                    self.view.removeItem(self.crossCut)
                    self.show_cross_cut = False

    def mouseMoved(self, arg):
        """Updates the position of the cross hair. The mouse has to be moved while pressing down the Ctrl button."""
        # arg = evt.pos()
        modifiers = QApplication.keyboardModifiers()
        if modifiers == Qt.ControlModifier:
            if self.cross_hair_setup:
                if not self.show_cross_hair:
                    for c in self.crosshair:
                        self.view.addItem(c)
                    self.show_cross_hair = True
                self.crosshair[1].setValue(int(self.img.mapFromScene(arg).x()))
                self.crosshair[0].setValue(int(self.img.mapFromScene(arg).y()))
        elif modifiers == Qt.AltModifier:
            self.logger.debug('Moving mouse while pressing Alt')
            if self.cross_cut_setup:
                if not self.show_cross_cut:
                    self.view.addItem(self.crossCut)
                self.show_cross_cut = True
                self.crossCut.setValue(int(self.img.mapFromScene(arg).y()))

    def do_auto_range(self):
        """ Sets the levels of the image based on the maximum and minimum. This is useful when auto-levels are off
        (the default behavior), and one needs to quickly adapt the histogram.
        """

        h, y = self.img.getHistogram()
        self.imv.setLevels(min(h), max(h))

    def draw_target_pointer(self, locations):
        """gets an image and draws a circle around the target locations.

        :param DataFrame locations: DataFrame generated by trackpy's locate method. It only requires columns `x` and `y` with coordinates.
        """
        if locations is None:
            return

        locations = locations[['y', 'x']].values
        brush = pg.mkBrush(color=(255, 0, 0))
        self.marker.setData(locations[:, 0],
                            locations[:, 1],
                            symbol='x',
                            symbolBrush=brush)

    def setup_cross_hair(self, max_size):
        """Sets up a cross hair."""
        self.show_cross_hair = self.setup_cross_hair_action.isChecked()
        if self.last_image is None:
            return
        self.logger.info('Setting up Cross Hair lines')

        if not isinstance(max_size, list):
            max_size = self.last_image.shape

        self.cross_hair_setup = True
        self.crosshair = []
        self.crosshair.append(
            pg.InfiniteLine(angle=0,
                            movable=False,
                            pen={
                                'color': 124,
                                'width': 4
                            }))
        self.crosshair.append(
            pg.InfiniteLine(angle=90,
                            movable=False,
                            pen={
                                'color': 124,
                                'width': 4
                            }))
        self.crosshair[0].setBounds((1, max_size[1] - 1))
        self.crosshair[1].setBounds((1, max_size[0] - 1))

    def setup_cross_cut(self, max_size):
        """Set ups the horizontal line for the cross cut."""
        self.show_cross_cut = self.setup_cross_cut_action.isChecked()
        if self.last_image is None:
            return
        self.logger.info('Setting up horizontal cross cut line')

        if not isinstance(max_size, list):
            max_size = self.last_image.shape[1]

        self.cross_cut_setup = True
        self.crossCut = pg.InfiniteLine(angle=0,
                                        movable=False,
                                        pen={
                                            'color': 'g',
                                            'width': 2
                                        })
        self.crossCut.setBounds((1, max_size))

    def mouse_clicked(self, evnt):
        modifiers = evnt.modifiers()
        if modifiers == Qt.ControlModifier:
            self.clicked_on_image.emit(
                self.img.mapFromScene(evnt.pos()).x(),
                self.img.mapFromScene(evnt.pos()).y())

    def add_actions_to_menu(self):
        """ Adds actions to the contextual menu. If you want to have control on which actions appear, consider subclassing
        this widget and overriding this method.
        """
        self.auto_range_action = QAction("Auto Range", self.view.menu)
        self.auto_range_action.triggered.connect(self.do_auto_range)

        self.setup_roi_lines_action = QAction("Setup ROI", self.view.menu)
        self.setup_roi_lines_action.triggered.connect(self.setup_roi_lines)

        self.setup_cross_cut_action = QAction("Setup cross cut",
                                              self.view.menu,
                                              checkable=True)
        self.setup_cross_cut_action.triggered.connect(self.setup_cross_cut)

        self.setup_cross_hair_action = QAction("Setup cross hair",
                                               self.view.menu,
                                               checkable=True)
        self.setup_cross_hair_action.triggered.connect(self.setup_cross_hair)

        self.auto_levels_action = QAction('Auto Levels',
                                          self.view.menu,
                                          checkable=True)
        self.view.menu.addAction(self.auto_range_action)
        self.view.menu.addAction(self.auto_levels_action)
        self.view.menu.addAction(self.setup_roi_lines_action)
        self.view.menu.addAction(self.setup_cross_hair_action)
        self.view.menu.addAction(self.setup_cross_cut_action)

    @classmethod
    def connect_to_camera(cls, camera, refresh_time=50, parent=None):
        """ Instantiate the viewer using connect_to_camera in order to get some functionality out of the box. It will
        create a timer to automatically update the image
        """
        instance = cls(parent=parent)
        instance.timer = QTimer()
        instance.timer.timeout.connect(
            lambda: instance.update_image(camera.temp_image))
        instance.timer.start(refresh_time)
        return instance