Merge branch 'main' of https://whale.am28.uni-tuebingen.de/git/jgrewe/fixtracks
This commit is contained in:
commit
7d6c86ed6d
@ -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)
|
||||||
|
@ -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())
|
||||||
|
@ -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 = []
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user