This commit is contained in:
Jan Grewe 2024-12-29 12:49:10 +01:00
commit 7d6c86ed6d
3 changed files with 81 additions and 45 deletions

View File

@ -1,5 +1,6 @@
import logging
from PyQt6.QtWidgets import QWidget, QStackedLayout
from PyQt6.QtCore import Qt
from fixtracks.taskwidgets import FixTracks
from fixtracks.detectionmerge import MergeDetections
@ -10,7 +11,9 @@ class CentralWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QStackedLayout()
layout.setAlignment(Qt.AlignmentFlag.AlignVCenter)
self._tw = TasksWidget()
self._tw.setMaximumHeight(200)
self._tw.clicked.connect(self._select_task)
self._tasksindex = layout.addWidget(self._tw)
self._mergewidget = MergeDetections(self)

View File

@ -1,12 +1,51 @@
import logging
from PyQt6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene
from PyQt6.QtCore import QThreadPool, QLineF, QPointF
from PyQt6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene, QGraphicsLineItem
from PyQt6.QtCore import QThreadPool, QLineF, QPointF, QRectF, Qt
from PyQt6.QtGui import QImage, QPixmap, QColor, QPen
from fixtracks.util import ImageReader
class VideoPreview(QWidget):
def __init__(self, left=True, parent=None):
super().__init__(None)
self._image = None
self._line_pen = QPen(QColor.fromString("red"), 4)
self._view = QGraphicsView()
self._view.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self._scene = None
self._pixmap = None
self._left = left
layout = QVBoxLayout()
layout.addWidget(self._view)
self.setLayout(layout)
def set_image(self, img):
self._scene = QGraphicsScene()
self._pixmap = self._scene.addPixmap(QPixmap.fromImage(img))
self._view.setScene(self._scene)
self._view.fitInView(self._scene.sceneRect(), mode=Qt.AspectRatioMode.KeepAspectRatio)
image_rect = self._pixmap.boundingRect()
start_x = image_rect.right() if self._left else image_rect.left()
start_y = image_rect.top()
end_y = image_rect.bottom()
self._scene.addLine(start_x, start_y, start_x, end_y, self._line_pen)
self._view.show()
def set_lineposition(self, position):
image_rect = self._pixmap.boundingRect()
for i in self._scene.items():
if isinstance(i, QGraphicsLineItem):
self._scene.removeItem(i)
start_x = image_rect.left() + position
start_y = image_rect.top()
end_y = image_rect.bottom()
self._scene.addLine(start_x, start_y, start_x, end_y, self._line_pen)
class MergeDetections(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
@ -24,27 +63,24 @@ class MergeDetections(QWidget):
self.left_videocombo.addItems(self._files)
self.left_posspinner = QSpinBox()
self.left_posspinner.valueChanged.connect(self.on_leftmergelinemove)
self.left_preview = QGraphicsView()
self.left_preview.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.left_line = None
self.left_preview = VideoPreview()
self.right_datacombo = QComboBox()
self.right_videocombo = QComboBox()
self.right_datacombo.addItems(self._files)
self.right_videocombo.addItems(self._files)
self.right_posspinner = QSpinBox()
self.right_preview = QLabel()
self.right_preview.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.right_line = None
self.right_posspinner.valueChanged.connect(self.on_rightmergelinemove)
self.right_preview = VideoPreview(left=False)
layout.addLayout(self.layout_controls())
splitter = QGridLayout()
# splitter.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
splitter.addWidget(self.left_preview, 0, 0)
splitter.addWidget(self.right_preview, 0, 1)
splitter.setColumnStretch(0, 1)
splitter.setColumnStretch(1, 1)
layout.addLayout(splitter)
self.setLayout(layout)
def layout_controls(self):
@ -71,7 +107,6 @@ class MergeDetections(QWidget):
grd.setColumnStretch(3, 50)
grd.setColumnMinimumWidth(0, 50)
grd.setColumnMinimumWidth(2, 50)
# grd.setRowStretch(4, 100)
return grd
@property
@ -103,8 +138,13 @@ class MergeDetections(QWidget):
self.right_datacombo.setCurrentIndex(0)
self.right_videocombo.currentIndexChanged.connect(self.on_rightvideoSelection)
self.left_videocombo.currentIndexChanged.connect(self.on_leftvideoSelection)
# self._files = file_list
def _toImage(self, frame):
height, width, _ = frame.shape
bytesPerLine = 3 * width
img = QImage(frame.data, width, height, bytesPerLine, QImage.Format.Format_BGR888).rgbSwapped()
return img
def on_rightvideoSelection(self):
logging.debug("Video selection of the %s side", "right")
self.right_imagereader = ImageReader(self.right_videocombo.currentText(), 100)
@ -114,13 +154,10 @@ class MergeDetections(QWidget):
def right_imgreaderDone(self, state):
logging.debug("Right image reader done with state %s", str(state))
frame = self.right_imagereader.frame
height, width, _ = frame.shape
bytesPerLine = 3 * width
img = QImage(frame.data, width, height, bytesPerLine, QImage.Format.Format_BGR888).rgbSwapped()
self.right_preview.setPixmap(QPixmap.fromImage(img).scaledToHeight(self.right_preview.height()))
self.right_posspinner.setMaximum(width)
self.left_posspinner.setValue(width-1)
img = self._toImage(frame)
self.right_preview.set_image(img)
self.right_posspinner.setMaximum(img.width() - 1)
self.right_posspinner.setValue(0)
def on_leftvideoSelection(self):
logging.debug("Video selection of the %s side", "left")
@ -131,25 +168,13 @@ class MergeDetections(QWidget):
def left_imgreaderDone(self, state):
logging.debug("Left image reader done with state %s", str(state))
frame = self.left_imagereader.frame
height, width, _ = frame.shape
bytesPerLine = 3 * width
img = QImage(frame.data, width, height, bytesPerLine, QImage.Format.Format_BGR888).rgbSwapped()
scene = QGraphicsScene()
scene.addPixmap(QPixmap.fromImage(img).scaledToHeight(self.left_preview.height()))
self.left_preview.setScene(scene)
# self.left_preview.setPixmap(QPixmap.fromImage(img).scaledToHeight(self.left_preview.height()))
self.left_posspinner.setMaximum(width-1)
self.left_posspinner.setValue(width-1)
origin = self.left_preview.mapToScene(int(width//2), 0)
destination = self.left_preview.mapToScene(width//2, height)
line = QLineF(origin, destination)
p = QPen(5)
c = QColor.fromString("red")
p.setColor(c)
self.left_line = scene.addLine(line, p)
self.left_preview.show()
img = self._toImage(frame)
self.left_preview.set_image(img)
self.left_posspinner.setMaximum(img.width() - 1)
self.left_posspinner.setValue(img.width() - 1)
def on_leftmergelinemove(self):
print(self.left_posspinner.value())
if self.left_line is not None:
self.left_line.setX(self.left_posspinner.value())
self.left_preview.set_lineposition(self.left_posspinner.value())
def on_rightmergelinemove(self):
self.right_preview.set_lineposition(self.right_posspinner.value())

View File

@ -1,8 +1,8 @@
import logging
import pathlib
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QFileDialog
from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel, QPushButton, QFileDialog, QSizePolicy
from PyQt6.QtCore import pyqtSignal, Qt
class TasksWidget(QWidget):
@ -10,20 +10,28 @@ class TasksWidget(QWidget):
def __init__(self, parent = None):
super().__init__(parent)
l = QVBoxLayout()
l.addWidget(QLabel("Tasks:"))
l = QHBoxLayout()
l.setAlignment(Qt.AlignmentFlag.AlignVCenter)
folderBtn = QPushButton("Select data folder")
folderBtn.setEnabled(True)
folderBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
folderBtn.clicked.connect(self._open_folder)
l.addWidget(folderBtn)
sublayout = QVBoxLayout()
self.mergeBtn = QPushButton("Merge detections")
self.mergeBtn.setEnabled(False)
self.mergeBtn.clicked.connect(self._merge_clicked)
self.mergeBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.tracksBtn = QPushButton("Join tracks")
self.tracksBtn.setEnabled(False)
self.tracksBtn.clicked.connect(self._tracks_clicked)
l.addWidget(self.mergeBtn)
l.addWidget(self.tracksBtn)
self.tracksBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
sublayout.addWidget(self.mergeBtn)
sublayout.addWidget(self.tracksBtn)
l.addLayout(sublayout)
self.setLayout(l)
self._file_list = []