使用从maptoscene(event.pos())派生的坐标在cvMat图像上绘制

时间:2019-07-13 17:38:17

标签: python pyqt5 qgraphicsview

到目前为止,我一直在尝试获取来自leftmouseclick函数的坐标,然后使用该坐标绘制cvMat图像。 因此,在我左键单击graphviewer之后(ps。图像设置为与graphviewer和setpixmap相同的大小)。 leftmouseclick函数将获取event.pos()并通过maptoScene()进行进一步操作以获取scenepos。其次,我将像素图转换为np.ndarray,并将cv.cirle与scenepos.x()和scenepos.y()一起在图像上绘制圆。第三,我将np.ndarray转换回pixmap并更新为qgraphviewer。 我知道这听起来有点愚蠢,但是我的问题是绘制的圆圈不在我单击qgraphviewer的位置。 使用maptoscene()进行映射时是否发生移位或其他问题?

下面是代码的一部分

def np2qpixmap(np_img):
    frame = cv2.cvtColor(np_img, cv2.COLOR_BGR2RGB)
    img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], frame.shape[1]*3, QtGui.QImage.Format_RGB888)
    return QtGui.QPixmap.fromImage(img)

def QImageToCvMat(incomingImage):
    incomingImage = incomingImage.convertToFormat(4)

    width = incomingImage.width()
    height = incomingImage.height()

    ptr = incomingImage.bits()
    ptr.setsize(incomingImage.byteCount())
    arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
    return arr

class Main(QMainWindow, TestGUI.Ui_MainWindow):
    leftMouseButtonClicked = QtCore.pyqtSignal(float, float)
    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        scene = QtWidgets.QGraphicsScene()
        self.pixmap = QtWidgets.QGraphicsPixmapItem()
        scene.addItem(self.pixmap)
        self.graphicsView.setScene(scene)
        self.leftMouseButtonClicked.connect(self.handleLeftClick)
        self.imgroot = "./image"
        self.annoroot = ""
        self.img = None
        self.imgList = glob.glob(os.path.join(self.imgroot, "*.png"))
        self.img_num = len(self.imgList)
        self.ImageButton.setCheckable(True)
        self.AnnoButton.setCheckable(True)
        self.image_scale=1
        self.i = 0
        if self.img_num > 0:
            self.setImage()
        else:
            self.textBrowser(">> No Image in Folder")

    def UpdateImage(self, processed_image):
        if isinstance(processed_image, np.ndarray):
            self.img = np2qpixmap(processed_image)
            # self.img = QtGui.QPixmap(processed_image)
        self.pixmap.setPixmap(self.img)

    def setImage(self):
        self.img = QtGui.QPixmap(self.imgList[self.i])
        if self.img.height() > self.img.width():
            self.scale = self.img.height() / self.graphicsView.height()
            self.img = self.img.scaledToHeight(self.graphicsView.height())
            self.pixmap.setPixmap(self.img)
        else:
            self.scale = self.img.width() / self.graphicsView.width()
            self.img = self.img.scaledToWidth(self.graphicsView.width())
            self.pixmap.setPixmap(self.img)

    def PreviousImage(self):
        if self.i - 1 > - 1:
            self.i = self.i - 1
            self.setImage()
        else:
            self.ShowText(">> The First Image!!")

    def NextImage(self):
        if self.i + 1 < self.img_num:
            self.i = self.i + 1
            self.setImage()
        else:
            self.ShowText(">> The Last Image!!")

    def ShowText(self, msg):
        self.textBrowser.append(msg)

    def BrowseFolder(self):
        if self.ImageButton.isChecked():
            self.imgroot = self.getExistingDirectory()
            if os.path.isdir(self.imgroot):
                self.textBrowser.append(">> Set Image Folder : {}".format(self.imgroot))
                self.file_browser.clear()
                self.file_browser.append(self.imgroot)
                self.imgList = glob.glob(os.path.join(self.imgroot, "*.png"))
                self.img_num = len(self.imgList)
                self.i = 0
                if self.img_num > 0:
                    self.setImage()
                else:
                    self.textBrowser.append(">> No Image in Folder")
            else:
                self.textBrowser.append(">> Not a valid folder")
            self.ImageButton.setChecked(False)
        elif self.AnnoButton.isChecked():
            self.annoroot = self.getExistingDirectory()
            if os.path.isdir(self.annoroot):
                self.textBrowser.append(">> Set Annotation Folder : {}".format(self.annoroot))
                self.anno_file_browser.clear()
                self.anno_file_browser.append(self.annoroot)
                self.AnnoList = glob.glob(os.path.join(self.imgroot, "*.xml"))
            else:
                self.textBrowser.append(">> Not a valid folder")

    def getExistingDirectory(self):
        """
        Open a filedialog where you must choose a directory
        :return: The selected directory
        """
        return str(QFileDialog.getExistingDirectory(None, "Select Directory"))

    def ClearText(self):
        self.textBrowser.clear()

    def mouseDoubleClickEvent(self, event):
        """ Show entire image.
        """
        self.scenePos = self.graphicsView.mapToScene(event.pos())
        if event.button() == QtCore.Qt.LeftButton:
            self.leftMouseButtonClicked.emit(self.scenePos.x(), self.scenePos.y())
        QMainWindow.mouseDoubleClickEvent(self, event)

    def handleLeftClick(self, x, y):
        if isinstance(self.img, QtGui.QPixmap):
            Processed_Image = QImageToCvMat(self.img.toImage())
        else:
            Processed_Image = self.img
        # Processed_Image = cv2.cvtColor(Processed_Image, cv2.CV_8UC3)
        cv2.circle(Processed_Image, (int(x), int(y)), 1, (0,0,255), 1)
        self.UpdateImage(Processed_Image)
        self.ShowText(">> Clicked on image pixel (row={}, column={})".format(self.scenePos.y(), self.scenePos.x()))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    MainWindow = Main()
    MainWindow.show()
    sys.exit(app.exec_())

0 个答案:

没有答案