sjaserds
@sjaserds
Студент

Как указать верные координаты на кадре opencv в интерфейсе PyQt?

Пытаюсь сделать выделение области на видео, но почему то точки ставятся не в том месте где стоит курсор.
Код:
Класс получения видео потока с камеры от отправка его другому потоку через сигнал. В классе описан config туда я сохраняю результат программы. (Координаты точек)

Импорты
from PyQt5.QtCore import pyqtSignal, QRect, QEvent, Qt
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import (QWidget, QLabel, QPushButton, QApplication, QHBoxLayout, QVBoxLayout)
from ConfigApp import *
from PyQt5.Qt import *
import numpy as np
import cv2
import sys


class ThreadOpenCV(QThread):
    changePixmap = pyqtSignal(QImage)

    def __init__(self):
        super().__init__()
        self.config = ConfigApp()
        self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
        self.data = None

        self.coordinatePoligone = [
            (self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_1_x"), self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_1_y")),
            (self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_2_x"), self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_2_y")),
            (self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_3_x"), self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_3_y")),
            (self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_4_x"), self.config.get_settings("config.ini", "OPTIONS_CAMERA", "point_4_y"))
        ]

    def run(self):
        self.cap.set(cv2.CAP_PROP_FPS, 24)
        while True:
            self.cap.set(cv2.CAP_PROP_CONTRAST, int(self.config.get_settings("config.ini", "OPTIONS_CAMERA", "contrast")))
            ret, frame = self.cap.read()
            if ret:
                if self.data == None:
                    pts = np.array([self.coordinatePoligone[0], self.coordinatePoligone[1], self.coordinatePoligone[2], self.coordinatePoligone[3]], np.int32)
                    pts = pts.reshape((-1, 1, 2))
                    cv2.polylines(frame, [pts], True, (0, 0, 255), 2)

                if self.data != None:
                    if len(self.data) <= 4:
                        for item in self.data:
                            cv2.circle(frame, item, 3, (0, 0, 255), -1)

                    if len(self.data) == 4:
                        pts = np.array([self.data[0], self.data[1], self.data[2], self.data[3]], np.int32)
                        pts = pts.reshape((-1, 1, 2))
                        cv2.polylines(frame, [pts], True,  (0, 0, 255), 2)

                image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                FlippedImage = cv2.flip(image, 1)
                ConvertToQtFormat = QImage(FlippedImage.data, FlippedImage.shape[1], FlippedImage.shape[0], QImage.Format_RGB888)
                pic = ConvertToQtFormat.scaled(640, 480, Qt.KeepAspectRatio)
                self.changePixmap.emit(pic)

                if cv2.waitKey(1) == ord('q'):
                    break


Класс получающий координаты и рисующий интерфейс, с многоугольником.
class Interface(QWidget):
    def __init__(self):
        super().__init__()
        self.initUi()

    def initUi(self):
        self.setWindowTitle("Options")
        # self.resize(1300, 500)
        self.points = []
        self.point = None
        self.data = None
        self.config = ConfigApp()
        self.thread = ThreadOpenCV()
        self.contrast = self.config.get_settings("config.ini", "OPTIONS_CAMERA", "contrast")

        #Interface elements
        self.label_video = QLabel(self)
        # self.label_video.setGeometry(QRect(10, 10, 720, 1280))
        self.label_video.setCursor(Qt.CrossCursor)
        self.btnSave = QPushButton("Сохранить", self)
        self.btnSave.setFixedSize(100, 40)
        self.horizontalSlider = QSlider(self)
        self.horizontalSlider.setFixedSize(300, 25)
        self.horizontalSlider.setObjectName("slider")
        self.horizontalSlider.setMaximum(100)
        self.horizontalSlider.setPageStep(1)
        self.horizontalSlider.setProperty("value", self.contrast)
        self.horizontalSlider.setOrientation(Qt.Horizontal)

        #Layouts
        self.mainLayout = QHBoxLayout()
        self.rightLayout = QVBoxLayout()

        #Options layout
        self.mainLayout.addWidget(self.label_video)
        self.rightLayout.addWidget(self.horizontalSlider)
        self.rightLayout.setContentsMargins(30, 30, 10, 10)
        self.rightLayout.addWidget(self.btnSave)
        self.mainLayout.addLayout(self.rightLayout)

        self.thread.start()
        self.thread.changePixmap.connect(self.setImage)
        self.btnSave.clicked.connect(self.saveWindowOptions)
        self.label_video.mousePressEvent = self.getPixel
        self.label_video.mouseReleaseEvent = self.addData

        self.setLayout(self.mainLayout)

    def getPixel(self, event):
        self.point = event.pos()
        print(self.point, event.pos().x(), event.pos().y())
        if len(self.points) <= 4:
            self.points.append((self.point.x() - 10, self.point.y() - 10))
            self.data = self.points
        else:
            self.points = []

    def addData(self, event):
        self.point = None
        self.thread.data = self.data

    def saveWindowOptions(self):
        if len(self.points) == 4:
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_1_x", str(self.points[0][0]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_1_y", str(self.points[0][1]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_2_x", str(self.points[1][0]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_2_y", str(self.points[1][1]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_3_x", str(self.points[2][0]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_3_y", str(self.points[2][1]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_4_x", str(self.points[3][0]))
            self.config.update_settings("config.ini", "OPTIONS_CAMERA", "point_4_y", str(self.points[3][1]))

    def setImage(self, image):
        self.label_video.setPixmap(QPixmap.fromImage(image))

    def event(self, event):
        if event.type() == QEvent.Close:
            self.thread.running = False
            self.thread.cap.release()
        return QWidget.event(self, event)


app = QApplication(sys.argv)
w = Interface()
w.show()
sys.exit(app.exec_())


Я получаю позицию мыши и отправляю ее в поток где cv2 отрысовывает точку по координатам, но почему cv2 отрысовывает неправильно будто изображение намного больше. Например я ставлю точку в интерфейсе по координате (631, 355) точка так и ставится на изображении. практически по середине но не внизу с права. Как мне поставиь точку в нижней правой части lable_video?
  • Вопрос задан
  • 156 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы