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

View File

@ -1,12 +1,51 @@
import logging import logging
from PyQt6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene from PyQt6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene, QGraphicsLineItem
from PyQt6.QtCore import QThreadPool, QLineF, QPointF from PyQt6.QtCore import QThreadPool, QLineF, QPointF, QRectF, Qt
from PyQt6.QtGui import QImage, QPixmap, QColor, QPen from PyQt6.QtGui import QImage, QPixmap, QColor, QPen
from fixtracks.util import ImageReader 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): class MergeDetections(QWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
@ -24,27 +63,24 @@ class MergeDetections(QWidget):
self.left_videocombo.addItems(self._files) self.left_videocombo.addItems(self._files)
self.left_posspinner = QSpinBox() self.left_posspinner = QSpinBox()
self.left_posspinner.valueChanged.connect(self.on_leftmergelinemove) self.left_posspinner.valueChanged.connect(self.on_leftmergelinemove)
self.left_preview = QGraphicsView() self.left_preview = VideoPreview()
self.left_preview.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.left_line = None
self.right_datacombo = QComboBox() self.right_datacombo = QComboBox()
self.right_videocombo = QComboBox() self.right_videocombo = QComboBox()
self.right_datacombo.addItems(self._files) self.right_datacombo.addItems(self._files)
self.right_videocombo.addItems(self._files) self.right_videocombo.addItems(self._files)
self.right_posspinner = QSpinBox() self.right_posspinner = QSpinBox()
self.right_preview = QLabel() self.right_posspinner.valueChanged.connect(self.on_rightmergelinemove)
self.right_preview.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.right_preview = VideoPreview(left=False)
self.right_line = None
layout.addLayout(self.layout_controls()) layout.addLayout(self.layout_controls())
splitter = QGridLayout() splitter = QGridLayout()
# splitter.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
splitter.addWidget(self.left_preview, 0, 0) splitter.addWidget(self.left_preview, 0, 0)
splitter.addWidget(self.right_preview, 0, 1) splitter.addWidget(self.right_preview, 0, 1)
splitter.setColumnStretch(0, 1) splitter.setColumnStretch(0, 1)
splitter.setColumnStretch(1, 1) splitter.setColumnStretch(1, 1)
layout.addLayout(splitter) layout.addLayout(splitter)
self.setLayout(layout) self.setLayout(layout)
def layout_controls(self): def layout_controls(self):
@ -71,7 +107,6 @@ class MergeDetections(QWidget):
grd.setColumnStretch(3, 50) grd.setColumnStretch(3, 50)
grd.setColumnMinimumWidth(0, 50) grd.setColumnMinimumWidth(0, 50)
grd.setColumnMinimumWidth(2, 50) grd.setColumnMinimumWidth(2, 50)
# grd.setRowStretch(4, 100)
return grd return grd
@property @property
@ -103,8 +138,13 @@ class MergeDetections(QWidget):
self.right_datacombo.setCurrentIndex(0) self.right_datacombo.setCurrentIndex(0)
self.right_videocombo.currentIndexChanged.connect(self.on_rightvideoSelection) self.right_videocombo.currentIndexChanged.connect(self.on_rightvideoSelection)
self.left_videocombo.currentIndexChanged.connect(self.on_leftvideoSelection) 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): def on_rightvideoSelection(self):
logging.debug("Video selection of the %s side", "right") logging.debug("Video selection of the %s side", "right")
self.right_imagereader = ImageReader(self.right_videocombo.currentText(), 100) self.right_imagereader = ImageReader(self.right_videocombo.currentText(), 100)
@ -114,13 +154,10 @@ class MergeDetections(QWidget):
def right_imgreaderDone(self, state): def right_imgreaderDone(self, state):
logging.debug("Right image reader done with state %s", str(state)) logging.debug("Right image reader done with state %s", str(state))
frame = self.right_imagereader.frame frame = self.right_imagereader.frame
height, width, _ = frame.shape img = self._toImage(frame)
bytesPerLine = 3 * width self.right_preview.set_image(img)
img = QImage(frame.data, width, height, bytesPerLine, QImage.Format.Format_BGR888).rgbSwapped() self.right_posspinner.setMaximum(img.width() - 1)
self.right_preview.setPixmap(QPixmap.fromImage(img).scaledToHeight(self.right_preview.height())) self.right_posspinner.setValue(0)
self.right_posspinner.setMaximum(width)
self.left_posspinner.setValue(width-1)
def on_leftvideoSelection(self): def on_leftvideoSelection(self):
logging.debug("Video selection of the %s side", "left") logging.debug("Video selection of the %s side", "left")
@ -131,25 +168,13 @@ class MergeDetections(QWidget):
def left_imgreaderDone(self, state): def left_imgreaderDone(self, state):
logging.debug("Left image reader done with state %s", str(state)) logging.debug("Left image reader done with state %s", str(state))
frame = self.left_imagereader.frame frame = self.left_imagereader.frame
height, width, _ = frame.shape img = self._toImage(frame)
bytesPerLine = 3 * width self.left_preview.set_image(img)
img = QImage(frame.data, width, height, bytesPerLine, QImage.Format.Format_BGR888).rgbSwapped() self.left_posspinner.setMaximum(img.width() - 1)
scene = QGraphicsScene() self.left_posspinner.setValue(img.width() - 1)
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()
def on_leftmergelinemove(self): def on_leftmergelinemove(self):
print(self.left_posspinner.value()) self.left_preview.set_lineposition(self.left_posspinner.value())
if self.left_line is not None:
self.left_line.setX(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 logging
import pathlib import pathlib
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton, QFileDialog from PyQt6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel, QPushButton, QFileDialog, QSizePolicy
from PyQt6.QtCore import pyqtSignal from PyQt6.QtCore import pyqtSignal, Qt
class TasksWidget(QWidget): class TasksWidget(QWidget):
@ -10,20 +10,28 @@ class TasksWidget(QWidget):
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
l = QVBoxLayout() l = QHBoxLayout()
l.addWidget(QLabel("Tasks:")) l.setAlignment(Qt.AlignmentFlag.AlignVCenter)
folderBtn = QPushButton("Select data folder") folderBtn = QPushButton("Select data folder")
folderBtn.setEnabled(True) folderBtn.setEnabled(True)
folderBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
folderBtn.clicked.connect(self._open_folder) folderBtn.clicked.connect(self._open_folder)
l.addWidget(folderBtn) l.addWidget(folderBtn)
sublayout = QVBoxLayout()
self.mergeBtn = QPushButton("Merge detections") self.mergeBtn = QPushButton("Merge detections")
self.mergeBtn.setEnabled(False) self.mergeBtn.setEnabled(False)
self.mergeBtn.clicked.connect(self._merge_clicked) self.mergeBtn.clicked.connect(self._merge_clicked)
self.mergeBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.tracksBtn = QPushButton("Join tracks") self.tracksBtn = QPushButton("Join tracks")
self.tracksBtn.setEnabled(False) self.tracksBtn.setEnabled(False)
self.tracksBtn.clicked.connect(self._tracks_clicked) self.tracksBtn.clicked.connect(self._tracks_clicked)
l.addWidget(self.mergeBtn) self.tracksBtn.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
l.addWidget(self.tracksBtn)
sublayout.addWidget(self.mergeBtn)
sublayout.addWidget(self.tracksBtn)
l.addLayout(sublayout)
self.setLayout(l) self.setLayout(l)
self._file_list = [] self._file_list = []