Example #1
0
 def paintEvent(self, evt):
     """
     Protected method handling a paint event.
     
     @param evt reference to the paint event (QPaintEvent)
     """
     if self.__privateMode:
         backgroundColor = QColor(220, 220, 220)     # light gray
         foregroundColor = Qt.black
     else:
         backgroundColor = QApplication.palette().color(QPalette.Base)
         foregroundColor = QApplication.palette().color(QPalette.Text)
     
     if self.__browser is not None:
         p = self.palette()
         progress = self.__browser.progress()
         if progress == 0 or progress == 100:
             if self.__browser.url().scheme() == "https":
                 if QSslCertificate is not None:
                     if self.__browser.page().hasValidSslInfo():
                         backgroundColor = Preferences.getHelp(
                             "SaveUrlColor")
                 else:
                     backgroundColor = Preferences.getHelp("SaveUrlColor")
             p.setBrush(QPalette.Base, backgroundColor)
             p.setBrush(QPalette.Text, foregroundColor)
         else:
             if self.__browser.url().scheme() == "https":
                 if QSslCertificate is not None:
                     if self.__browser.page().hasValidSslInfo():
                         backgroundColor = Preferences.getHelp(
                             "SaveUrlColor")
                 else:
                     backgroundColor = Preferences.getHelp("SaveUrlColor")
             highlight = QApplication.palette().color(QPalette.Highlight)
             r = (highlight.red() + 2 * backgroundColor.red()) // 3
             g = (highlight.green() + 2 * backgroundColor.green()) // 3
             b = (highlight.blue() + 2 * backgroundColor.blue()) // 3
             
             loadingColor = QColor(r, g, b)
             if abs(loadingColor.lightness() -
                     backgroundColor.lightness()) < 20:
                 # special handling for special color schemes (e.g Gaia)
                 r = (2 * highlight.red() + backgroundColor.red()) // 3
                 g = (2 * highlight.green() + backgroundColor.green()) // 3
                 b = (2 * highlight.blue() + backgroundColor.blue()) // 3
                 loadingColor = QColor(r, g, b)
             
             gradient = QLinearGradient(
                 QPointF(0, 0), QPointF(self.width(), 0))
             gradient.setColorAt(0, loadingColor)
             gradient.setColorAt(progress / 100.0 - 0.000001, loadingColor)
             gradient.setColorAt(progress / 100.0, backgroundColor)
             p.setBrush(QPalette.Base, gradient)
         
         self.setPalette(p)
     
     E5LineEdit.paintEvent(self, evt)
Example #2
0
def mixColors(col1, col2, f=.5):
    fromString = False
    if type(col1) == str:
        fromString = True
        col1 = QColor(col1)
    if type(col2) == str:
        col2 = QColor(col2)
    f2 = 1-f
    r = col1.red() * f + col2.red() * f2
    g = col1.green() * f + col2.green() * f2
    b = col1.blue() * f + col2.blue() * f2

    return QColor(r, g, b) if not fromString else QColor(r, g, b).name()
Example #3
0
class ColorSwatchWidget(QLabel):
    def __init__(self, color=QColor(255, 255, 255, 255)):
        if isinstance(color, QColor):
           self.current_color = color
        else:
            # otherwise, it should be an rgb or rgba tuple
            if len(color) == 3:
                self.current_color = QColor(color[0], color[1], color[2], 255)
            else:
                self.current_color = QColor(color[0], color[1], color[2], color[3])
        super(QLabel, self).__init__("")
        self.setMinimumSize(30, 30)

        self.reset_style_sheet()

    def reset_style_sheet(self):
        color_string = "rgb(" + str(self.current_color.red()) + ", " + \
                        str(self.current_color.green()) + ", " + \
                        str(self.current_color.blue()) + ")"
        self.setStyleSheet("QLabel { background-color : "+ color_string + "; "
                           "border-style: outset;"
                           "border-width: 2px;"
                           "border-color: beige;}")

    def set_color(self, color):
        self.current_color = color

    def mousePressEvent(self, e):
        color_dialog = QColorDialog()
        color_dialog.exec_()
        self.current_color = color_dialog.selectedColor()
        self.reset_style_sheet()

    def value(self):
        return self.current_color
Example #4
0
 def _get_flight_bgcolor(fl: XNFlight) -> QColor:
     ret = QColor(255, 255, 255)
     mis = fl.mission
     if mis == 'ownharvest':
         ret = QColor(255, 255, 200)
     elif mis == 'owndeploy':
         ret = QColor(200, 200, 255)
     elif mis == 'ownattack':
         ret = QColor(255, 200, 230)
     elif mis == 'owntransport':
         ret = QColor(200, 255, 200)
     elif mis == 'ownespionage':
         ret = QColor(255, 220, 150)
     elif mis == 'owncolony':
         ret = QColor(190, 210, 255)
     elif mis == 'ownmissile':
         ret = QColor(165, 255, 255)
     elif mis == 'ownbase':
         ret = QColor(153, 200, 255)
     elif mis == 'attack':
         ret = QColor(255, 230, 230)
     if fl.direction == 'return':
         # darken -20%
         ret.setRed(ret.red() * 0.8)
         ret.setGreen(ret.green() * 0.8)
         ret.setBlue(ret.blue() * 0.8)
     return ret
Example #5
0
    def _update_colors(self):
        op = self.topLevelOperatorView
        ctable = self._doneSegmentationLayer.colorTable

        for name, label in self._shownObjects3D.items():
            color = QColor(ctable[op.MST.value.object_names[name]])
            color = (old_div(color.red(), 255.0), old_div(color.green(), 255.0), old_div(color.blue(), 255.0))
            self._renderMgr.setColor(label, color)

        if self._showSegmentationIn3D and self._segmentation_3d_label is not None:
            self._renderMgr.setColor(self._segmentation_3d_label, (0.0, 1.0, 0.0)) # Green
Example #6
0
    def render_color_scribble(self):
        r = []
        g = []
        b = []
        for i in range(8):
            for j in range(8):
                color = QColor(self.scribble_widget.image().pixel(j, i))
                r.append(color.red())
                g.append(color.green())
                b.append(color.blue())

        self.set_rgb(r, g, b)
Example #7
0
def qcolor2rgbmpl(qcolor: QColor) -> Tuple[float, float, float]:
    """
    Calculates the red, green and blue components of the given QColor instance.

    :param qcolor: the input QColor instance
    :type qcolor: QColor
    :return: the triplet of the three RGB color values
    :type: a tuple of three floats
    """

    red = qcolor.red() / 255.0
    green = qcolor.green() / 255.0
    blue = qcolor.blue() / 255.0

    return red, green, blue
Example #8
0
    def hsl_changed(self, *_args):
        if self.changing:
            return

        h, s, l = self.spin_h.value(), self.spin_s.value(), self.spin_l.value()
        hsl = QColor()
        hsl.setHsl(h, s, l)
        r, g, b = hsl.red(), hsl.green(), hsl.blue()

        self.changing = True
        self.spin_r.setValue(r)
        self.spin_g.setValue(g)
        self.spin_b.setValue(b)
        self.changing = False

        self.rgb_led.set_rgb_value(r, g, b)
        self.label_color.setStyleSheet('QLabel {{ background: #{:02x}{:02x}{:02x} }}'.format(r, g, b))
Example #9
0
    def updateGUI(self):

        img = self.camera.getOrigImage()
        if img is not None:
            self.image = QImage(img.data, img.shape[1], img.shape[0], img.shape[1] * img.shape[2], QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)
            self.sourceImg.setPixmap(QPixmap.fromImage(self.image))

        filt = self.getFilterName()
        img = self.camera.getFilteredImage(filt)
        if img is not None:
            self.imageF = QImage(img.data, img.shape[1], img.shape[0], img.shape[1] * img.shape[2], QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)
            self.filterImg.setPixmap(QPixmap.fromImage(self.imageF))

        #print "update"
        pos = self.sourceImg.getMousePos()
        if pos != None:
            #print pos
            x_ini = (self.sourceImg.width()*self.ZOOM_X*pos.x())/self.sourceImg.width()
            y_ini = (self.sourceImg.height()*self.ZOOM_X*pos.y())/self.sourceImg.height()
            rect = QRect(x_ini-100,y_ini-100,200,200)

            #print 'orig', pos.x(), ",", pos.y(), ",", self.sourceImg.size()
            #print 'scale', x_ini, ",", y_ini

            #self.crop.setPixmap(QPixmap.fromImage(self.image.copy(rect).scaled(1000,1000)))

            #print self.sourceImg.pixmap().size()
            im2 = self.image.copy().scaled(self.sourceImg.width()*self.ZOOM_X,self.sourceImg.height()*self.ZOOM_X)
            self.crop.setPixmap(QPixmap.fromImage(im2.copy(rect)))
            #print self.crop.pixmap().size()
            
            pos = self.sourceImg.getMousePos()
            #print pos
            rgb = QColor(self.image.pixel(pos))
            self.tootippixel.setStyleSheet("background: rgb(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + "); border: 1px solid;")
            self.tootippixel.setGeometry(pos.x(), pos.y()+52, 20,20)
            self.pixel.setStyleSheet("background: rgb(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + ");border: 1px solid;")
            text = "XY ["+str(pos.x())+","+str(pos.y())+"]\nrgb(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + ")"
            self.rgbVal.setText(text)
class QAVButton(QPushButton):
    def __init__(self, label):
        """ builds a custom button and displays it"""
        # calls super constuctor
        super(QAVButton, self).__init__(label)
        self.sound = QSoundEffect()
        self.volume = 1.
        self.color = QColor(Qt.gray)

        self.count = 0
        self.duration = 1000
        self.rate = 20

        self.timer = QTimer()
        self.timer.timeout.connect(self.update_anim)

        self.mode = "sin"

        self.pressed.connect(self.start)
        self.released.connect(self.stop)

        self.is_accelerating = False
        self.update_color_with_alha(1)

    def setSound(self, sound_file):
        self.sound.setSource(QUrl.fromLocalFile(sound_file))
        self.sound.setLoopCount(QSoundEffect.Infinite)

    def start(self):
        self.count = 0
        self.sound.play()
        self.timer.start(self.rate)

    def stop(self):
        self.timer.stop()
        self.sound.stop()

    def set_color(self, col):
        self.color = col
        self.update_color_with_alha(1)

    def update_color_with_alha(self, alpha):
        red = self.color.red()
        green = self.color.green()
        blue = self.color.blue()
        bg_style = f"background-color:rgba({red},{green},{blue}, {alpha})"
        self.setStyleSheet(bg_style)

    def update_anim(self):

        #logarithmic (check with perception of luminosity/brighness)
        #val = math.log(count + 1)
        #linear
        if self.mode == "sin":
            val = math.sin(self.count * 2 * math.pi) / 2 + 0.5
        elif self.mode == "lin":
            val = 1 - self.count
        else:
            val = math.log(self.count + 1)

        alpha = round(val * 100) + 155
        self.update_color_with_alha(alpha)

        amplitude = val * 0.8 + 0.2
        self.sound.setVolume(amplitude)

        self.count = self.count + self.rate / self.duration
        # print(count)
        if self.count >= 1 - self.rate / self.duration:
            self.count = 0

            if self.is_accelerating:
                self.duration = max(200, self.duration * 0.95)
Example #11
0
def _deserialize_color(color: QColor) -> AssColor:
    return AssColor(
        color.red(), color.green(), color.blue(), 255 - color.alpha()
    )
Example #12
0
    def updateGUI(self):
        defined_img=None
        if self.file_path is not None:
            defined_img=QImage(self.file_path).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)


        img = self.camera.getOrigImage()
        if defined_img is not None:
            img=defined_img
            self.image=img
        elif defined_img is None:
            if img is not None:
                self.image = QImage(img.data, img.shape[1], img.shape[0], img.shape[1] * img.shape[2], QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)

        if img is not None:
            
            self.sourceImg.setPixmap(QPixmap.fromImage(self.image))

        #Filter Image



        filt = self.getFilterName()
        
        if (filt is not "Orig"):
            disc2 = self.camera.getFilter(filt).apply(self.colorSpace)
            imgDisc = QImage(disc2.data, disc2.shape[1], disc2.shape[0], disc2.shape[1] * disc2.shape[2], QImage.Format_RGB888).scaled(200, 200)
            self.colorSpaceLabel.setPixmap(QPixmap.fromImage(imgDisc))

        img = self.camera.getOrigImage()
        if defined_img is not None:
            img2=cv2.imread(self.file_path)
            img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
            if (filt is not "Orig"):
                self.imageF=self.camera.getFilter(filt).apply(img2)
                self.imageF= QImage(self.imageF.data, self.imageF.shape[1], self.imageF.shape[0], self.imageF.shape[1] * self.imageF.shape[2], QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)
            else:
                self.imageF=QImage(img2.data, img2.shape[1], img2.shape[0], img2.shape[1] * img2.shape[2], QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)

        elif defined_img is None:
            if img is not None:
                img = self.camera.getFilteredImage(filt)
                self.imageF = QImage(img.data, img.shape[1], img.shape[0], img.shape[1] * img.shape[2], QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX) 
            
        
        #img = self.camera.getFilteredImage(filt)

        self.filterImg.setPixmap(QPixmap.fromImage(self.imageF))
            

        #print "update"
        pos = self.sourceImg.getMousePos()
        if pos != None:
            #print pos
            x_ini = (self.sourceImg.width()*self.ZOOM_X*pos.x())/self.sourceImg.width()
            y_ini = (self.sourceImg.height()*self.ZOOM_X*pos.y())/self.sourceImg.height()
            rect = QRect(x_ini-100,y_ini-100,200,200)

            #print 'orig', pos.x(), ",", pos.y(), ",", self.sourceImg.size()
            #print 'scale', x_ini, ",", y_ini

            #self.crop.setPixmap(QPixmap.fromImage(self.image.copy(rect).scaled(1000,1000)))

            #print self.sourceImg.pixmap().size()
            im2 = self.image.copy().scaled(self.sourceImg.width()*self.ZOOM_X,self.sourceImg.height()*self.ZOOM_X)
            self.crop.setPixmap(QPixmap.fromImage(im2.copy(rect)))
            #print self.crop.pixmap().size()
            
            pos = self.sourceImg.getMousePos()
            #print pos
            rgb = QColor(self.image.pixel(pos))
            self.tootippixel.setStyleSheet("background: rgb(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + "); border: 1px solid;")
            self.tootippixel.setGeometry(pos.x(), pos.y()+52, 20,20)
            self.pixel.setStyleSheet("background: rgb(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + ");border: 1px solid;")
            text = "XY ["+str(pos.x())+","+str(pos.y())+"]\nrgb(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + ")"
            self.rgbVal.setText(text)
Example #13
0
class Canvas(widgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.background_color = QColor('#000000')
        self.rubberMode = False
        self.rubberModeStrokeWidthFctr = 20
        self.stroke_width = 1
        self.pen_color = QColor('#00FF00')
        self.col_prev_rct = QRect(0, 0, 20, 20)

        self.initImage()

        self.points = list()
        self.curDragPoints = list()
        self._initPointsAverager()
        self.reg = list()

#		self.setMouseTracking(True)

    def setPointsData(self, data):
        self.points = data.points
        self.img = data.img
        self.validateImage()
        self.update()

    def setPoints(self, points):
        self.points = points

    def validateImage(self):
        if self.img.isNull():
            self.initImage()

    def getPointsData(self):
        return PointsData(self.points, self.img)

    @pyqtSlot()
    def retrieveUpdatedData(self):
        try:
            data = self.dataRetriever()
            self.setPointsData(data)
        except:
            pass

    @pyqtSlot()
    def updateData(self):
        try:
            self.dataUpdater(self.getPointsData())
        except:
            pass

    def getPoints(self):
        return self.points

    def initImage(self):
        self.img = initImage(self.size(), self.background_color)

    def drawColorPreview(self):
        self.painter.setBrush(QBrush(self.pen_color))
        self.painter.drawRect(self.col_prev_rct)

    def rgba(self):
        return (self.pen_color.red(), self.pen_color.green(),
                self.pen_color.blue(), self.pen_color.alpha())

    @pyqtSlot(int, int, int, int)
    def rgba_changed(self, r, g, b, a):
        self.pen_color = QColor(r, g, b, a)
        self.update()

    @pyqtSlot('QString')
    def setPenColor(self, col_hex):
        self.pen_color = QColor(col_hex)
        self.update()

    @pyqtSlot()
    def saveImage(self):
        if self.img.isNull():
            return
        img_path = saveFileDialog(self)
        if img_path:
            pixmp = QPixmap.fromImage(self.img)
            pixmp.save(img_path, quality=100)

    @pyqtSlot(int)
    def setStrokeWidth(self, sw):
        self.stroke_width = max(sw, 0.25)

    def strokeWidth(self):
        return self.stroke_width

    def resizeEvent(self, e):
        if not self.img.isNull():
            self.img = resizeImage(self.img, self.size(),
                                   self.background_color)

    def paintEvent(self, event):
        painter = QPainter(self)
        self.painter = painter

        self.paintBackground()

        if not self.img.isNull():
            pixmp = QPixmap.fromImage(self.img)
            painter.drawPixmap(pixmp.rect(), pixmp, pixmp.rect())

#		for p in self.curDragPoints:
#			col = self.background_color if self.rubberMode else self.pen_color
#			self.drawDispersePoint(p, self.stroke_width, col=col)

        self.drawColorPreview()

        painter.end()
        del painter

    def createImagePainter(self):
        if self.img.isNull():
            return
        painter = QPainter(self.img)
        self.painter = painter

    def deletePainter(self):
        self.painter.end()
        del self.painter

    def drawLinesOnImage(self, points):
        if self.img.isNull():
            return
        self.createImagePainter()
        self.drawLines(points)
        self.deletePainter()

    def drawLatestAveragedPontsOnImage(self, averager=None):
        if averager is None:
            averager = self.pntsAvrgr

        # self.pntsAvrgr.getLatestAveragedPoints() - if no new points are available, None is returned!
        latestAvrgdPoints = averager.getLatestAveragedPoints()
        if latestAvrgdPoints is not None:
            self.drawLinesOnImage(latestAvrgdPoints)
        self.update()

    @pyqtSlot()
    def clearCanvas(self):
        self._clearPoints()
        self._clearImg()
        self.updateData()
        self.update()

    def _clearImg(self):
        if self.img.isNull():
            return
        painter = QPainter(self.img)
        painter.setBrush(QBrush(self.background_color))
        painter.drawRect(self.img.rect())
        painter.end()
        del painter

    def _clearPoints(self):
        self.points.clear()
        self.curDragPoints.clear()

    def paintBackground(self):
        self.painter.setBrush(QBrush(self.background_color))
        self.painter.drawRect(0, 0, 10000, 10000)

    def mouseMoveEvent(self, e):
        self.mouseMovePressed(e)

    def mousePressEvent(self, e):
        btns = e.buttons()

        if btns == Qt.LeftButton or btns == Qt.RightButton:
            self.rubberMode = btns == Qt.RightButton
            self._initPointsAverager()
            self.curDragPoints = list()
            self.addPoint((e.x(), e.y()))

    def _onAvrgrFinalized(self, averager):
        self.points.append(averager.getPoints())
        self.updateData()
        self.update()

    def mouseReleaseEvent(self, e):
        #pnts_cnt = len(self.curDragPoints)

        self.pntsAvrgr.finalize()
        #self.points.append( self.pntsAvrgr.getPoints() )
        #self.drawLatestAveragedPontsOnImage()

        self.curDragPoints = list()

        self.rubberMode = False
        self.update()

    def _initPointsAverager(self):
        pntsAvrgr = PointsAverager()
        pntsAvrgr.rubberMode = self.rubberMode

        def newAvrgPntsAvlbl():
            rmBckup = self.rubberMode
            self.rubberMode = pntsAvrgr.rubberMode
            self._newAveragedPointsAvailable(pntsAvrgr)
            self.rubberMode = rmBckup

        def onFnlzd():
            self._onAvrgrFinalized(pntsAvrgr)

        pntsAvrgr.onNewAvergedPointsAvailable.connect(newAvrgPntsAvlbl)
        pntsAvrgr.onFinalized.connect(onFnlzd)

        self.pntsAvrgr = pntsAvrgr

    def _newAveragedPointsAvailable(self, averager):
        self.drawLatestAveragedPontsOnImage(averager)

    def mouseMovePressed(self, e):
        curPnt = (e.x(), e.y())
        self.addPoint(curPnt)

    def addPoint(self, p):
        self.curDragPoints.append(p)
        self.pntsAvrgr.addPoint(p)
        #self.drawLatestAveragedPontsOnImage()
        self.update()

    def drawLines(self, pnts):
        pen = QPen()
        pen.setWidth(1)
        pen_width = self.stroke_width
        if self.rubberMode:
            pen_width *= self.rubberModeStrokeWidthFctr
        col = self.background_color if self.rubberMode else self.pen_color

        ld = LineDrawer()
        ld.addPoints(pnts)
        ld.drawLines(self.painter, col, pen_width)
class MovablePolyLine(QGraphicsObject):
    def __init__(self, parent=None):
        super(MovablePolyLine, self).__init__(parent)
        self.setZValue(1000)
        self.polygon = QPolygonF()
        self.radius = 5.0
        self.itemList = []
        self.rect = QRectF()
        self.color = QColor(255,0,0)

        self.setOpacity(0.5)
        # self.setHandlesChildEvents(False)
        # self.setFlags(QGraphicsItem.ItemIsMovable)

        self.isDrawLine = True
        self.drawItemFlags = None

        self.points = None

        self.itemType = QGraphicsEllipseItem

    def setDrawLine(self, flag):
        self.isDrawLine = flag

    def setDrawItems(self, flags):
        self.drawItemFlags = flags
        for item, flag in zip(self.itemList, flags):
            if flag:
                item.show()
            else:
                item.hide()

    def setRadius(self, r):
        self.radius = r

        radii = 2*self.radius
        rectList = [QRectF(-self.radius, -self.radius, radii, radii) for p in self.points]
        for item, rect in zip(self.itemList, rectList):
            item.setRect(rect)

    def setLineWidth(self, w):
        self.lineWidth = w
        self.update()

    def getLineWidth(self):
        return self.lineWidth


    def setColor(self, rgb):
        self.color = QColor(*rgb)
        for item in self.itemList:
            item.setBrush(self.color)

    def getColor(self):
        return [self.color.red(),self.color.green(),self.color.blue()]
    def getRadius(self):
        return self.radius

    def setPoints(self, ps=None, flags=None):
        if ps is not None and self.points is not None:
            if len(ps)==len(self.points):
                self.points = ps
                for item, point in zip(self.itemList, self.points):
                    item.setPos(*point)
                    item.mouseMoveEvent = self.generateItemMouseMoveEvent(item, point)
                    item.mousePressEvent = self.generateItemMousePressEvent(item, point)
                self.update()
                return

        scene = self.scene()
        if scene is not None:
            for item in self.itemList:
                scene.removeItem(item)
                del item
        self.itemList.clear()

        if ps is not None:
            self.points = ps

        if flags is not None:
            self.drawItemFlags = flags

        if self.points is not None:
            radii = 2*self.radius
            rectList = [QRectF(-self.radius, -self.radius, radii, radii) for p in self.points]
            self.itemList = [self.itemType(self) for rect in rectList]

            for item, point, rect, flag in zip(self.itemList, self.points, rectList, self.drawItemFlags):
                item.setBrush(self.color)
                item.setRect(rect)
                item.setPos(*point)

                if not flag:
                    item.hide()

                item.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemSendsScenePositionChanges)
                item.setAcceptHoverEvents(True)
                item.mouseMoveEvent = self.generateItemMouseMoveEvent(item, point)
                item.mousePressEvent = self.generateItemMousePressEvent(item, point)

    def setRect(self, rect):
        self.rect = rect

    def generateItemMouseMoveEvent(self, item, point):
        def itemMouseMoveEvent(event):
            self.itemType.mouseMoveEvent(item, event)
            centerPos = item.scenePos()

            point[0] = centerPos.x()
            point[1] = centerPos.y()
            self.update()
        return itemMouseMoveEvent

    def generateItemMousePressEvent(self, item, point):
        def itemMousePressEvent(event):
            self.itemType.mousePressEvent(item, event)
            pass
        return itemMousePressEvent

    def boundingRect(self):
        return self.rect

    def paint(self, painter, option, widget):
        if self.points is not None and self.isDrawLine:
            painter.save()

            pen = QPen(self.color)
            pen.setWidth(self.getLineWidth())

            painter.setPen(pen)
            qPoints = [QPointF(*p.tolist()) for p in self.points]
            polygon = QPolygonF(qPoints)
            painter.drawPolyline(polygon)

            painter.restore()
Example #15
0
 def mouseMoveEvent(self, event):
     if not self.cross:
         mouse_x = event.pos().x()
         mouse_y = event.pos().y()
         self.mouse_pos = event.pos()
         if self.img != None:
             rgb = QColor(self.img.pixel(self.mouse_pos))
             text = "XY[" + str(mouse_x) + "," + str(mouse_y)+ "] RGB(" + str(rgb.red()) + "," + str(rgb.green()) + "," + str(rgb.blue()) + ")"
             QToolTip.showText(QPoint(QCursor.pos()), text)
         self.repaint()
Example #16
0
def color_values(color: QColor) -> t.Tuple[int, int, int, int]:
    return color.red(), color.green(), color.blue(), color.alpha()
Example #17
0
def blend_colors(color1: QColor, color2: QColor, ratio: float) -> int:
    return qRgb(
        int(color1.red() * (1 - ratio) + color2.red() * ratio),
        int(color1.green() * (1 - ratio) + color2.green() * ratio),
        int(color1.blue() * (1 - ratio) + color2.blue() * ratio),
    )
Example #18
0
class GuiProjectEditStatus(QWidget):

    COL_LABEL = 0
    COL_USAGE = 1

    KEY_ROLE = Qt.UserRole
    COL_ROLE = Qt.UserRole + 1
    NUM_ROLE = Qt.UserRole + 2

    def __init__(self, mainGui, theProject, isStatus):
        QWidget.__init__(self, mainGui)

        self.mainConf   = novelwriter.CONFIG
        self.mainGui    = mainGui
        self.theProject = theProject
        self.mainTheme  = mainGui.mainTheme

        if isStatus:
            self.theStatus = self.theProject.statusItems
            pageLabel = self.tr("Novel File Status Levels")
            colSetting = "statusColW"
        else:
            self.theStatus = self.theProject.importItems
            pageLabel = self.tr("Note File Importance Levels")
            colSetting = "importColW"

        wCol0 = self.mainConf.pxInt(
            self.theProject.options.getInt("GuiProjectSettings", colSetting, 130)
        )

        self.colDeleted = []
        self.colChanged = False
        self.selColour  = QColor(100, 100, 100)

        self.iPx = self.mainTheme.baseIconSize

        # The List
        # ========

        self.listBox = QTreeWidget()
        self.listBox.setHeaderLabels([
            self.tr("Label"), self.tr("Usage"),
        ])
        self.listBox.itemSelectionChanged.connect(self._selectedItem)
        self.listBox.setColumnWidth(self.COL_LABEL, wCol0)
        self.listBox.setIndentation(0)

        for key, entry in self.theStatus.items():
            self._addItem(key, entry["name"], entry["cols"], entry["count"])

        # List Controls
        # =============

        self.addButton = QPushButton(self.mainTheme.getIcon("add"), "")
        self.addButton.clicked.connect(self._newItem)

        self.delButton = QPushButton(self.mainTheme.getIcon("remove"), "")
        self.delButton.clicked.connect(self._delItem)

        self.upButton = QPushButton(self.mainTheme.getIcon("up"), "")
        self.upButton.clicked.connect(lambda: self._moveItem(-1))

        self.dnButton = QPushButton(self.mainTheme.getIcon("down"), "")
        self.dnButton.clicked.connect(lambda: self._moveItem(1))

        # Edit Form
        # =========

        self.editName = QLineEdit()
        self.editName.setMaxLength(40)
        self.editName.setEnabled(False)
        self.editName.setPlaceholderText(self.tr("Select item to edit"))

        self.colPixmap = QPixmap(self.iPx, self.iPx)
        self.colPixmap.fill(QColor(100, 100, 100))
        self.colButton = QPushButton(QIcon(self.colPixmap), self.tr("Colour"))
        self.colButton.setIconSize(self.colPixmap.rect().size())
        self.colButton.clicked.connect(self._selectColour)

        self.saveButton = QPushButton(self.tr("Save"))
        self.saveButton.clicked.connect(self._saveItem)

        # Assemble
        # ========

        self.listControls = QVBoxLayout()
        self.listControls.addWidget(self.addButton)
        self.listControls.addWidget(self.delButton)
        self.listControls.addWidget(self.upButton)
        self.listControls.addWidget(self.dnButton)
        self.listControls.addStretch(1)

        self.editBox = QHBoxLayout()
        self.editBox.addWidget(self.editName)
        self.editBox.addWidget(self.colButton)
        self.editBox.addWidget(self.saveButton)

        self.mainBox = QVBoxLayout()
        self.mainBox.addWidget(self.listBox)
        self.mainBox.addLayout(self.editBox)

        self.innerBox = QHBoxLayout()
        self.innerBox.addLayout(self.mainBox)
        self.innerBox.addLayout(self.listControls)

        self.outerBox = QVBoxLayout()
        self.outerBox.addWidget(QLabel("<b>%s</b>" % pageLabel))
        self.outerBox.addLayout(self.innerBox)

        self.setLayout(self.outerBox)

        return

    def getNewList(self):
        """Return list of entries.
        """
        if self.colChanged:
            newList = []
            for n in range(self.listBox.topLevelItemCount()):
                item = self.listBox.topLevelItem(n)
                newList.append({
                    "key":  item.data(self.COL_LABEL, self.KEY_ROLE),
                    "name": item.text(self.COL_LABEL),
                    "cols": item.data(self.COL_LABEL, self.COL_ROLE),
                })
            return newList, self.colDeleted

        return [], []

    ##
    #  User Actions
    ##

    def _selectColour(self):
        """Open a dialog to select the status icon colour.
        """
        if self.selColour is not None:
            newCol = QColorDialog.getColor(
                self.selColour, self, self.tr("Select Colour")
            )
            if newCol.isValid():
                self.selColour = newCol
                pixmap = QPixmap(self.iPx, self.iPx)
                pixmap.fill(newCol)
                self.colButton.setIcon(QIcon(pixmap))
                self.colButton.setIconSize(pixmap.rect().size())
        return

    def _newItem(self):
        """Create a new status item.
        """
        newItem = self._addItem(None, self.tr("New Item"), (100, 100, 100), 0)
        newItem.setBackground(self.COL_LABEL, QBrush(QColor(0, 255, 0, 70)))
        newItem.setBackground(self.COL_USAGE, QBrush(QColor(0, 255, 0, 70)))
        self.colChanged = True
        return

    def _delItem(self):
        """Delete a status item.
        """
        selItem = self._getSelectedItem()
        if selItem is not None:
            iRow = self.listBox.indexOfTopLevelItem(selItem)
            if selItem.data(self.COL_LABEL, self.NUM_ROLE) > 0:
                self.mainGui.makeAlert(self.tr(
                    "Cannot delete a status item that is in use."
                ), nwAlert.ERROR)
            else:
                self.listBox.takeTopLevelItem(iRow)
                self.colDeleted.append(selItem.data(self.COL_LABEL, self.KEY_ROLE))
                self.colChanged = True
        return

    def _saveItem(self):
        """Save changes made to a status item.
        """
        selItem = self._getSelectedItem()
        if selItem is not None:
            selItem.setText(self.COL_LABEL, simplified(self.editName.text()))
            selItem.setIcon(self.COL_LABEL, self.colButton.icon())
            selItem.setData(self.COL_LABEL, self.COL_ROLE, (
                self.selColour.red(), self.selColour.green(), self.selColour.blue()
            ))
            self.editName.setEnabled(False)
            self.colChanged = True

        return

    def _addItem(self, key, name, cols, count):
        """Add a status item to the list.
        """
        pixmap = QPixmap(self.iPx, self.iPx)
        pixmap.fill(QColor(*cols))

        item = QTreeWidgetItem()
        item.setText(self.COL_LABEL, name)
        item.setIcon(self.COL_LABEL, QIcon(pixmap))
        item.setData(self.COL_LABEL, self.KEY_ROLE, key)
        item.setData(self.COL_LABEL, self.COL_ROLE, cols)
        item.setData(self.COL_LABEL, self.NUM_ROLE, count)
        item.setText(self.COL_USAGE, self._usageString(count))

        self.listBox.addTopLevelItem(item)

        return item

    def _moveItem(self, step):
        """Move and item up or down step.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return

        tIndex = self.listBox.indexOfTopLevelItem(selItem)
        nChild = self.listBox.topLevelItemCount()
        nIndex = tIndex + step
        if nIndex < 0 or nIndex >= nChild:
            return

        cItem = self.listBox.takeTopLevelItem(tIndex)
        self.listBox.insertTopLevelItem(nIndex, cItem)
        self.listBox.clearSelection()

        cItem.setSelected(True)
        self.colChanged = True

        return

    def _selectedItem(self):
        """Extract the info of a selected item and populate the settings
        boxes and button.
        """
        selItem = self._getSelectedItem()
        if selItem is None:
            return

        cols = selItem.data(self.COL_LABEL, self.COL_ROLE)
        name = selItem.text(self.COL_LABEL)

        pixmap = QPixmap(self.iPx, self.iPx)
        pixmap.fill(QColor(*cols))
        self.selColour = QColor(*cols)
        self.editName.setText(name)
        self.colButton.setIcon(QIcon(pixmap))
        self.editName.setEnabled(True)
        self.editName.selectAll()
        self.editName.setFocus()

        return

    ##
    #  Internal Functions
    ##

    def _getSelectedItem(self):
        """Get the currently selected item.
        """
        selItem = self.listBox.selectedItems()
        if len(selItem) > 0:
            return selItem[0]
        return None

    def _usageString(self, nUse):
        """Generate usage string.
        """
        if nUse == 0:
            return self.tr("Not in use")
        elif nUse == 1:
            return self.tr("Used once")
        else:
            return self.tr("Used by {0} items").format(nUse)
Example #19
0
class AppWindow(QMainWindow):
    def __init__(self):
        super(AppWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.img_area.setScaledContents(False)
        self.ui.img_area.setStyleSheet('border: 1px solid red')
        self.add_tool_bar()
        self.bind_actions()
        self.init_vars()

    def init_vars(self):
        self.open_mode = OPEN_MODE.OPEN_FILE
        self.opened_files = []
        self.cur_img = None
        self.panel_pic = None  # 用来在上面绘制矩阵等形状
        self.origin_img = None  # 保留原始大小的图片
        self.labelimg = None
        self.scale = 1
        self.cur_rect_list = []
        self.cur_label_list = []
        self.histroty = []
        self.fill_color = QColor('green')
        self.pixel_range = [-5, 5]
        self.state = STATE.NORMAL
        self.start_point = None
        self.end_point = None
        self.polygon_points = None
        self.ellipse_points = None
        self.modified = False
        self.saved = False

        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.DEBUG)
        handler = logging.StreamHandler()
        handler.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(levelname)s %(funcName)s %(message)s')
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)

    def refresh_vars(self):
        self.cur_img = None
        self.panel_pic = None  # 用来在上面绘制矩阵等形状
        self.origin_img = None  # 保留原始大小的图片
        self.labelimg = None
        self.scale = 1
        self.cur_rect_list = []
        self.cur_label_list = []
        self.histroty = []
        self.state = STATE.NORMAL
        self.ui.actionRectangle.setChecked(False)
        self.ui.actionPolygon.setChecked(False)
        self.ui.actionEllipse.setChecked(False)
        self.start_point = None
        self.end_point = None
        self.polygon_points = None
        self.ellipse_points = None
        self.modified = False
        self.saved = False

    def bind_actions(self):
        self.ui.actionOpen_File.triggered.connect(self.open_file)
        self.ui.actionOpen_Dir.triggered.connect(self.open_dir)
        self.ui.file_list.itemClicked.connect(self.file_list_item_changed)
        self.ui.actionZoom_In.triggered.connect(self.zoom_in_pic)
        self.ui.actionZoom_Out.triggered.connect(self.zoom_out_pic)
        self.ui.img_area.mouse_pressed.connect(self.mouse_pressed)
        self.ui.img_area.mouse_move.connect(self.mouse_move)
        self.ui.img_area.mouse_release.connect(self.mouse_release)
        self.ui.actionfill_color.triggered.connect(self.set_fill_color)
        self.ui.actionSet_Pixel_Range.triggered.connect(self.set_pixel_range)
        self.ui.actionUndo.triggered.connect(self.undo)
        self.ui.actionSave.triggered.connect(self.save)
        self.ui.actionPolygon.triggered.connect(self.create_polygon)
        self.ui.actionRectangle.triggered.connect(self.create_rectangle)
        self.ui.actionEllipse.triggered.connect(self.create_ellipse)

    def save(self):
        name = str(self.selected_filename.absolute())
        items = name.split('.')
        output_filename = '.'.join(items[:-1]) + '.npy'
        np.save(output_filename, self.labelimg)
        self.saved = True
        self.modified = False

    def undo(self, checked):
        if self.state == STATE.DRAW_POLYGON and self.polygon_points is not None and self.polygon_points[
                'finish'] is False:
            if len(self.polygon_points['points']) == 1:
                self.polygon_points = None
            elif len(self.polygon_points['points']) > 1:
                self.polygon_points['points'].pop(-1)
                self.draw_lines(self.polygon_points['points'], False)
                if self.labelimg is not None:
                    pic = self.draw_points()
                    self.show_pic(file_name=None, content=pic)
                else:
                    self.show_pic(file_name=None, content=self.panel_pic)
        else:
            if len(self.histroty) == 0:
                return
            x, y = self.histroty.pop(-1)
            self.labelimg[x, y] = 0
            pic = self.draw_points()
            self.show_pic(file_name=None, content=pic)
            self.modified = True

    def set_fill_color(self, checked):
        color = QColorDialog.getColor()
        if color.isValid():
            self.fill_color = color

    def set_pixel_range(self, checked):
        dialog = PixelRangeDialog()
        if dialog.exec_():
            v1, v2 = dialog.get_result()
            self.pixel_range = [v1, v2]
            self.logger.debug(self.pixel_range)

    def create_polygon(self, checked):
        if checked:
            self.state = STATE.DRAW_POLYGON
            self.ui.actionEllipse.setChecked(False)
            self.ui.actionRectangle.setChecked(False)
        else:
            self.state = STATE.NORMAL

    def create_rectangle(self, checked):
        if checked:
            self.state = STATE.DRAW_RECTANGLE
            self.ui.actionEllipse.setChecked(False)
            self.ui.actionPolygon.setChecked(False)
        else:
            self.state = STATE.NORMAL

    def create_ellipse(self, checked):
        if checked:
            self.state = STATE.DRAW_ELLIPSE
            self.ui.actionPolygon.setChecked(False)
            self.ui.actionRectangle.setChecked(False)
        else:
            self.state = STATE.NORMAL

    def pos_in_img_area(self, pos: PyQt5.QtCore.QPoint):
        if self.cur_img is None:
            return False, None
        width = self.ui.img_area.width()
        height = self.ui.img_area.height()
        img_height, img_width, _ = self.cur_img.shape
        w = (width - img_width) // 2
        h = (height - img_height) // 2
        x_valid = w <= pos.x() <= w + img_width
        y_valid = h <= pos.y() <= h + img_height
        valid = x_valid and y_valid
        if valid:
            return True, (pos.x() - w, pos.y() - h)
        else:
            return False, None

    def mouse_pressed(self, ev: QMouseEvent):
        if self.state == STATE.NORMAL:
            return
        if ev.button() == Qt.LeftButton:
            pos = ev.pos()
            valid, relative_pos = self.pos_in_img_area(pos)
            self.logger.debug(valid)
            if valid:
                self.logger.debug(relative_pos)
                point = (int(relative_pos[0] / self.scale),
                         int(relative_pos[1] / self.scale))
                if self.state == STATE.DRAW_RECTANGLE:
                    self.start_point = point
                    self.end_point = None
                    self.logger.debug(self.start_point)
                elif self.state == STATE.DRAW_POLYGON:
                    if self.polygon_points is None or self.polygon_points[
                            'finish'] is True:
                        self.polygon_points = {
                            'finish': False,
                            'points': [point]
                        }
                    else:
                        p1 = np.array([
                            self.polygon_points['points'][0][0] * self.scale,
                            self.polygon_points['points'][0][1] * self.scale
                        ])
                        p2 = np.array(
                            [point[0] * self.scale, point[1] * self.scale])
                        dis = np.linalg.norm(p1 - p2, 2)
                        if dis < 10:
                            self.polygon_points['finish'] = True
                            self.draw_lines(self.polygon_points['points'],
                                            True)
                        else:
                            self.polygon_points['points'].append(point)
                            self.draw_lines(self.polygon_points['points'],
                                            False)
                        if self.labelimg is not None:
                            pic = self.draw_points()
                            self.show_pic(file_name=None, content=pic)
                        else:
                            self.show_pic(file_name=None,
                                          content=self.panel_pic)
                elif self.state == STATE.DRAW_ELLIPSE:
                    if self.ellipse_points is None:
                        self.ellipse_points = {'points': [point], 'info': None}
                    elif len(self.ellipse_points['points']) == 1:
                        self.ellipse_points['points'].append(point)
                        self.draw_lines(self.ellipse_points['points'], False)
                        if self.labelimg is not None:
                            pic = self.draw_points()
                            self.show_pic(file_name=None, content=pic)
                        else:
                            self.show_pic(file_name=None,
                                          content=self.panel_pic)
                    elif len(self.ellipse_points['points']) == 2:
                        self.ellipse_points['points'].append(point)
                        self.ellipse_points['info'] = self.draw_ellipse(
                            self.ellipse_points['points'])
                        if self.labelimg is not None:
                            pic = self.draw_points()
                            self.show_pic(file_name=None, content=pic)
                        else:
                            self.show_pic(file_name=None,
                                          content=self.panel_pic)
                    else:
                        self.ellipse_points = {'points': [point], 'info': None}
                else:
                    raise NotImplementedError()
        elif ev.button() == Qt.RightButton:
            pass

    def mouse_move(self, ev: QMouseEvent):
        if self.state == STATE.NORMAL:
            return
        pos = ev.pos()
        valid, relative_pos = self.pos_in_img_area(pos)
        if valid:
            relative_pos = (int(relative_pos[0] / self.scale),
                            int(relative_pos[1] / self.scale))
            if self.state == STATE.DRAW_RECTANGLE:
                self.draw_rect(self.start_point, relative_pos)
                if self.labelimg is not None:
                    pic = self.draw_points()
                    self.show_pic(file_name=None, content=pic)
                else:
                    self.show_pic(file_name=None, content=self.panel_pic)
            elif self.state == STATE.DRAW_POLYGON:
                pass
            elif self.state == STATE.DRAW_ELLIPSE:
                pass
            else:
                raise NotImplementedError()

    def draw_ellipse(self, points):
        color_r, color_g, color_b = self.fill_color.red(
        ), self.fill_color.green(), self.fill_color.blue()
        points = list(
            map(
                lambda item:
                (int(item[0] * self.scale), int(item[1] * self.scale)),
                points))
        p1 = np.array(points[0])
        p2 = np.array(points[1])
        if p1[0] > p2[0]:
            p1, p2 = p2, p1
        p3 = np.array(points[2])
        center = tuple((p1 + p2) // 2)
        r1 = int(np.linalg.norm(p1 - p2, 2) / 2)
        a = p2[1] - p1[1]
        b = p1[0] - p2[0]
        c = p2[0] * p1[1] - p1[0] * p2[1]
        r2 = int(np.abs(a * p3[0] + b * p3[1] + c) / np.sqrt(a**2 + b**2))
        if r1 > r2:
            theta = -1 * (np.arctan(a / b) * 180) / np.pi
            self.panel_pic = cv.ellipse(self.cur_img.copy(), center, (r1, r2),
                                        theta, 0, 360,
                                        (color_r, color_g, color_b), 1)
            return ((int(center[0] / self.scale), int(center[1] / self.scale)),
                    (int(r1 / self.scale), int(r2 / self.scale)), theta)
        else:
            theta = (np.arctan(a / b) * 180) / np.pi
            if theta > 0:
                theta = 90 - theta
            else:
                theta = -90 - theta
            self.panel_pic = cv.ellipse(self.cur_img.copy(), center, (r2, r1),
                                        theta, 0, 360,
                                        (color_r, color_g, color_b), 1)
            return ((int(center[0] / self.scale), int(center[1] / self.scale)),
                    (int(r2 / self.scale), int(r1 / self.scale)), theta)

    def draw_lines(self, points, end=False):
        b, g, r = self.fill_color.blue(), self.fill_color.green(
        ), self.fill_color.red()
        temp_img = self.cur_img.copy()
        points = list(
            map(
                lambda item:
                (int(item[0] * self.scale), int(item[1] * self.scale)),
                points))
        for i in range(len(points) - 1):
            temp_img = cv.line(temp_img, points[i], points[i + 1], (r, g, b),
                               1)
        if end:
            temp_img = cv.line(temp_img, points[-1], points[0], (r, g, b), 1)
        self.panel_pic = temp_img

    def draw_rect(self, start_point, end_point):
        b, g, r = self.fill_color.blue(), self.fill_color.green(
        ), self.fill_color.red()
        self.fill_color.rgb()
        start_point = (int(start_point[0] * self.scale),
                       int(start_point[1] * self.scale))
        end_point = (int(end_point[0] * self.scale),
                     int(end_point[1] * self.scale))
        self.panel_pic = cv.rectangle(self.cur_img.copy(), start_point,
                                      end_point, (r, g, b), 1)

    def draw_points(self):
        if self.labelimg is None:
            return
        b, g, r = self.fill_color.blue(), self.fill_color.green(
        ), self.fill_color.red()
        x, y = np.where(self.labelimg == 1)
        temp = self.panel_pic.copy()
        for i in range(x.shape[0]):
            cv.circle(temp, (int(y[i] * self.scale), int(x[i] * self.scale)),
                      1, (r, g, b), 1)
        return temp

    def mouse_release(self, ev: QMouseEvent):
        if self.state == STATE.NORMAL:
            return
        if ev.button() == Qt.LeftButton:
            if self.state == STATE.DRAW_RECTANGLE:
                pos = ev.pos()
                valid, relative_pos = self.pos_in_img_area(pos)
                self.logger.debug(valid)
                if valid:
                    self.logger.debug(relative_pos)
                    self.end_point = (int(relative_pos[0] / self.scale),
                                      int(relative_pos[1] / self.scale))
        elif ev.button() == Qt.RightButton:
            if self.state == STATE.NORMAL:
                return
            if self.state == STATE.DRAW_RECTANGLE:
                if self.start_point is None or self.end_point is None:
                    return
                pos = ev.pos()
                valid, relative_pos = self.pos_in_img_area(pos)
                if valid:
                    click_pos = (int(relative_pos[0] / self.scale),
                                 int(relative_pos[1] / self.scale))
                    min_x, max_x = min(self.start_point[0],
                                       self.end_point[0]), max(
                                           self.start_point[0],
                                           self.end_point[0])
                    min_y, max_y = min(self.start_point[1],
                                       self.end_point[1]), max(
                                           self.start_point[1],
                                           self.end_point[1])
                    self.logger.debug(click_pos)
                    if min_x <= click_pos[0] <= max_x and min_y <= click_pos[
                            1] <= max_y:
                        pixel_value = self.origin_img[click_pos[1],
                                                      click_pos[0], 0]
                        low, high = pixel_value + \
                            self.pixel_range[0], pixel_value + \
                            self.pixel_range[1]
                        selected_area = self.origin_img[min_y:max_y + 1,
                                                        min_x:max_x + 1, 0]
                        x, y = np.where(
                            (selected_area >= low) * (selected_area <= high))
                        x = x + min_y
                        y = y + min_x
                        self.labelimg[x, y] = 1
                        pic = self.draw_points()
                        self.show_pic(file_name=None, content=pic)
                        self.histroty.append((x, y))
                        self.modified = True
            elif self.state == STATE.DRAW_POLYGON:
                if self.polygon_points is None or self.polygon_points[
                        'finish'] is False:
                    return
                pos = ev.pos()
                valid, relative_pos = self.pos_in_img_area(pos)
                if valid:
                    click_pos = (int(relative_pos[0] / self.scale),
                                 int(relative_pos[1] / self.scale))
                    self.logger.debug(click_pos)
                    x_pos = np.array(
                        [item[0] for item in self.polygon_points['points']])
                    y_pos = np.array(
                        [item[1] for item in self.polygon_points['points']])
                    min_x, max_x = x_pos.min(), x_pos.max()
                    min_y, max_y = y_pos.min(), y_pos.max()
                    p = np.array(self.polygon_points['points']).reshape(
                        [1, len(self.polygon_points['points']), 2])
                    p[0, :, 0] -= min_x
                    p[0, :, 1] -= min_y
                    mask = np.zeros([max_y - min_y + 1, max_x - min_x + 1],
                                    np.uint8)
                    mask = cv.fillPoly(mask, p, 1)
                    pixel_value = self.origin_img[click_pos[1], click_pos[0],
                                                  0]
                    low, high = pixel_value + \
                        self.pixel_range[0], pixel_value + self.pixel_range[1]
                    selected_img = self.origin_img[min_y:max_y + 1,
                                                   min_x:max_x + 1, 0]
                    x, y = np.where(
                        (selected_img >= low) * (selected_img <= high) * mask)
                    x = x + min_y
                    y = y + min_x
                    self.labelimg[x, y] = 1
                    pic = self.draw_points()
                    self.show_pic(file_name=None, content=pic)
                    self.histroty.append((x, y))
                    self.modified = True
            elif self.state == STATE.DRAW_ELLIPSE:
                if self.ellipse_points is None or len(
                        self.ellipse_points['points']
                ) < 3 or self.ellipse_points['info'] is None:
                    return
                pos = ev.pos()
                valid, relative_pos = self.pos_in_img_area(pos)
                if valid:
                    click_pos = (int(relative_pos[0] / self.scale),
                                 int(relative_pos[1] / self.scale))
                    self.logger.debug(click_pos)
                    center, r, theta = self.ellipse_points['info']
                    theta = int(np.around(theta))
                    p = cv.ellipse2Poly(center, r, theta, 0, 360, 1)
                    num_p = p.shape[0]
                    p = p.reshape((1, num_p, 2))
                    min_x, max_x = np.min(p[0, :, 0]), np.max(p[0, :, 0])
                    min_y, max_y = np.min(p[0, :, 1]), np.max(p[0, :, 1])
                    p[0, :, 0] -= min_x
                    p[0, :, 1] -= min_y
                    mask = np.zeros((max_y - min_y + 1, max_x - min_x + 1),
                                    np.uint8)
                    mask = cv.fillPoly(mask, p, 1)
                    pixel_value = self.origin_img[click_pos[1], click_pos[0],
                                                  0]
                    low, high = pixel_value + \
                        self.pixel_range[0], pixel_value + self.pixel_range[1]
                    selected_img = self.origin_img[min_y:max_y + 1,
                                                   min_x:max_x + 1, 0]
                    x, y = np.where(
                        (selected_img >= low) * (selected_img <= high) * mask)
                    x = x + min_y
                    y = y + min_x
                    self.labelimg[x, y] = 1
                    pic = self.draw_points()
                    self.show_pic(file_name=None, content=pic)
                    self.histroty.append((x, y))
                    self.modified = True
                    self.saved = False

    def zoom_in_pic(self, checked):
        self.zoom_pic(True)

    def zoom_out_pic(self, checked):
        self.zoom_pic(False)

    def zoom_pic(self, zoom_in):
        if self.cur_img is None:
            return
        if zoom_in:
            if self.scale >= 5:
                pass
            elif self.scale < 1:
                self.scale += 0.1
            else:
                self.scale += 1
        else:
            if self.scale == 0:
                pass
            elif self.scale <= 1:
                self.scale -= 0.1
            else:
                self.scale -= 1
        self.logger.debug(self.scale)
        height, width, _ = self.origin_img.shape
        self.cur_img = cv.resize(
            self.origin_img,
            (int(height * self.scale), int(width * self.scale)),
            cv.INTER_LINEAR)
        if self.state == STATE.DRAW_RECTANGLE:
            if self.start_point is not None and self.end_point is not None:
                self.draw_rect(self.start_point, self.end_point)
                if self.labelimg is not None:
                    pic = self.draw_points()
                    self.show_pic(content=pic)
                else:
                    self.show_pic(file_name=None, content=self.panel_pic)
        elif self.state == STATE.DRAW_POLYGON:
            if self.polygon_points is not None and self.polygon_points[
                    'finish'] is True:
                self.draw_lines(self.polygon_points['points'], True)
                if self.labelimg is not None:
                    pic = self.draw_points()
                    self.show_pic(content=pic)
                else:
                    self.show_pic(file_name=None, content=self.panel_pic)
        elif self.state == STATE.DRAW_ELLIPSE:
            if self.ellipse_points is not None and len(
                    self.ellipse_points['points']) == 3:
                self.draw_ellipse(self.ellipse_points['points'])
                if self.labelimg is not None:
                    pic = self.draw_points()
                    self.show_pic(content=pic)
                else:
                    self.show_pic(file_name=None, content=self.panel_pic)
        elif self.labelimg is not None:
            self.panel_pic = self.cur_img.copy()
            pic = self.draw_points()
            self.show_pic(file_name=None, content=pic)
        else:
            self.show_pic(file_name=None)

    def file_list_item_changed(self, item):
        if self.modified and not self.saved:
            res = QMessageBox.warning(
                self, 'warning', 'Changes not saved, do you want to save?',
                QMessageBox.Ok | QMessageBox.No, QMessageBox.Ok)
            if res == QMessageBox.Ok:
                self.save()
        base_pic_name = item.text()
        for index, filename in enumerate(self.opened_files):
            if filename.name == base_pic_name:
                selected_filename = filename
                break
        self.selected_filename = selected_filename
        self.refresh_vars()
        self.open(self.selected_filename)

    def add_tool_bar(self):
        self.toolbar = QToolBar()
        self.addToolBar(Qt.TopToolBarArea, self.toolbar)
        self.toolbar.addAction(self.ui.actionOpen_File)
        self.toolbar.addAction(self.ui.actionOpen_Dir)
        self.toolbar.addAction(self.ui.actionSave)
        self.toolbar.addAction(self.ui.actionZoom_In)
        self.toolbar.addAction(self.ui.actionZoom_Out)
        self.toolbar.addAction(self.ui.actionfill_color)
        self.toolbar.addAction(self.ui.actionSet_Pixel_Range)
        self.toolbar.addAction(self.ui.actionRectangle)
        self.toolbar.addAction(self.ui.actionEllipse)
        self.toolbar.addAction(self.ui.actionPolygon)
        self.toolbar.addAction(self.ui.actionUndo)

    def show_pic(self, file_name=None, content=None):
        if file_name is not None:
            file_name = str(file_name.absolute())
            img = cv.imdecode(np.fromfile(file_name, dtype=np.uint8), -1)
            assert img is not None
            if len(img.shape) == 2:
                img = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
            height, width, channel = img.shape
            self.cur_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
            self.origin_img = self.cur_img
            self.labelimg = np.zeros(self.origin_img.shape[:2], dtype=np.int)
            qimg = QImage(self.cur_img.data, width, height, width * channel,
                          QImage.Format_RGB888)
            self.ui.img_area.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
            self.ui.img_area.setPixmap(QPixmap.fromImage(qimg))
            self.ui.img_area.adjustSize()
        elif content is not None:
            height, width, channel = content.shape
            qimg = QImage(content.data, width, height, width * channel,
                          QImage.Format_RGB888)
            self.ui.img_area.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
            self.ui.img_area.setPixmap(QPixmap.fromImage(qimg))
            self.ui.img_area.adjustSize()
        else:
            height, width, channel = self.cur_img.shape
            qimg = QImage(self.cur_img.data, width, height, width * channel,
                          QImage.Format_RGB888)
            self.ui.img_area.setAlignment(Qt.AlignCenter | Qt.AlignHCenter)
            self.ui.img_area.setPixmap(QPixmap.fromImage(qimg))
            self.ui.img_area.adjustSize()

    def open_file(self, checked):
        if self.modified and not self.saved:
            res = QMessageBox.warning(
                self, 'warning', 'Changes not saved, do you want to save?',
                QMessageBox.Ok | QMessageBox.No, QMessageBox.Ok)
            if res == QMessageBox.Ok:
                self.save()
        filename, filetype = QFileDialog.getOpenFileName(
            self, '选取文件', '.', 'PNG Files(*.png);;JPG Files(*.jpg)')
        if filename == '':
            return
        filename = Path(filename)
        self.open_mode = OPEN_MODE.OPEN_FILE
        self.opened_files = [filename]
        self.selected_filename = filename
        self.open(self.selected_filename)
        self.refresh_list()

    def open_dir(self, checked):
        if self.modified and not self.saved:
            res = QMessageBox.warning(
                self, 'warning', 'Changes not saved, do you want to save?',
                QMessageBox.Ok | QMessageBox.No, QMessageBox.Ok)
            if res == QMessageBox.Ok:
                self.save()
        opened_dir = QFileDialog.getExistingDirectory(self, '打开文件夹', '.')
        if opened_dir == '':
            return
        opened_dir = Path(opened_dir)
        self.open_mode = OPEN_MODE.OPEN_DIR
        self.opened_files = list(opened_dir.iterdir())
        self.opened_files = [
            item for item in self.opened_files if util.is_pic(item)
        ]
        if len(self.opened_files) == 0:
            QMessageBox.warning(self, 'warning', 'No image found')
        else:
            self.selected_filename = self.opened_files[0]
            self.open(self.selected_filename)
            self.refresh_list()

    def refresh_list(self):
        self.ui.file_list.clear()
        for file_name in self.opened_files:
            base_name = file_name.name
            self.ui.file_list.addItem(base_name)

    def open(self, filename: Path):
        self.setWindowTitle(filename.name)
        self.show_pic(file_name=filename)
        temp = str(filename).split('.')
        npy_filename = '.'.join(temp[:-1]) + '.npy'
        if os.path.exists(npy_filename):
            self.labelimg = np.load(npy_filename)
            self.panel_pic = self.cur_img.copy()
            pic = self.draw_points()
            self.show_pic(file_name=None, content=pic)
class TimelineDelta(object):
	"""
	
	"""

	def __init__(self, begin, end=30, title=None, height=30, top=0, parent=None):
		"""
		
		:param begin: 
		:param end: 
		:param title: 
		:param height: 
		:param top: 
		:param parent: 
		"""
		self._top = top
		self._height = height
		self._parent = parent
		self._title = title
		self._lock = False
		self._begin = begin
		self._end = end

		self.checkNumberOfTracks()

		self._defautcolor = parent._tracks[self.track].color

	##########################################################################
	#### HELPERS/FUNCTIONS ###################################################
	##########################################################################

	def checkNumberOfTracks(self):
		"""
		
		:return: 
		"""
		if self.track >= (self._parent.numberoftracks - 1):
			for i in range(self._parent.numberoftracks - 1, self.track + 1):
				self._parent.addTrack()

	def collide(self, x, y):
		"""
		
		:param x: 
		:param y: 
		:return: 
		"""
		return self.begin <= x <= self.end and self._top <= y <= (self._top + self._height)

	def in_range(self, start, end):
		"""
		:param start: 
		:param end: 
		:return: 
		"""
		return start <= self.begin and end >= self.end or \
			   self.begin <= start <= self.end or \
			   self.begin <= end <= self.end

	def canSlideBegin(self, x, y):
		"""
		
		:param x: 
		:param y: 
		:return: 
		"""
		return not self._lock and x == int(round(self.begin)) and self._top <= y <= (self._top + self._height)

	def canSlideEnd(self, x, y):
		"""
		
		:param x: 
		:param y: 
		:return: 
		"""
		return not self._lock and int(round(self.end)) == x and self._top <= y <= (self._top + self._height)

	def moveEnd(self, x):
		"""
		Move the right edge of the event rectangle.
		:param x: 
		"""

		# Do nothing if locked
		if self._lock:
			return

		# Do nothing if trying to go over the pther edge
		if self._end <= self._begin - x and x < 0:
			return

		# Increment accordingly
		self._end += x / self._parent._scale

		# Minimum begin position is at 0
		if self._end > (self._parent.width() / self._parent._scale):
			self._end = (self._parent.width() / self._parent._scale)

	def moveBegin(self, x):
		"""
		Move the left edge of the event rectangle.
		:param x: 
		"""

		# Do nothing if locked
		if self._lock:
			return

		# Do nothing if trying to go over the other edge
		if self._begin >= self._end - x and x > 0:
			return

		# Increment accordingly
		self._begin += x / self._parent._scale

		# Minimum begin position is at 0
		if self._begin < 0:
			self._begin = 0

	def move(self, x, y):
		"""
		
		:param x: 
		:param y: 
		:return: 
		"""
		if self._lock: return

		if (self.begin + x) >= 0 and (self.end + x) <= self._parent.width():
			self._begin += x / self._parent._scale
			self._end += x / self._parent._scale
		current_track = self.track
		new_track = Track.whichTrack(y)

		if current_track != new_track and new_track >= 0 and new_track <= self._parent.numberoftracks:
			self.track = new_track
			self.checkNumberOfTracks()

	def showEditWindow(self):
		"""
		
		:return: 
		"""
		text, ok = QInputDialog.getText(
			self._parent, 'Edit event', 'Comment:', text=self._title)
		if ok:
			self._title = str(text)
			self._parent.repaint()

	def draw(self, painter, showvalues=False):
		"""
		
		:param painter: 
		:param showvalues: 
		:return: 
		"""
		start, end = self.begin, self.end
		if self._lock:
			transparency = 0.1
		else:
			transparency = 0.5
		painter.setPen(QColor(0, 0, 0))
		painter.setOpacity(transparency)
		painter.drawRoundedRect(
			start, self._top, end - start, self._height, 3, 3)
		painter.setOpacity(1.0)

		painter.drawText(start + 3, self._top + 19, self._title)
		if showvalues:
			painter.drawText(
				start, self._top + 44, "[%d;%d] delta:%d" % (self._begin, self._end, self._end - self._begin))

	def remove(self):
		"""
		
		:return: 
		"""
		try:
			self._parent._tracks[self.track].periods.remove(self)
		except:
			pass

	##########################################################################
	#### PROPERTIES ##########################################################
	##########################################################################

	@property
	def title(self):
		return self._title

	@property
	def lock(self):
		return self._lock

	@lock.setter
	def lock(self, value):
		self._lock = value

	@property
	def begin(self):
		return self._begin * self._parent._scale

	@begin.setter
	def begin(self, value):
		if self._lock: return
		self._begin = value / self._parent._scale
		if self._begin < 0: self._begin = 0

	@property
	def end(self):
		return self._end * self._parent._scale

	@end.setter
	def end(self, value):
		if self._lock: return
		self._end = value / self._parent._scale
		if self._end > (self._parent.width() / self._parent._scale):
			self._end = (self._parent.width() / self._parent._scale)

	@property
	def track(self):
		return Track.whichTrack(self._top)

	@track.setter
	def track(self, value):
		# if the object exists in other track remove it
		if self.track < len(self._parent._tracks) and self in self._parent._tracks[self.track].periods: self.remove()

		# Verify if the new track exists. In case not create it
		self._top = Track.whichTop(value)
		if self.track >= len(self._parent._tracks): self._parent.addTrack()

		# if do not exists in the track add it
		if self not in self._parent._tracks[self.track].periods: self._parent._tracks[self.track].periods.append(self)

	@property
	def color(self):
		return self._defautcolor

	@color.setter
	def color(self, value):
		self._defautcolor = QColor(value) if (type(value) == str) else value

	@property
	def bgrcolor(self):
		return self._defautcolor.blue(), self._defautcolor.green(), self._defautcolor.red()

	@property
	def properties(self):
		return ['P',
		        self._lock,
		        int(round(self._begin)),
		        int(round(self._end)),
		        self._title,
		        self._defautcolor.name(),
		        self.track]

	@properties.setter
	def properties(self, value):
		self._lock = value[1] == 'True'
		self._begin = int(value[2])
		self._end = int(value[3])
		self._title = value[4]
		self._defautcolor = QColor(value[5])
		self.track = int(value[6])

		self.checkNumberOfTracks()
def to_css_format(color: QColor, alpha=255):
    return "rgba({r}, {g}, {b}, {a})".format(r=color.red(),
                                             g=color.green(),
                                             b=color.blue(),
                                             a=alpha)
Example #22
0
 def QtColorToSting(clr: QtGui.QColor):
     return "rgb({0}, {1}, {2})".format(clr.red(), clr.green(), clr.blue())
Example #23
0
def onchange_text():
    color = QColor(qrand() % 256, qrand() % 256, qrand() % 256)
    w.setStyleSheet('background: rgb({}, {}, {});'.format(color.red(), color.green(), color.blue()))
Example #24
0
    def updateGUI(self):
        defined_img = None
        if self.file_path is not None:
            defined_img = QImage(self.file_path).scaled(
                self.IMAGE_COLS_MAX, self.IMAGE_ROWS_MAX)

        img = self.camera.getOrigImage()
        if defined_img is not None:
            img = defined_img
            self.image = img
        elif defined_img is None:
            if img is not None:
                self.image = QImage(img.data, img.shape[1], img.shape[0],
                                    img.shape[1] * img.shape[2],
                                    QImage.Format_RGB888).scaled(
                                        self.IMAGE_COLS_MAX,
                                        self.IMAGE_ROWS_MAX)

        if img is not None:

            self.sourceImg.setPixmap(QPixmap.fromImage(self.image))

        #Filter Image

        filt = self.getFilterName()

        if (filt is not "Orig"):
            disc2 = self.camera.getFilter(filt).apply(self.colorSpace)
            imgDisc = QImage(disc2.data, disc2.shape[1], disc2.shape[0],
                             disc2.shape[1] * disc2.shape[2],
                             QImage.Format_RGB888).scaled(200, 200)
            self.colorSpaceLabel.setPixmap(QPixmap.fromImage(imgDisc))

        img = self.camera.getOrigImage()
        if defined_img is not None:
            img2 = cv2.imread(self.file_path)
            img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
            if (filt is not "Orig"):
                self.imageF = self.camera.getFilter(filt).apply(img2)
                self.imageF = QImage(
                    self.imageF.data, self.imageF.shape[1],
                    self.imageF.shape[0],
                    self.imageF.shape[1] * self.imageF.shape[2],
                    QImage.Format_RGB888).scaled(self.IMAGE_COLS_MAX,
                                                 self.IMAGE_ROWS_MAX)
            else:
                self.imageF = QImage(img2.data, img2.shape[1], img2.shape[0],
                                     img2.shape[1] * img2.shape[2],
                                     QImage.Format_RGB888).scaled(
                                         self.IMAGE_COLS_MAX,
                                         self.IMAGE_ROWS_MAX)

        elif defined_img is None:
            if img is not None:
                img = self.camera.getFilteredImage(filt)
                self.imageF = QImage(img.data, img.shape[1], img.shape[0],
                                     img.shape[1] * img.shape[2],
                                     QImage.Format_RGB888).scaled(
                                         self.IMAGE_COLS_MAX,
                                         self.IMAGE_ROWS_MAX)

        #img = self.camera.getFilteredImage(filt)

        self.filterImg.setPixmap(QPixmap.fromImage(self.imageF))

        #print "update"
        pos = self.sourceImg.getMousePos()
        if pos != None:
            #print pos
            x_ini = (self.sourceImg.width() * self.ZOOM_X *
                     pos.x()) / self.sourceImg.width()
            y_ini = (self.sourceImg.height() * self.ZOOM_X *
                     pos.y()) / self.sourceImg.height()
            rect = QRect(x_ini - 100, y_ini - 100, 200, 200)

            #print 'orig', pos.x(), ",", pos.y(), ",", self.sourceImg.size()
            #print 'scale', x_ini, ",", y_ini

            #self.crop.setPixmap(QPixmap.fromImage(self.image.copy(rect).scaled(1000,1000)))

            #print self.sourceImg.pixmap().size()
            im2 = self.image.copy().scaled(
                self.sourceImg.width() * self.ZOOM_X,
                self.sourceImg.height() * self.ZOOM_X)
            self.crop.setPixmap(QPixmap.fromImage(im2.copy(rect)))
            #print self.crop.pixmap().size()

            pos = self.sourceImg.getMousePos()
            #print pos
            rgb = QColor(self.image.pixel(pos))
            self.tootippixel.setStyleSheet("background: rgb(" +
                                           str(rgb.red()) + "," +
                                           str(rgb.green()) + "," +
                                           str(rgb.blue()) +
                                           "); border: 1px solid;")
            self.tootippixel.setGeometry(pos.x(), pos.y() + 52, 20, 20)
            self.pixel.setStyleSheet("background: rgb(" + str(rgb.red()) +
                                     "," + str(rgb.green()) + "," +
                                     str(rgb.blue()) + ");border: 1px solid;")
            text = "XY [" + str(pos.x()) + "," + str(
                pos.y()) + "]\nrgb(" + str(rgb.red()) + "," + str(
                    rgb.green()) + "," + str(rgb.blue()) + ")"
            self.rgbVal.setText(text)
Example #25
0
 def _setColor(self, color: QColor):
     self.color = color
     self.setStyleSheet("background-color: rgb({},{},{});".format(
         color.red(), color.green(), color.blue()))
Example #26
0
class ColorItem(QGraphicsItem):
    n = 0

    def __init__(self):
        super(ColorItem, self).__init__()

        self.color = QColor(qrand() % 256, qrand() % 256, qrand() % 256)

        self.setToolTip(
            "QColor(%d, %d, %d)\nClick and drag this color onto the robot!" %
            (self.color.red(), self.color.green(), self.color.blue()))
        self.setCursor(Qt.OpenHandCursor)

    def boundingRect(self):
        return QRectF(-15.5, -15.5, 34, 34)

    def paint(self, painter, option, widget):
        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.darkGray)
        painter.drawEllipse(-12, -12, 30, 30)
        painter.setPen(QPen(Qt.black, 1))
        painter.setBrush(QBrush(self.color))
        painter.drawEllipse(-15, -15, 30, 30)

    def mousePressEvent(self, event):
        if event.button() != Qt.LeftButton:
            event.ignore()
            return

        self.setCursor(Qt.ClosedHandCursor)

    def mouseMoveEvent(self, event):
        if QLineF(QPointF(event.screenPos()),
                  QPointF(event.buttonDownScreenPos(Qt.LeftButton))).length(
                  ) < QApplication.startDragDistance():
            return

        drag = QDrag(event.widget())
        mime = QMimeData()
        drag.setMimeData(mime)

        ColorItem.n += 1
        if ColorItem.n > 2 and qrand() % 3 == 0:
            image = QImage(':/images/head.png')
            mime.setImageData(image)
            drag.setPixmap(QPixmap.fromImage(image).scaled(30, 40))
            drag.setHotSpot(QPoint(15, 30))
        else:
            mime.setColorData(self.color)
            mime.setText(
                "#%02x%02x%02x" %
                (self.color.red(), self.color.green(), self.color.blue()))

            pixmap = QPixmap(34, 34)
            pixmap.fill(Qt.white)

            painter = QPainter(pixmap)
            painter.translate(15, 15)
            painter.setRenderHint(QPainter.Antialiasing)
            self.paint(painter, None, None)
            painter.end()

            pixmap.setMask(pixmap.createHeuristicMask())

            drag.setPixmap(pixmap)
            drag.setHotSpot(QPoint(15, 20))

        drag.exec_()
        self.setCursor(Qt.OpenHandCursor)

    def mouseReleaseEvent(self, event):
        self.setCursor(Qt.OpenHandCursor)
Example #27
0
def qcolor_to_qsscolor(c: QColor) -> str:
    """Convert a QColor to a string that can be used in a QStyleSheet."""
    ensure_valid(c)
    return "rgba({}, {}, {}, {})".format(c.red(), c.green(), c.blue(),
                                         c.alpha())
class CircleBarGraphWidget(QLabel):
    def __init__(self,
                 parentWidget: QWidget = None,
                 title="Title",
                 minValue=0,
                 maxValue=100,
                 size=200,
                 barColor=None):
        super().__init__(parentWidget)
        self.size = size
        self.value = 0
        self.title = title

        self.minValue = minValue
        self.maxValue = maxValue

        if barColor is not None:
            [red, green, blue] = [
                int(float(i))
                for i in barColor.split("(")[1].split(")")[0].split(",")
            ]
            self.barColor = QColor(red, green, blue)
        else:
            self.barColor = QColor(50, 50, 255)

        self.textColor = QColor(255, 255, 255)

        self.setAlignment(Qt.AlignCenter)

    def setSize(self, size):
        # TODO: Use the QWidget size functions instead of this sketchy one
        self.size = size

        self.setGeometry(0, 0, size, size)
        self.setMinimumWidth(size)
        self.setMinimumHeight(size)

    def paintEvent(self, e):
        painter = QPainter(self)  # Grey background

        fontSize = int(self.width() * 0.1)
        padding = 4
        painter.setPen(QPen(self.textColor, 1, Qt.SolidLine))
        painter.setFont(QFont("Monospace", fontSize))
        fontHeight = int(fontSize * 1.5)

        valueText = str(self.value)[0:6]
        painter.drawText(QRect(0, 0, self.width(),
                               self.height() * 0.9), Qt.AlignCenter, valueText)

        painter.setFont(QFont("Monospace", fontSize / 2))
        painter.drawText(
            QRect(0, (self.height() * 0.9 / 2) + fontHeight / 2 + padding,
                  self.width(), fontHeight / 2), Qt.AlignCenter, self.title)

        theta = clamp(
            interpolate(self.value, self.minValue, self.maxValue, 0, 360 * 16),
            0, 360 * 16)
        barPadding = 20

        painter.setPen(QPen(self.barColor, 30, Qt.SolidLine))
        painter.translate(0, self.height())
        painter.rotate(-90)

        painter.drawArc(barPadding, barPadding,
                        self.width() - 2 * barPadding,
                        self.height() - 2 * barPadding, 0, -theta)

    def setValue(self, value):
        self.value = value

    def setTextColor(self, textColor: str):
        if "rgb" in textColor:
            [red, green, blue] = [
                int(float(i))
                for i in textColor.split("(")[1].split(")")[0].split(",")
            ]
            self.textColor = QColor(red, green, blue)
        else:
            self.textColor = QColor(textColor)

    @staticmethod
    def getType():
        return "CircleBarGraph"

    def getLimits(self):
        return [self.minValue, self.maxValue]

    def getMin(self):
        return str(self.minValue)

    def getMax(self):
        return str(self.maxValue)

    def getColor(self):
        colorString = "rgb({0},{1},{2})".format(self.barColor.red(),
                                                self.barColor.green(),
                                                self.barColor.blue())
        return colorString
Example #29
0
class MainWindow(QMainWindow, Ui_MainWindow):
    '''
    Main ui
    '''
    def __init__(self, *args, obj=None, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setupUi(self)
        self.cwd = getcwd()
                        
        self.raw.fig.canvas.mpl_connect('button_press_event', self.readFile)
        self.apply_1.clicked.connect(self.converting_planes)
        self.apply_2.clicked.connect(self.pseudo)
        self.apply_3.clicked.connect(self.kmeans_planes)
        self.color_widget_1.mouseReleaseEvent = self.color1
        self.color_widget_2.mouseReleaseEvent = self.color2
        self.color_1 = QColor(255, 255, 255)
        self.color_2 = QColor(0, 0, 0)

    def readFile(self, e):
        '''
        Read a picture
        '''
        imgChoose, _ = QFileDialog.getOpenFileName(self,  
                                    "Open image",  
                                    self.cwd,  
                                    "Image Files (*.png *.jpg *.jpeg *.bmp)") 

        if imgChoose == "":
            return

        self.raw_img = imread(imgChoose)
        self.b,self.g,self.r = split(self.raw_img)
        self.raw_img = merge([self.r, self.g, self.b])
        # self.gray_img = sum(self.raw_img, axis=2) / 3.0
        self.processed_img = self.raw_img.copy()
        self.raw.axes.cla()
        self.raw.axes.imshow(self.raw_img)
        self.raw.axes.set_axis_off()
        self.raw.draw()
        # self.filtered_img = zeros(shape=self.raw_img.shape)

    def saveImage(self, e):
        '''
        Save an image
        '''
        imageName, _ = QFileDialog.getSaveFileName(self,  
                                    "Save Image As",  
                                    "",
                                    "Image Files (*.png *.jpg)")  

        if imageName == "":
            return

        if imageName:
            e.canvas.figure.savefig(imageName)
    
    def draw_on(self, p, img, cmap = None, vmin = None, vmax = None):
        p.axes.cla()
        p.axes.imshow(img, cmap = cmap, vmin = vmin, vmax = vmax)
        p.axes.set_axis_off()
        p.draw()

    def color1(self, e):
        self.color_1 = QColorDialog.getColor()
        r, g, b = str(self.color_1.red()), str(self.color_1.green()), str(self.color_1.blue())
        self.color_widget_1.setStyleSheet(f"background-color: rgb({r}, {g}, {b});")

    def color2(self, e):
        self.color_2 = QColorDialog.getColor()
        r, g, b = str(self.color_2.red()), str(self.color_2.green()), str(self.color_2.blue())
        self.color_widget_2.setStyleSheet(f"background-color: rgb({r}, {g}, {b});")
    
    def reset(self):

        self.filtered_img = zeros(shape = self.raw_img.shape)
        self.filter.axes.cla()
        self.filter.axes.imshow(self.filtered_img, cmap='gray', vmin=0, vmax=255)
        self.filter.axes.set_axis_off()
        self.filter.draw()
    
    def pseudo(self):
        btnId = self.pseudo_group.checkedId()  #-2 ~ -7
        
        if btnId == -2:
            im_gray = self.processed_img
            im_color = cv.applyColorMap(im_gray, cv.COLORMAP_AUTUMN)
            r, g, b = im_gray[:,:, 0], im_gray[:,:, 1], im_gray[:,:, 2]

            self.draw_on(self.pseudo1, r, 'gray')
            self.draw_on(self.pseudo2, g, 'gray')
            self.draw_on(self.pseudo3, b, 'gray')
            self.draw_on(self.mixed_pseudo, im_color)

        elif btnId == -3:
            im_gray = self.processed_img
            im_color = cv.applyColorMap(im_gray, cv.COLORMAP_JET)
            r, g, b = im_gray[:,:, 0], im_gray[:,:, 1], im_gray[:,:, 2]
            
            self.draw_on(self.pseudo1, r, 'gray')
            self.draw_on(self.pseudo2, g, 'gray')
            self.draw_on(self.pseudo3, b, 'gray')
            self.draw_on(self.mixed_pseudo, im_color)

        elif btnId == -4:
            im_gray = self.processed_img
            im_color = cv.applyColorMap(im_gray, cv.COLORMAP_RAINBOW)
            r, g, b = im_gray[:,:, 0], im_gray[:,:, 1], im_gray[:,:, 2]
            
            self.draw_on(self.pseudo1, r, 'gray')
            self.draw_on(self.pseudo2, g, 'gray')
            self.draw_on(self.pseudo3, b, 'gray')
            self.draw_on(self.mixed_pseudo, im_color)

        elif btnId == -5:
            gray = 0.299 * self.r + 0.587 * self.g + 0.114 * self.b
            level = self.c_level.value() - 1

            r1, g1, b1 = self.color_1.red(), self.color_1.green(), self.color_1.blue()
            r2, g2, b2 = self.color_2.red(), self.color_2.green(), self.color_2.blue()

            r_step = (r2 - r1) / level
            g_step = (g2 - g1) / level
            b_step = (b2 - b1) / level

            new_r = zeros(self.r.shape)
            new_g = zeros(self.r.shape)
            new_b = zeros(self.r.shape)

            for x in range(self.r.shape[0]):
                for y in range(self.r.shape[1]):

                    new_r[x][y] = around(r1 + np.round(gray[x][y] * level / 255) * r_step)
                    new_g[x][y] = around(g1 + np.round(gray[x][y] * level / 255) * g_step)
                    new_b[x][y] = around(b1 + np.round(gray[x][y] * level / 255) * b_step)
            
            new_r, new_g, new_b = new_r.astype(np.int), new_g.astype(np.int), new_b.astype(np.int)
            mix = dstack([new_r, new_g, new_b])
            mix[mix > 255] = 255
            
            self.draw_on(self.pseudo1, self.r, 'gray')
            self.draw_on(self.pseudo2, self.g, 'gray')
            self.draw_on(self.pseudo3, self.b, 'gray')
            self.draw_on(self.mixed_pseudo, mix)
        
    def converting_planes(self):
        btnId = self.plane_btns.checkedId()  #-2 ~ -7
        
        if btnId == -2:
            self.rgb(self.plane1, self.plane2, self.plane3, self.mixed_plane)
        elif btnId == -3:
            self.cmy(self.plane1, self.plane2, self.plane3, self.mixed_plane)
        elif btnId == -4:
            self.hsi(self.plane1, self.plane2, self.plane3, self.mixed_plane)
        elif btnId == -5:
            self.xyz(self.plane1, self.plane2, self.plane3, self.mixed_plane)
        elif btnId == -6:
            self.lab(self.plane1, self.plane2, self.plane3, self.mixed_plane)
        elif btnId == -7:
            self.yuv(self.plane1, self.plane2, self.plane3, self.mixed_plane)
        
    def kmeans_planes(self):
        btnId = self.btns_2.checkedId()

        if btnId == -2:
            self.kmeans(self.rgb(self.kplane1, self.kplane2, self.kplane3, self.kmeans_processed), self.k_level.value())
        elif btnId == -3:
            self.kmeans(self.cmy(self.kplane1, self.kplane2, self.kplane3, self.kmeans_processed), self.k_level.value() )
        elif btnId == -4:
            self.kmeans(self.hsi(self.kplane1, self.kplane2, self.kplane3, self.kmeans_processed), self.k_level.value())
        elif btnId == -5:
            self.kmeans(self.xyz(self.kplane1, self.kplane2, self.kplane3, self.kmeans_processed), self.k_level.value())
        elif btnId == -6:
            self.kmeans(self.lab(self.kplane1, self.kplane2, self.kplane3, self.kmeans_processed), self.k_level.value())
        elif btnId == -7:
            self.kmeans(self.yuv(self.kplane1, self.kplane2, self.kplane3, self.kmeans_processed), self.k_level.value())

    def rgb(self, p1, p2, p3, p4):
        self.draw_on(p1, self.r, 'gray', 0, 255)
        self.draw_on(p2, self.g, 'gray', 0, 255)
        self.draw_on(p3, self.b, 'gray', 0, 255)
        mix = dstack([self.r, self.g, self.b])
        self.draw_on(p4, mix, None, 0, 255)

        return mix
    
    def cmy(self, p1, p2, p3, p4):
        self.draw_on(p1, 255-self.r, 'gray', 0, 255)
        self.draw_on(p2, 255-self.g, 'gray', 0, 255)
        self.draw_on(p3, 255-self.b, 'gray', 0, 255)
        mix = dstack([255-self.r, 255-self.g, 255-self.b])
        self.draw_on(p4, mix, None, 0, 255)

        return mix
    
    def hsi(self, p1, p2, p3, p4):
        r, g, b = self.r / 255, self.g / 255, self.b / 255
        h, s, i = zeros(r.shape), zeros(r.shape), zeros(r.shape)

        for x in range(r.shape[0]):
            for y in range(r.shape[1]):
                min_ = min(r[x][y], g[x][y], b[x][y])
                
                s[x][y] = 1 - (3 / (r[x][y] + g[x][y] + b[x][y])) * min_
                i[x][y] = (r[x][y] + g[x][y] + b[x][y]) / 3

                up = ((r[x][y] - g[x][y]) + (r[x][y] - b[x][y])) * .5
                down = ((r[x][y] - g[x][y])** 2 + (r[x][y] - b[x][y]) * (g[x][y] - b[x][y]))** .5
                degree = arccos(up / down)
                
                if b[x][y] > g[x][y]:
                    h[x][y] = 360 - np.degrees(degree)
                else:
                    h[x][y] = np.degrees(degree)
        
        h = h * 255 / 360
        h[np.isnan(h)] = 0

        s = s * 255
        s[np.isnan(s)] = 0

        i = i * 255
        i[np.isnan(i)] = 0

        h, s, i = h.astype(np.int), s.astype(np.int), i.astype(np.int)

        self.draw_on(p1, h, 'gray')
        self.draw_on(p2, s, 'gray')
        self.draw_on(p3, i, 'gray')
        mix = dstack([h, s, i])
        self.draw_on(p4, mix)
        
        return mix
    
    def xyz(self, p1, p2, p3, p4):
        x_, y_, z = zeros(self.r.shape), zeros(self.r.shape), zeros(self.r.shape)
        
        for x in range(self.r.shape[0]):
            for y in range(self.r.shape[1]):
                x_[x][y] = 0.412453 * self.r[x][y] + 0.35758 * self.g[x][y] + 0.180423 * self.b[x][y]
                y_[x][y] = 0.212671 * self.r[x][y] + 0.71516 * self.g[x][y] + 0.072169 * self.b[x][y]
                z[x][y] = 0.019334 * self.r[x][y] + 0.119193 * self.g[x][y] + 0.950227 * self.b[x][y]

        x_, y_, z = x_.astype(np.int), y_.astype(np.int), z.astype(np.int)
        self.draw_on(p1, x_, 'gray')
        self.draw_on(p2, y_, 'gray')
        self.draw_on(p3, z, 'gray')
        mix = dstack([x_, y_, z])
        mix[mix > 255] = 255
        self.draw_on(p4, mix)

        return mix
    
    def lab(self, p1, p2, p3, p4):
        x_, y_, z = zeros(self.r.shape), zeros(self.r.shape), zeros(self.r.shape)
        
        for x in range(self.r.shape[0]):
            for y in range(self.r.shape[1]):
                x_[x][y] = 0.412453 * self.r[x][y] + 0.35758 * self.g[x][y] + 0.180423 * self.b[x][y]
                y_[x][y] = 0.212671 * self.r[x][y] + 0.71516 * self.g[x][y] + 0.072169 * self.b[x][y]
                z[x][y] = 0.019334 * self.r[x][y] + 0.119193 * self.g[x][y] + 0.950227 * self.b[x][y]

        x_, y_, z = x_ / 255, y_ / 255, z / 255
        
        xn = 0.950456
        yn = 1.0
        zn = 1.088754
        l, a, b = zeros(self.r.shape), zeros(self.r.shape), zeros(self.r.shape)

        for x in range(self.r.shape[0]):
            for y in range(self.r.shape[1]):
                if y_[x][y] / yn > .008856:
                    l[x][y] = 116 * (y_[x][y]/yn)**(1/3) - 16
                else:
                    903.3 * y_[x][y]/yn
                a[x][y] = 500 * (dum(x_[x][y], xn) - dum(y_[x][y], yn))
                b[x][y] = 200 * (dum(y_[x][y], yn) - dum(z[x][y], zn))
        
        l = l * 255
        a = a * 255
        b = b * 255

        l, a, b = l.astype(np.int), a.astype(np.int), b.astype(np.int)
        mix = dstack([l, a, b])
        mix[mix > 255] = 255

        self.draw_on(p1, l, 'gray')
        self.draw_on(p2, a, 'gray')
        self.draw_on(p3, b, 'gray')
        self.draw_on(p4, mix)

        return mix

    def yuv(self, p1, p2, p3, p4):
        y_, u, v = zeros(self.r.shape), zeros(self.r.shape), zeros(self.r.shape)
        
        for x in range(self.r.shape[0]):
            for y in range(self.r.shape[1]):

                y_[x][y] = 0.299 * self.r[x][y] + 0.587 * self.g[x][y] + 0.114 * self.b[x][y]
                u[x][y] = -0.169 * self.r[x][y] + -0.331 * self.g[x][y] + 0.5 * self.b[x][y] + 128
                v[x][y] = 0.5 * self.r[x][y] + -0.419 * self.g[x][y] + 0.081 * self.b[x][y] + 128
        
        y_, u, v = y_.astype(np.int), u.astype(np.int), v.astype(np.int)
        mix = dstack([y_, u, v])
        mix[mix > 255] = 255

        self.draw_on(p1, y_, 'gray')
        self.draw_on(p2, u, 'gray')
        self.draw_on(p3, v, 'gray')
        self.draw_on(p4, mix)

        return mix

    def kmeans(self, img, k):
        Z = img.reshape((-1, 3))
        Z = float32(Z)
        criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)

        ret, label, center = cv.kmeans(Z, k, None, criteria, 10, cv.KMEANS_RANDOM_CENTERS)

        center = uint8(center)
        res = center[label.flatten()]
        res2 = res.reshape((img.shape))
        
        self.mixed_kplane.axes.cla()
        self.mixed_kplane.axes.imshow(res2)
        self.mixed_kplane.axes.set_axis_off()
        self.mixed_kplane.draw()
Example #30
0
    def paintEvent(self, event):
        super(WaterFloatButton, self).paintEvent(event)

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)

        # 鼠标悬浮进度
        edge_color = QColor(self.hover_bg)
        pro = 0
        if self.hover_progress > 0 or self.press_progress or len(
                self.waters) > 0:
            if self.water_animation:
                '''
                不用判断 water 是出现还是消失状态
                如果一直悬浮的话,颜色不会变
                而如果是点一下立马移开,文字会出现一种“渐隐渐现”的效果
                '''
                if len(self.waters) > 0:
                    pro = max(self.hover_progress, self.waters[-1].progress)
                else:
                    pro = self.hover_progress
            else:
                math.max(self.hover_progress, self.press_progress)
            edge_color.setAlpha(255 * (100 - pro) / 100)

        # 画边框
        path = QPainterPath()
        if self.show_foreground:
            path = self.getBgPainterPath()  # 整体背景

            # 出现动画
            if self.show_ani_appearing and self.show_ani_progress != 100 and self.border_bg.alpha(
            ) != 0:
                pw = self.size().width() * self.show_ani_progress / 100
                rect = QRect(0, 0, pw, self.size().height())
                rect_path = QPainterPath()
                rect_path.addRect(rect)
                path &= rect_path

                x = self.show_ani_point.x()
                y = self.show_ani_point.y()
                gen = self.quick_sqrt(x * x + y * y)
                x = -self.water_self.radius * x / gen  # 动画起始中心点横坐标 反向
                y = -self.water_self.radius * y / gen  # 动画起始中心点纵坐标 反向
            if self.border_bg.alpha() != 0:  # 如果有背景,则不进行画背景线条
                painter.setPen(self.border_bg)
                painter.drawPath(path)

        # 画文字
        if (self.self_enabled or self.fore_enabled) and self.text != '':
            rect = QRect(QPoint(0, 0), self.size())
            color: QColor
            if pro:
                if self.auto_text_color:
                    aim_color = QColor(0, 0, 0) if self.isLightColor(
                        self.hover_bg) else QColor(255, 255, 255)
                    color = QColor(
                        self.text_color.red() +
                        (aim_color.red() - self.text_color.red()) * pro / 100,
                        self.text_color.green() +
                        (aim_color.green() - self.text_color.green()) * pro /
                        100,
                        self.text_color.blue() +
                        (aim_color.blue() - self.text_color.blue()) * pro /
                        100, 255)
                painter.setPen(color)
            else:
                color = self.text_color
                color.setAlpha(255)
            painter.setPen(color)
            if self.font_size > 0:
                font = painter.font()
                font.setPixelSize(self.font_size)
                painter.setFont(font)
            painter.drawText(rect, Qt.AlignCenter, self.text)
Example #31
0
class DrawMask(QWidget):
    PREVIEW_CLIP_WIDTH = 450
    PREVIEW_MASK_WIDTH = 450

    def __init__(self, parent=None):
        super(DrawMask, self).__init__(parent=parent)
        self.parent = parent
        self.image_clip_data = None
        self.show_image_size = (0, 0)
        self.image_mask_data = None
        self.image_draw_data = None
        self.item_name_to_clip_image_info = {
        }  # (clip image, clip_pos_size, left_up_pos, size)
        self.item_name_to_mask_image_info = {}  # (mask image)
        self.current_item_name = 'image 1'
        self.color_pen = QColor(50, 200, 50)
        self.brush_size = 6

        # pick color
        ft2 = QFont()
        ft2.setBold(True)
        self.btn_color = QPushButton('Color', self)
        self.btn_color.clicked.connect(self.on_clicked_color)
        self.btn_color.setFont(ft2)
        pla = self.btn_color.palette()
        pla.setColor(QPalette.ButtonText, self.color_pen)
        self.btn_color.setPalette(pla)

        # brush setting
        self.label_brush_size = QLabel('Brush Size')
        self.spin_brush_size = QSpinBox(self)
        self.spin_brush_size.setRange(2, 50)
        self.spin_brush_size.setSingleStep(1)
        self.spin_brush_size.setValue(self.brush_size)
        self.spin_brush_size.valueChanged.connect(self.on_change_brush_size)

        self.btn_clear = QPushButton('Clear Mask', self)
        self.btn_clear.clicked.connect(self.on_clicked_clear)
        self.btn_finish = QPushButton('Finish', self)
        self.btn_finish.clicked.connect(self.on_clicked_finish)

        # image
        self.image_draw_mask = DrawLabel('image draw', self)
        self.image_draw_mask.setAlignment(Qt.AlignTop)
        self.image_draw_mask.setCursor(Qt.CrossCursor)
        self.image_mask_preview = QLabel('mask preview')
        self.image_mask_preview.setAlignment(Qt.AlignHCenter)

        # listview
        self.label_listview = QLabel('Select Image')
        self.model_image_clip = QStringListModel(self)
        self.model_image_clip.setStringList(
            self.item_name_to_clip_image_info.keys())
        self.listview_image_clip = QListView(self)
        self.listview_image_clip.setModel(self.model_image_clip)
        self.listview_image_clip.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.listview_image_clip.doubleClicked.connect(
            lambda: self.on_clicked_listview_item(self.listview_image_clip))

        self.grid_layout = QGridLayout()
        self.grid_layout.addWidget(self.label_brush_size, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.spin_brush_size, 0, 1, 1, 1)
        self.grid_layout.addWidget(self.btn_color, 0, 2, 1, 1)
        self.grid_layout.addWidget(self.btn_clear, 0, 6, 1, 2)
        self.grid_layout.addWidget(self.btn_finish, 0, 8, 1, 2)
        self.grid_layout.addWidget(self.image_draw_mask, 1, 0, 5, 5)
        self.grid_layout.addWidget(self.image_mask_preview, 1, 5, 5, 5,
                                   Qt.AlignTop)
        self.grid_layout.addWidget(self.label_listview, 6, 5, 1, 2)
        self.grid_layout.addWidget(self.listview_image_clip, 7, 5, 1, 4)
        self.setLayout(self.grid_layout)

    def set_image(self, item_name_to_clip_image_info):
        self.item_name_to_clip_image_info = item_name_to_clip_image_info
        self.model_image_clip.setStringList(
            self.item_name_to_clip_image_info.keys())

        for item_name, clip_image_info in self.item_name_to_clip_image_info.items(
        ):
            self.item_name_to_mask_image_info[item_name] = (np.copy(
                clip_image_info[0]), )
            self.item_name_to_mask_image_info[item_name][0][:, :] = 0

        self.parent.setTabEnabled(2, True)

        self.set_current_draw('image 1')

    def set_current_draw(self, item_name):
        from image_inpainting_demo import set_label_image
        self.current_item_name = item_name

        # show preview
        self.image_clip_data = self.item_name_to_clip_image_info[
            self.current_item_name][0]

        # create mask
        self.image_mask_data = self.item_name_to_mask_image_info[
            self.current_item_name][0]
        set_label_image(self.image_mask_preview, self.PREVIEW_MASK_WIDTH,
                        self.image_mask_data)

        # draw image
        color = (self.color_pen.red(), self.color_pen.green(),
                 self.color_pen.blue())
        self.image_draw_data = np.copy((self.image_mask_data / 255 * color) + (
            (1 - self.image_mask_data / 255) * self.image_clip_data))
        self.image_draw_data = np.array(self.image_draw_data, np.uint8)
        self.show_image_size = set_label_image(self.image_draw_mask,
                                               self.PREVIEW_CLIP_WIDTH,
                                               self.image_draw_data)

    def draw_mask(self, pos):
        from image_inpainting_demo import set_label_image

        show_width, show_height = self.show_image_size
        height, width, bytesPerComponent = self.image_clip_data.shape

        # calculate row coordinate
        to_row_width, to_row_height = width / float(
            show_width), height / float(show_height)
        actual_x, actual_y = int(pos[0] * to_row_width), int(pos[1] *
                                                             to_row_height)

        half_size = int(math.ceil(self.brush_size / 2.0))
        x1, y1 = min(actual_x + half_size, width), min(actual_y + half_size,
                                                       width)
        x0, y0 = max(actual_x - (self.brush_size - half_size),
                     0), max(actual_y - (self.brush_size - half_size), 0)

        self.image_mask_data[y0:y1 + 1, x0:x1 + 1] = 255
        set_label_image(self.image_mask_preview, self.PREVIEW_MASK_WIDTH,
                        self.image_mask_data)
        self.refresh_mask_image((x0, y0, x1, y1))

    def refresh_mask_image(self, x0y0_x1y1=None):
        from image_inpainting_demo import set_label_image

        color = (self.color_pen.red(), self.color_pen.green(),
                 self.color_pen.blue())
        if x0y0_x1y1:
            x1, y1 = x0y0_x1y1[2], x0y0_x1y1[3]
            x0, y0 = x0y0_x1y1[0], x0y0_x1y1[1]
            self.image_draw_data[y0:y1 + 1, x0:x1 + 1] = color
        else:
            self.image_draw_data = np.copy(
                (self.image_mask_data / 255 * color) +
                ((1 - self.image_mask_data / 255) * self.image_clip_data))
            self.image_draw_data = np.array(self.image_draw_data, np.uint8)
        set_label_image(self.image_draw_mask, self.PREVIEW_CLIP_WIDTH,
                        self.image_draw_data)

    def on_clicked_color(self):
        new_color = QColorDialog.getColor()
        if new_color.isValid():
            pla = self.btn_color.palette()
            pla.setColor(QPalette.ButtonText, new_color)
            self.btn_color.setPalette(pla)
            self.color_pen = new_color
            self.refresh_mask_image()

    def on_change_brush_size(self):
        self.brush_size = int(self.spin_brush_size.value())

    def on_clicked_clear(self):
        from image_inpainting_demo import set_label_image

        self.image_mask_data[:, :] = 0
        set_label_image(self.image_mask_preview, self.PREVIEW_MASK_WIDTH,
                        self.image_mask_data)
        self.refresh_mask_image()

    def on_clicked_finish(self):
        self.parent.image_inpainting.set_image(
            self.item_name_to_clip_image_info,
            self.item_name_to_mask_image_info)

    def on_clicked_listview_item(self, listview):
        data = listview.currentIndex().data()
        self.set_current_draw(data)
Example #32
0
class RGBSlider(QWidget):

    def __init__(self, _image=None, *args, **kwargs):
        super().__init__(*args, **kwargs) 
        self._image = _image

        self.initializeUI() 

    def initializeUI(self):
        """
        Initialize the window and display its contents to the screen. 
        """
        self.setMinimumSize(225, 300)
        self.setWindowTitle('9.3 - RGB Slider')

        # Store the current pixel value 
        self.current_val = QColor()

        self.setupWidgets()

        self.show()

    def setupWidgets(self):
        """
        Create instances of widgets and arrange them in layouts.
        """
        # Image that will display the current color set by
        # slider/spin_box values
        self.color_display = QImage(100, 100, QImage.Format_RGBX64)
        self.color_display.fill(Qt.black)

        self.cd_label = QLabel()
        self.cd_label.setPixmap(QPixmap.fromImage(self.color_display))
        self.cd_label.setScaledContents(True)

        # Create RGB sliders and spinboxes
        red_label = QLabel("Red")
        red_label.setFont(QFont('Helvetica', 14))
        self.red_slider = QSlider(Qt.Horizontal)
        self.red_slider.setObjectName("Red")
        self.red_slider.setMaximum(255)

        self.red_spinbox = QSpinBox()
        self.red_spinbox.setMaximum(255)

        green_label = QLabel("Green")
        green_label.setFont(QFont('Helvetica', 14))
        self.green_slider = QSlider(Qt.Horizontal)
        self.green_slider.setObjectName("Green")
        self.green_slider.setMaximum(255)

        self.green_spinbox = QSpinBox()
        self.green_spinbox.setMaximum(255)

        blue_label = QLabel("Blue")
        blue_label.setFont(QFont('Helvetica', 14))
        self.blue_slider = QSlider(Qt.Horizontal)
        self.blue_slider.setObjectName("Blue")
        self.blue_slider.setMaximum(255)

        self.blue_spinbox = QSpinBox()
        self.blue_spinbox.setMaximum(255)

        # Use the hex labels to display color values in hex format
        hex_label = QLabel("Hex Color ")
        self.hex_values_label = QLabel()

        hex_h_box = QHBoxLayout()
        hex_h_box.addWidget(hex_label, Qt.AlignRight)
        hex_h_box.addWidget(self.hex_values_label, Qt.AlignRight)

        hex_container = QWidget()
        hex_container.setLayout(hex_h_box)

        # Create grid layout for sliders and spinboxes
        grid = QGridLayout()
        grid.addWidget(red_label, 0, 0, Qt.AlignLeft)
        grid.addWidget(self.red_slider, 1, 0)
        grid.addWidget(self.red_spinbox, 1, 1)
        grid.addWidget(green_label, 2, 0, Qt.AlignLeft)
        grid.addWidget(self.green_slider, 3, 0)
        grid.addWidget(self.green_spinbox, 3, 1)
        grid.addWidget(blue_label, 4, 0, Qt.AlignLeft)
        grid.addWidget(self.blue_slider, 5, 0)
        grid.addWidget(self.blue_spinbox, 5, 1)
        grid.addWidget(hex_container, 6, 0, 1, 0)

        # Use [] to pass arguments to the valueChanged signal
        # The sliders and spinboxes for each color should display the 
        # same values and be updated at the same time.
        self.red_slider.valueChanged['int'].connect(self.updateRedSpinBox)
        self.red_spinbox.valueChanged['int'].connect(self.updateRedSlider)

        self.green_slider.valueChanged['int'].connect(self.updateGreenSpinBox)
        self.green_spinbox.valueChanged['int'].connect(self.updateGreenSlider)

        self.blue_slider.valueChanged['int'].connect(self.updateBlueSpinBox)
        self.blue_spinbox.valueChanged['int'].connect(self.updateBlueSlider)

        # Create container for rgb widgets
        rgb_widgets = QWidget()
        rgb_widgets.setLayout(grid)

        v_box = QVBoxLayout()
        v_box.addWidget(self.cd_label)
        v_box.addWidget(rgb_widgets)

        self.setLayout(v_box)

    # The following methods update the red, green and blue
    # sliders and spinboxes. 
    def updateRedSpinBox(self, value):
        self.red_spinbox.setValue(value)
        self.redValue(value)
        
    def updateRedSlider(self, value):
        self.red_slider.setValue(value)
        self.redValue(value)

    def updateGreenSpinBox(self, value):
        self.green_spinbox.setValue(value)
        self.greenValue(value)
        
    def updateGreenSlider(self, value):
        self.green_slider.setValue(value)
        self.greenValue(value)

    def updateBlueSpinBox(self, value):
        self.blue_spinbox.setValue(value)
        self.blueValue(value)
        
    def updateBlueSlider(self, value):
        self.blue_slider.setValue(value)
        self.blueValue(value)

    # Create new colors based upon the changes to the RGB values
    def redValue(self, value):
        new_color = qRgb(value, self.current_val.green(), self.current_val.blue())
        self.updateColorInfo(new_color)

    def greenValue(self, value):
        new_color = qRgb(self.current_val.red(), value, self.current_val.blue())
        self.updateColorInfo(new_color)

    def blueValue(self, value):
        new_color = qRgb(self.current_val.red(), self.current_val.green(), value)
        self.updateColorInfo(new_color)

    def updateColorInfo(self, color):
        """
        Update color displayed in image and set the hex values accordingly.
        """
        self.current_val = QColor(color)
        self.color_display.fill(color)

        self.cd_label.setPixmap(QPixmap.fromImage(self.color_display))
        self.hex_values_label.setText("{}".format(self.current_val.name()))

    def getPixelValues(self, event):
        """
        The method reimplements the mousePressEvent method. 
        To use, set an widget's mousePressEvent equal to getPixelValues, like so:
            image_label.mousePressEvent = rgb_slider.getPixelValues
        If an _image != None, then the user can select pixels in the images, 
        and update the sliders to get view the color, and get the rgb and hex values. 
        """
        x = event.x()
        y = event.y() 

        # valid() returns true if the point selected is a valid 
        # coordinate pair within the image
        if self._image.valid(x, y):
            self.current_val = QColor(self._image.pixel(x, y))

            red_val = self.current_val.red()
            green_val = self.current_val.green()
            blue_val = self.current_val.blue()

            self.updateRedSpinBox(red_val)
            self.updateRedSlider(red_val)
            self.updateGreenSpinBox(green_val)
            self.updateGreenSlider(green_val)
            self.updateBlueSpinBox(blue_val)
            self.updateBlueSlider(blue_val)
class MovablePolyLine(QGraphicsObject):
    def __init__(self, parent=None):
        super(MovablePolyLine, self).__init__(parent)
        self.setZValue(1000)
        self.polygon = QPolygonF()
        self.radius = 5.0
        self.itemList = []
        self.rect = QRectF()
        self.color = QColor(255,0,0)

        self.lineWidth = 5
        self.brightness = 0

        self.setOpacity(0.5)
        # self.setHandlesChildEvents(False)
        # self.setFlags(QGraphicsItem.ItemIsMovable)

        self.isDrawLine = True
        self.drawItemFlags = None

        self.points = None

        self.itemType = QGraphicsEllipseItem

    def setDrawLine(self, flag):
        self.isDrawLine = flag

    def setDrawItems(self, flags):
        self.drawItemFlags = flags
        for item, flag in zip(self.itemList, flags):
            if flag:
                item.show()
            else:
                item.hide()

    def setRadius(self, r):
        self.radius = r

        if self.points is None:
            return

        radii = 2*self.radius
        rectList = [QRectF(-self.radius, -self.radius, radii, radii) for p in self.points]
        for item, rect in zip(self.itemList, rectList):
            item.setRect(rect)

    def setLineWidth(self, w):
        self.lineWidth = w
        self.update()

    def getLineWidth(self):
        return self.lineWidth

    def setColor(self, rgb):
        rgb = [min(val+self.brightness, 255) for val in rgb]
        self.color = QColor(*rgb)
        for item in self.itemList:
            item.setBrush(self.color)

    def setBrightness(self, val):
        delta = val - self.brightness
        self.brightness = val
        rgb = [min(val+delta, 255) for val in [self.color.red(), self.color.green(), self.color.blue()]]
        self.color = QColor(*rgb)
        for item in self.itemList:
            item.setBrush(self.color)

    def getRadius(self):
        return self.radius

    # TODO:NaNが入ってると劇的に重くなるので,無理矢理NaNをはじいてはいる.
    #もう少しきれいに書き直すこと.
    #フレームが前に進むたびに値を詰め直しているためおそいので,その対策も同時に.
    def setPoints(self, ps=None, flags=None):
        if ps is not None and self.points is not None:
            points = [p for p in ps if not np.any(pd.isnull(p))]
            if len(points)==len(self.points):
                self.points = points
                for item, point in zip(self.itemList, self.points):
                    item.setPos(*point)
                    item.mouseMoveEvent = self.generateItemMouseMoveEvent(item, point)
                    item.mousePressEvent = self.generateItemMousePressEvent(item, point)
                self.update()
                return

        scene = self.scene()
        if scene is not None:
            for item in self.itemList:
                scene.removeItem(item)
                del item
        self.itemList.clear()

        if flags is not None:
            self.drawItemFlags = flags

        drawItemFlags = self.drawItemFlags

        if ps is not None:
            self.points = [p for p in ps if not np.any(pd.isnull(p))]
            drawItemFlags = [f for f, p in zip(self.drawItemFlags, ps) if not np.any(pd.isnull(p))]

        if self.points is not None:
            radii = 2*self.radius
            rectList = [QRectF(-self.radius, -self.radius, radii, radii) for p in self.points]
            self.itemList = [self.itemType(self) for rect in rectList]

            for item, point, rect, flag in zip(self.itemList, self.points, rectList, drawItemFlags):
                item.setBrush(self.color)
                item.setRect(rect)
                item.setPos(*point)

                if not flag:
                    item.hide()

                item.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemSendsScenePositionChanges)
                item.setAcceptHoverEvents(True)
                item.mouseMoveEvent = self.generateItemMouseMoveEvent(item, point)
                item.mousePressEvent = self.generateItemMousePressEvent(item, point)

    def setRect(self, rect):
        self.rect = rect

    def generateItemMouseMoveEvent(self, item, point):
        def itemMouseMoveEvent(event):
            self.itemType.mouseMoveEvent(item, event)
            centerPos = item.scenePos()

            point[0] = centerPos.x()
            point[1] = centerPos.y()
            self.update()
        return itemMouseMoveEvent

    def generateItemMousePressEvent(self, item, point):
        def itemMousePressEvent(event):
            self.itemType.mousePressEvent(item, event)
            pass
        return itemMousePressEvent

    def boundingRect(self):
        return self.rect

    def paint(self, painter, option, widget):
        if self.points is not None and self.isDrawLine:
            painter.save()

            pen = QPen(self.color)
            pen.setWidth(self.getLineWidth())

            painter.setPen(pen)
            qPoints = [QPointF(*p.tolist()) for p in self.points]
            polygon = QPolygonF(qPoints)
            painter.drawPolyline(polygon)

            painter.restore()
 def convertColor(color: QColor):
     return [color.red() / 255, color.green() / 255, color.blue() / 255]
Example #35
0
class ColorItem(QGraphicsItem):
    n = 0

    def __init__(self):
        super(ColorItem, self).__init__()

        self.color = QColor(qrand() % 256, qrand() % 256, qrand() % 256)

        self.setToolTip(
            "QColor(%d, %d, %d)\nClick and drag this color onto the robot!"
            % (self.color.red(), self.color.green(), self.color.blue())
        )
        self.setCursor(Qt.OpenHandCursor)
        self.setAcceptedMouseButtons(Qt.LeftButton)

    def boundingRect(self):
        return QRectF(-15.5, -15.5, 34, 34)

    def paint(self, painter, option, widget):
        painter.setPen(Qt.NoPen)
        painter.setBrush(Qt.darkGray)
        painter.drawEllipse(-12, -12, 30, 30)
        painter.setPen(QPen(Qt.black, 1))
        painter.setBrush(QBrush(self.color))
        painter.drawEllipse(-15, -15, 30, 30)

    def mousePressEvent(self, event):
        self.setCursor(Qt.ClosedHandCursor)

    def mouseMoveEvent(self, event):
        if (
            QLineF(QPointF(event.screenPos()), QPointF(event.buttonDownScreenPos(Qt.LeftButton))).length()
            < QApplication.startDragDistance()
        ):
            return

        drag = QDrag(event.widget())
        mime = QMimeData()
        drag.setMimeData(mime)

        ColorItem.n += 1
        if ColorItem.n > 2 and qrand() % 3 == 0:
            root = QFileInfo(__file__).absolutePath()

            image = QImage(root + "/images/head.png")
            mime.setImageData(image)
            drag.setPixmap(QPixmap.fromImage(image).scaled(30, 40))
            drag.setHotSpot(QPoint(15, 30))
        else:
            mime.setColorData(self.color)
            mime.setText("#%02x%02x%02x" % (self.color.red(), self.color.green(), self.color.blue()))

            pixmap = QPixmap(34, 34)
            pixmap.fill(Qt.white)

            painter = QPainter(pixmap)
            painter.translate(15, 15)
            painter.setRenderHint(QPainter.Antialiasing)
            self.paint(painter, None, None)
            painter.end()

            pixmap.setMask(pixmap.createHeuristicMask())

            drag.setPixmap(pixmap)
            drag.setHotSpot(QPoint(15, 20))

        drag.exec_()
        self.setCursor(Qt.OpenHandCursor)

    def mouseReleaseEvent(self, event):
        self.setCursor(Qt.OpenHandCursor)
Example #36
0
def createStyle(kpi, custom=False, sqlIdx=None):

    style = {}

    #try:
    # mandatory stuff
    if 'subtype' in kpi:
        style['subtype'] = kpi['subtype']
    else:
        style['subtype'] = None

    if 'name' in kpi:
        if custom:
            style['name'] = 'cs-' + kpi['name']
        else:
            style['name'] = kpi['name']
    else:
        return None

    if 'type' in kpi:
        if kpi['type'] == 'service':
            style['type'] = 's'
        else:
            style['type'] = 'h'
    else:
        return None

    if custom:
        if 'nofilter' in kpi:
            style['nofilter'] = True
        else:
            style['nofilter'] = False

        if 'sqlname' in kpi:
            style['sqlname'] = kpi['sqlname']
        else:
            if 'subtype' in kpi and kpi['subtype'] == 'gantt':
                style['sqlname'] = 'None'
            else:
                return None

    # optional stuff
    if 'group' in kpi:
        style['group'] = kpi['group']
    else:
        style['group'] = ''

    if 'description' in kpi:
        style['desc'] = kpi['description']
    else:
        style['desc'] = ''

    if 'label' in kpi:
        style['label'] = kpi['label']
    else:
        style['label'] = ''

    if 'sUnit' in kpi and 'dUnit' in kpi:
        sUnit = kpi['sUnit'].split('/')
        dUnit = kpi['dUnit'].split('/')

        if len(sUnit) > 1 and len(
                dUnit) > 1 and sUnit[1] == 'sample' and dUnit[1] == 'sec':
            style['sUnit'] = sUnit[0]
            style['dUnit'] = dUnit[0]
            style['perSample'] = True
        else:
            style['sUnit'] = kpi['sUnit']
            style['dUnit'] = kpi['dUnit']
    else:
        style['sUnit'] = '-'

    #create pen
    if 'color' in kpi:
        color = QColor(kpi['color'])
    else:
        color = QColor('#DDD')

    if 'style' in kpi and kpi['style'] != '':
        if kpi['style'] == 'solid':
            penStyle = Qt.SolidLine
        elif kpi['style'] == 'dotted':
            penStyle = Qt.DotLine
        elif kpi['style'] == 'dashed':
            penStyle = Qt.DashLine
        elif kpi['style'] == 'dotline':
            penStyle = Qt.DotLine
        elif kpi['style'] == 'bar' or kpi['style'] == 'candle':
            penStyle = Qt.SolidLine
        else:
            log('[W] pen style unknown: %s - [%s]' % (kpi['name'],
                                                      (kpi['style'])))
            penStyle = Qt.DashDotDotLine
    else:
        if style['type'] == 'h':
            penStyle = Qt.DashLine
        else:
            penStyle = Qt.SolidLine

    if kpi['name'][:7] == '---#---':
        style['pen'] = '-'
    else:
        if 'subtype' in kpi and kpi['subtype'] == 'gantt':
            # gantt stuff
            if 'width' in kpi:
                style['width'] = int(kpi['width'])
            else:
                style['width'] = 8

            if 'font' in kpi:
                style['font'] = int(kpi['font'])
            else:
                style['font'] = 8

            if 'shift' in kpi:
                style['shift'] = int(kpi['shift'])
            else:
                style['shift'] = 2

            if 'style' in kpi and (kpi['style'] == 'bar'
                                   or kpi['style'] == 'candle'):
                style['style'] = kpi['style']
            else:
                style['style'] = 'bar'

            clr = QColor(color)
            style['brush'] = clr
            penColor = QColor(clr.red() * 0.75,
                              clr.green() * 0.75,
                              clr.blue() * 0.75)
            style['pen'] = QPen(penColor, 1, penStyle)

            if 'y_range' in kpi and kpi['y_range'] != '':
                yr = kpi['y_range']
                style['y_range'] = [None] * 2
                style['y_range'][0] = 100 - max(0, yr[0])
                style['y_range'][1] = 100 - min(100, yr[1])
            else:
                style['y_range'] = [0, 100]
        else:
            # regular kpis
            style['pen'] = QPen(color, 1, penStyle)

    style['sql'] = sqlIdx
    '''
    except Exception as e:
        log(str(kpi))
        log(style)
        log('Error creating a style: %s' % str(e))
        
        return None
    '''
    return style
Example #37
0
class ClockBack(QColorThemedGraphicsObject):
    """
    Draw a nice back face of the clock.
    This is just the white circle for now.
    """
    def get_alpha(self):
        return self._alpha
    def set_alpha(self,c):
        self._alpha = c
        self.update()
    alpha = pyqtProperty(float, get_alpha, set_alpha)
    def get_line_width(self):
        return self._line_width
    def set_line_width(self,c):
        self._line_width = c
        self.update()
    line_width = pyqtProperty(float, get_line_width, set_line_width)

    def set_outline_color(self, outline_color):
        self._outline_color = outline_color

    def __init__(self, size, *args, **kw):
        super(ClockBack,self).__init__(*args, **kw)
        self.size = size
        self.bbox = QRectF(0, 0, self.size, self.size)
        self._color = QColor(255,0,0,255)
        self._outline_color = QColor(255,0,0,255)
        self._alpha = 255
        self._line_width = 3

    def paint(self, painter, option, widget):
        # Draw background
        painter.setPen(QPen(QColor(self._outline_color.red(),
                                   self._outline_color.green(),
                                   self._outline_color.blue(),
                                   0.5*255 + 0.5*self._alpha
        ), self._line_width))
        # How much white to mix in?
        # At low alpha, I want the background to be super close to
        # pure white.
        A=(1 - 0.07*(self._alpha/255.))
        B=1-A
        painter.setBrush(QColor(255*A+B*self._color.red(),
                                255*A+B*self._color.green(),
                                255*A+B*self._color.blue(),
                                self._alpha
        ))
        center = self.size/2
        painter.drawEllipse(self.bbox)
        ## Draw four ticks along the sides
        #pen = QPen(QColor(self._color.red(),
        #                  self._color.green(),
        #                  self._color.blue(),
        #                  128), 2)
        #painter.setPen(pen)
        #START, END = 0.40, 0.43
        #painter.drawLine(QPointF(center, center + START*self.size),
        #                 QPointF(center, center + END*self.size))
        #painter.drawLine(QPointF(center, center - START*self.size),
        #                 QPointF(center, center - END*self.size))
        #painter.drawLine(QPointF(center + START*self.size, center),
        #                 QPointF(center + END*self.size, center))
        #painter.drawLine(QPointF(center - START*self.size, center),
        #                 QPointF(center - END*self.size, center))
    def boundingRect(self):
        return QRectF(-self._line_width,
                      -self._line_width,
                      self.size + 2*self.line_width,
                      self.size + 2*self.line_width)
Example #38
0
class MainWindow(QMainWindow):
    def __init__(self, app):
        super().__init__()
        self.app = app
        self.showMaximized()
        self.image_service = ImageService()
        self.storage_service = StorageService()
        self.stacked_widget = QStackedWidget()
        self.stacked_widget.showMaximized()

        self.main_widget = MainWidget(self)
        self.settings_widget = SettingsWidget(self, Settings())
        self.pattern_widget = PatternWidget(self, Pattern())

        self.stacked_widget.addWidget(self.main_widget)
        self.stacked_widget.addWidget(self.pattern_widget)
        self.stacked_widget.addWidget(self.settings_widget)

        self.setCentralWidget(self.stacked_widget)

        self.selected_pattern_name = None
        self.selected_settings_name = None
        self.pattern = None
        self.settings = None
        self._create_actions()
        self._set_menu_bar()
        self._set_tool_bar()
        self.errors_color = QColor(255, 0, 0)

    def _create_actions(self):
        self.new_pattern_action = QAction(
            QIcon(os.path.join(ICONS_DIR, 'add.png')), "New pattern", self)
        self.new_pattern_action.triggered.connect(
            self._new_pattern_action_handler)

        self.new_settings_action = QAction(
            QIcon(os.path.join(ICONS_DIR, 'settings.png')), "New settings",
            self)
        self.new_settings_action.triggered.connect(
            self._new_settings_action_handler)

        self.next_image_action = QAction(
            QIcon(os.path.join(ICONS_DIR, 'next')), "Next image", self)
        self.next_image_action.triggered.connect(
            self._next_image_action_handler)
        self.next_image_action.setEnabled(False)

        self.errors_color_action = QAction(
            QIcon(os.path.join(ICONS_DIR, 'color.png')), "Errors marker", self)
        self.errors_color_action.triggered.connect(
            self._errors_color_action_handler)

        self.exit_action = QAction('Exit', self)
        self.exit_action.triggered.connect(self.app.quit)

    def _create_pattern_combo(self):
        self.pattern_combo = QComboBox(self)
        avaliable_pcbs = self.storage_service.get_avaliable_pattern_names()
        for name in avaliable_pcbs:
            self.pattern_combo.addItem(name)

        self.pattern_combo.activated[str].connect(
            self._selected_pattern_action_handler)

    def _create_settings_combo(self):
        self.settings_combo = QComboBox(self)
        avaliable_settings_names = self.storage_service.get_avaliable_settings_names(
        )
        for name in avaliable_settings_names:
            self.settings_combo.addItem(name)

        self.settings_combo.activated[str].connect(
            self._selected_settings_action_handler)

    def _set_menu_bar(self):
        menu_bar = self.menuBar()
        menu_file = menu_bar.addMenu('File')

        menu_file.addAction(self.new_pattern_action)
        menu_file.addAction(self.exit_action)

    def _set_tool_bar(self):
        self._create_pattern_combo()
        self._create_settings_combo()
        self.tool_bar = self.addToolBar('Tools')

        self.tool_bar.addWidget(self.pattern_combo)
        self.tool_bar.addAction(self.new_pattern_action)
        self.tool_bar.addSeparator()

        self.tool_bar.addWidget(self.settings_combo)
        self.tool_bar.addAction(self.new_settings_action)
        self.tool_bar.addAction(self.errors_color_action)
        self.tool_bar.addSeparator()

        self.tool_bar.addAction(self.next_image_action)

    def _new_pattern_action_handler(self):
        file_dialog = QFileDialog(self)
        file_dialog.setNameFilters(["All Files (*)", "Images (*.png *.jpg)"])
        file_dialog.selectNameFilter("Images (*.png *.jpg)")
        if file_dialog.exec_():
            filename = file_dialog.selectedFiles()[0]
            with wait_cursor():
                image_orig = cv2.imread(filename, cv2.IMREAD_COLOR)
                self.stacked_widget.removeWidget(self.pattern_widget)
                self.settings_widget = PatternWidget(self, Pattern())
                self.stacked_widget.addWidget(self.pattern_widget)
                self.stacked_widget.setCurrentWidget(self.pattern_widget)
                self.pattern_widget.setImage(image_orig)
                self.pattern_widget.update()

    def _new_settings_action_handler(self):
        file_dialog = QFileDialog(self)
        file_dialog.setNameFilters(["All Files (*)", "Images (*.png *.jpg)"])
        file_dialog.selectNameFilter("Images (*.png *.jpg)")
        if file_dialog.exec_():
            filename = file_dialog.selectedFiles()[0]
            with wait_cursor():
                image_orig = cv2.imread(filename, cv2.IMREAD_COLOR)
                self.stacked_widget.removeWidget(self.settings_widget)
                self.settings_widget = SettingsWidget(self, Settings())
                self.stacked_widget.addWidget(self.settings_widget)
                self.stacked_widget.setCurrentWidget(self.settings_widget)
                self.settings_widget.setImage(image_orig)
                self.settings_widget.update()

    def _next_image_action_handler(self):
        #all requirements met, don't check again
        image_orig = self.storage_service.next_image()
        if image_orig != None:
            with wait_cursor():
                images = self.image_service.transform_image(
                    image_orig, self.settings)
                images = self.image_service.compare(self.pattern, images,
                                                    self.settings)
                bgr = [
                    self.errors_color.blue(),
                    self.errors_color.green(),
                    self.errors_color.red()
                ]
                images = self.image_service.mark_errors(images, bgr)
                self.stacked_widget.removeWidget(self.main_widget)
                self.main_widget = MainWidget(self)
                self.stacked_widget.addWidget(self.main_widget)
                self.stacked_widget.setCurrentWidget(self.main_widget)
                self.main_widget.setImage(images)

    def _errors_color_action_handler(self):
        color = QColorDialog.getColor()
        if color.isValid():
            self.errors_color = color

    def _selected_pattern_action_handler(self, name):
        self.selected_pattern_name = name
        self.pattern = self.storage_service.load_pattern(
            self.selected_pattern_name)
        self._toggle_next_image_action()

    def _selected_settings_action_handler(self, name):
        self.selected_settings_name = name
        self.settings = self.storage_service.load_settings(
            self.selected_settings_name)
        self._toggle_next_image_action()

    def _toggle_next_image_action(self):
        if self.selected_pattern_name and self.selected_pattern_name != PATTERN_COMBO_NAME and self.selected_settings_name and self.selected_settings_name != SETTINGS_COMBO_NAME:
            self.next_image_action.setEnabled(True)
        else:
            self.next_image_action.setEnabled(False)

    ### PUBLIC METHODS ###

    def pattern_finished(self, pattern_name):
        if pattern_name:
            self.pattern_combo.clear()
            avaliable_pattern_names = self.storage_service.get_avaliable_pattern_names(
            )
            for name in avaliable_pattern_names:
                self.pattern_combo.addItem(name)
            index = self.pattern_combo.findText(pattern_name)
            self.pattern_combo.setCurrentIndex(index)
            self.selected_pattern_name = pattern_name
            self._toggle_next_image_action()
        self.stacked_widget.setCurrentWidget(self.main_widget)

    def settings_finished(self, settings_name):
        if settings_name:
            self.settings_combo.clear()
            avaliable_settings_names = self.storage_service.get_avaliable_settings_names(
            )
            for name in avaliable_settings_names:
                self.settings_combo.addItem(name)
            index = self.settings_combo.findText(settings_name)
            self.settings_combo.setCurrentIndex(index)
            self.selected_settings_name = name
            self._toggle_next_image_action()
        self.stacked_widget.setCurrentWidget(self.main_widget)