示例#1
0
def loadTriangles(leftPointFilePath, rightPointFilePath):
    #fileLeft = os.path.join(leftPointFilePath, 'TestData/LeftGray.png.txt')
    #fileRight = os.path.join(rightPointFilePath, 'TestData/RightGray.png.txt')

    leftTriangles = []
    rightTriangles = []

    #leftFile = np.loadtxt('LeftGray.png.txt')
    #print(leftFile)
    leftFile = np.loadtxt(leftPointFilePath)
    leftPoints = leftFile.astype(np.float)

    #rightFile = np.loadtxt('RightGray.png.txt')
    rightFile = np.loadtxt(rightPointFilePath)
    rightPoints = rightFile.astype(np.float)
    #print(leftPoints)
    leftSimplice = Delaunay(leftPoints).simplices
    rightSimplice = Delaunay(rightPoints).simplices
    #print(leftSimplice)
    # plt.triplot(leftPoints[:, 0], leftPoints[:, 1], leftSimplice)   ## can plot the triangles
    # plt.plot(leftPoints[:,0], leftPoints[:,1], 'o')
    # plt.show()
    #
    # plt.triplot(rightPoints[:, 0], rightPoints[:, 1], rightSimplice)  ## can plot the triangles
    # plt.plot(rightPoints[:, 0], rightPoints[:, 1], 'o')
    # plt.show()
    for triangle in leftSimplice.tolist():
        Tri = Triangle(leftPoints[triangle])
        Tri1 = Triangle(rightPoints[triangle])
        leftTriangles.append(Tri)  ## 3*2 triangle vertices for left
        #for triangle in rightSimplice.tolist():
        rightTriangles.append(Tri1)  ## 3*2 triangle vertices for right
    #print(tuple((leftTriangles, rightTriangles)))
    return tuple((leftTriangles, rightTriangles))
示例#2
0
def morph_pair(idx1, idx2, duration, fps, out_name, stream):
    """
    For a pair of images, produce a morph sequence with the given duration
    and fps to be written to the provided output stream.
    """
    im1 = IM_LIST[idx1]
    im2 = IM_LIST[idx2]

    im1_landmarks = LANDMARK_LIST[idx1]
    im2_landmarks = LANDMARK_LIST[idx2]

    total_frames = int(duration * fps)

    if im1_landmarks is None or im2_landmarks is None:
        print("No faces found, performing cross-dissolve between {} and {}".
              format(IM_FILES[idx1], IM_FILES[idx2]))
        cross_dissolve(total_frames, im1, im2, stream)

    else:
        average_landmarks = (im1_landmarks + im2_landmarks) / 2

        triangulation = Delaunay(average_landmarks).simplices
        # draw_triangulation(im2, average_landmarks, triangulation)

        h, w = im1.shape[:2]
        morph_seq(total_frames, im1, im2, im1_landmarks, im2_landmarks,
                  triangulation.tolist(), (w, h), out_name, stream)
    return Image.fromarray(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))
示例#3
0
class MorphingApp(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MorphingApp, self).__init__(parent)
        self.setupUi(self)
        self.btnBlend.setEnabled(False)
        self.chkTriangles.setEnabled(False)
        self.sliderAlpha.setEnabled(False)
        self.startSetImg = QGraphicsScene()
        self.endSetImg = QGraphicsScene()
        self.Morpher = QGraphicsScene()
        self.initialPoints = False
        self.addPoints = False
        self.comfirm = False
        #       QGraphicsScene()

        # self.leftImg =
        #self.rightImg =
        self.state = "first_state"
        self.gfxLeft.setScene(self.startSetImg)
        self.gfxRight.setScene(self.endSetImg)
        self.gfxBlendImg.setScene(self.Morpher)
        self.btnStartImg.clicked.connect(self.loadLeftImage)
        self.btnEndImg.clicked.connect(self.loadRightImage)
        self.sliderAlpha.valueChanged.connect(self.setAlpha)
        self.chkTriangles.stateChanged.connect(self.triangulation)
        self.btnBlend.clicked.connect(self.getImageAtAlpha)
        self.gfxLeft.mousePressEvent = self.setLeftPoints
        self.gfxRight.mousePressEvent = self.setRightPoints
        self.centralwidget.mousePressEvent = self.secondWaySave
        self.keyPressEvent = self.BackSpace
        #self.retriangulation()

    def loadLeftImage(self):
        """
        *** DO NOT MODIFY THIS METHOD! ***
        Obtain a file name from a file dialog, and pass it on to the loading method. This is to facilitate automated
        testing. Invoke this method when clicking on the 'load' button.

        You must modify the method below.
        """
        self.filePath, _ = QFileDialog.getOpenFileName(
            self, caption='Open JPG file ...', filter="Image (*.jpg *.png)")

        if not self.filePath:
            return
        self.startImage = imageio.imread(self.filePath)
        self.startSetImg.clear()
        self.startSetImg.addPixmap(QPixmap(self.filePath))
        self.gfxLeft.fitInView(self.startSetImg.itemsBoundingRect(),
                               QtCore.Qt.KeepAspectRatio)
        self.LeftimgPoints = self.filePath + '.txt'
        try:
            fh = open(self.LeftimgPoints, 'r')
            redPen = QPen(QtCore.Qt.red)
            redBrush = QBrush(QtCore.Qt.red)
            self.leftPoints = np.loadtxt(self.LeftimgPoints)
            self.initialPoints = True
            for x, y in self.leftPoints:
                self.startSetImg.addEllipse(x, y, 20, 20, redPen, redBrush)
        except FileNotFoundError:
            open(self.LeftimgPoints, 'w').close()
            self.initialPoints = False
            self.addPoints = False

    def loadRightImage(self):
        """
        *** DO NOT MODIFY THIS METHOD! ***
        Obtain a file name from a file dialog, and pass it on to the loading method. This is to facilitate automated
        testing. Invoke this method when clicking on the 'load' button.

        You must modify the method below.
        """
        self.filePath1, _ = QFileDialog.getOpenFileName(
            self, caption='Open JPG file ...', filter="Image (*.jpg *.png)")

        if not self.filePath1:
            return
        self.endImage = imageio.imread(self.filePath1)
        self.endSetImg.clear()
        self.endSetImg.addPixmap(QPixmap(self.filePath1))
        self.gfxRight.fitInView(self.endSetImg.itemsBoundingRect(),
                                QtCore.Qt.KeepAspectRatio)
        self.btnBlend.setEnabled(True)
        self.chkTriangles.setEnabled(True)
        self.sliderAlpha.setEnabled(True)
        self.txtAlpha.setEnabled(True)

        #load point correspondence
        self.RightimgPoints = self.filePath1 + '.txt'
        try:
            fh = open(self.RightimgPoints, 'r')
            self.rightPoints = np.loadtxt(self.RightimgPoints)
            redPen = QPen(QtCore.Qt.red)
            print(self.rightPoints)
            redBrush = QBrush(QtCore.Qt.red)
            self.initialPoints = True
            for x, y in self.rightPoints:
                self.endSetImg.addEllipse(x, y, 20, 20, redPen, redBrush)
        except FileNotFoundError:
            open(self.RightimgPoints, 'w').close()
            self.initialPoints = False
            self.addPoints = False

    def setAlpha(self):
        self.txtAlpha.setText(str(self.sliderAlpha.value() / 20.0))

    def retriangulation(self):
        if self.state == "right_set":
            if self.chkTriangles.isChecked():
                self.chkTriangles.setChecked(False)
                self.chkTriangles.setChecked(True)

    def triangulation(self):
        if self.chkTriangles.isChecked() == True:
            self.tri1 = []
            self.tri2 = []
            self.leftSimplices = Delaunay(self.leftPoints).simplices
            if self.initialPoints == True and self.addPoints == True:
                Pen = QPen(QtCore.Qt.cyan)
                print(1)
            elif self.addPoints == True:
                Pen = QPen(QtCore.Qt.blue)
                print(2)
            else:
                Pen = QPen(QtCore.Qt.red)
            for triangle in self.leftSimplices.tolist():
                #TriLeft = self.leftPoints[triangle]
                #TriRight = self.rightPoints[triangle]
                #leftTriangles.append(Tri)
                # print(self.leftPoints[triangle])
                #print(self.leftPoints[triangle[0]])

                pointA = QtCore.QPointF(self.leftPoints[triangle[0]][0],
                                        self.leftPoints[triangle[0]][1])
                PointB = QtCore.QPointF(self.leftPoints[triangle[1]][0],
                                        self.leftPoints[triangle[1]][1])
                PointC = QtCore.QPointF(self.leftPoints[triangle[2]][0],
                                        self.leftPoints[triangle[2]][1])
                self.drawTriangle = QtGui.QPolygonF([pointA, PointB, PointC])
                self.tri1Item = QGraphicsPolygonItem(self.drawTriangle)
                self.tri1Item.setPen(Pen)
                self.startSetImg.addItem(self.tri1Item)

                self.tri1.append(self.tri1Item)

                pointAA = QtCore.QPointF(self.rightPoints[triangle[0]][0],
                                         self.rightPoints[triangle[0]][1])
                PointBB = QtCore.QPointF(self.rightPoints[triangle[1]][0],
                                         self.rightPoints[triangle[1]][1])
                PointCC = QtCore.QPointF(self.rightPoints[triangle[2]][0],
                                         self.rightPoints[triangle[2]][1])
                self.drawTriangle1 = QtGui.QPolygonF(
                    [pointAA, PointBB, PointCC])
                self.tri2Item = QGraphicsPolygonItem(self.drawTriangle1)
                self.tri2Item.setPen(Pen)
                self.endSetImg.addItem(self.tri2Item)
                self.tri2.append(self.tri2Item)

        else:
            #print("111111111")
            for item1 in self.tri1:
                self.startSetImg.removeItem(item1)
            for item2 in self.tri2:
                self.endSetImg.removeItem(item2)

    def getImageAtAlpha(self):
        triangleTuple = loadTriangles(self.filePath + '.txt',
                                      self.filePath1 + '.txt')
        #img = Morpher(leftImage, triangleTuple[0], rightImage, triangleTuple[1]).getImageAtAlpha()

        alpha = self.sliderAlpha.value()
        img = Morpher(self.startImage, triangleTuple[0], self.endImage,
                      triangleTuple[1]).getImageAtAlpha(alpha / 20.0)
        imgQt = QImage(ImageQt.ImageQt(Image.fromarray(img)))
        result = QPixmap.fromImage(imgQt)
        self.Morpher.addPixmap(result)
        self.gfxBlendImg.fitInView(self.Morpher.itemsBoundingRect(),
                                   QtCore.Qt.KeepAspectRatio)

    def secondWaySave(self, e):
        if self.state == "right_set":
            self.comfirmPoints()
            self.state = "first_state"

    def setLeftPoints(self, e):
        if self.state == "first_state":
            ## if it contains points already
            self.leftPoint = self.gfxLeft.mapToScene(e.pos())
            greenPen = QPen(QtCore.Qt.green)
            greenBrush = QBrush(QtCore.Qt.green)
            self.leftPointItem = QGraphicsEllipseItem(self.leftPoint.x(),
                                                      self.leftPoint.y(), 20,
                                                      20)
            self.leftPointItem.setPen(greenPen)
            self.leftPointItem.setBrush(greenBrush)
            self.startSetImg.addItem(self.leftPointItem)
            self.state = "left_set"
        elif self.state == "right_set":
            self.comfirmPoints()
            ## if it contains points already
            self.leftPoint = self.gfxLeft.mapToScene(e.pos())
            greenPen = QPen(QtCore.Qt.green)
            greenBrush = QBrush(QtCore.Qt.green)
            self.leftPointItem = QGraphicsEllipseItem(self.leftPoint.x(),
                                                      self.leftPoint.y(), 20,
                                                      20)
            self.leftPointItem.setPen(greenPen)
            self.leftPointItem.setBrush(greenBrush)
            self.startSetImg.addItem(self.leftPointItem)
            self.state = "left_set"

    def setRightPoints(self, e):
        if self.state == "left_set":
            ## if it contains points already
            self.rightPoint = self.gfxRight.mapToScene(e.pos())
            greenPen = QPen(QtCore.Qt.green)
            greenBrush = QBrush(QtCore.Qt.green)
            self.rightPointItem = QGraphicsEllipseItem(self.rightPoint.x(),
                                                       self.rightPoint.y(), 20,
                                                       20)
            self.rightPointItem.setPen(greenPen)
            self.rightPointItem.setBrush(greenBrush)
            self.endSetImg.addItem(self.rightPointItem)
            self.state = "right_set"

    def comfirmPoints(self):
        #print(123)
        self.addPoints = True
        self.comfirm = True
        bluePen = QPen(QtCore.Qt.blue)
        blueBrush = QBrush(QtCore.Qt.blue)
        self.startSetImg.removeItem(self.leftPointItem)
        self.endSetImg.removeItem(self.rightPointItem)
        self.leftPointItem.setPen(bluePen)
        self.leftPointItem.setBrush(blueBrush)
        self.rightPointItem.setPen(bluePen)
        self.rightPointItem.setBrush(blueBrush)
        self.endSetImg.addItem(self.rightPointItem)
        self.startSetImg.addItem(self.leftPointItem)

        if os.stat(self.LeftimgPoints).st_size == 0 and os.stat(
                self.RightimgPoints).st_size == 0:
            self.leftPoints = np.array(
                [[self.leftPoint.x(), self.leftPoint.y()]])
            self.rightPoints = np.array(
                [[self.rightPoint.x(),
                  self.rightPoint.y()]])
        else:
            self.leftPoints = np.vstack(
                (self.leftPoints, [self.leftPoint.x(),
                                   self.leftPoint.y()]))
            #self.leftPoints.append([self.leftPoint.x(), self.leftPoint.y()])
            #self.rightPoints.append([self.rightPoint.x(), self.rightPoint.y()])
            self.rightPoints = np.vstack(
                (self.rightPoints, [self.rightPoint.x(),
                                    self.rightPoint.y()]))
        self.retriangulation()
        with open(self.filePath + '.txt', "w") as fin:
            for point in self.leftPoints.tolist():
                fin.write(
                    str((round(point[0], 1))) + '     ' +
                    str((round(point[1], 1))) + '\n')
        with open(self.filePath1 + '.txt', "w") as fin1:
            for point in self.rightPoints.tolist():
                fin1.write(
                    str((round(point[0], 1))) + '     ' +
                    str((round(point[1], 1))) + '\n')

    def BackSpace(self, e):
        key = e.key()
        if key == QtCore.Qt.Key_Backspace:

            if self.state == "left_set":
                self.startSetImg.removeItem(self.leftPointItem)
                self.state = "first_state"
            elif self.state == "right_set":
                self.endSetImg.removeItem(self.rightPointItem)
                self.state = "left_set"