work work
This commit is contained in:
parent
8c62d17dde
commit
7586643faa
@ -47,7 +47,7 @@ class PreviewDialog(QDialog):
|
||||
imgfile = file_dialog.selectedFiles()[0]
|
||||
if imgfile is not None:
|
||||
img = QImage(imgfile)
|
||||
self.merge_preview.set_image(img)
|
||||
self.merge_preview.setImage(img)
|
||||
|
||||
file_dialog = QFileDialog(self, "Select pickled DataFrame", "", "Pandas DataFrame (*.pkl)")
|
||||
if file_dialog.exec():
|
||||
@ -63,7 +63,7 @@ class PreviewDialog(QDialog):
|
||||
self._progress_bar.setValue(0)
|
||||
if state and self._reader is not None:
|
||||
self._df = self._reader.data
|
||||
self.merge_preview.set_dataframe(self._df)
|
||||
self.merge_preview.setDataframe(self._df)
|
||||
self._reader = None
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from PySide6.QtCore import Signal, QObject
|
||||
from PySide6.QtCore import Signal, QObject, QPointF
|
||||
|
||||
class ProducerSignals(QObject):
|
||||
finished = Signal(bool)
|
||||
@ -7,3 +7,13 @@ class ProducerSignals(QObject):
|
||||
# running = pyqtSignal()
|
||||
progress = Signal(float)
|
||||
progress2 = Signal((str, float, float))
|
||||
|
||||
class DetectionSignals(QObject):
|
||||
hover = Signal((int, QPointF))
|
||||
clicked = Signal((int, QPointF))
|
||||
|
||||
class TimelineSignals(QObject):
|
||||
changed = Signal(int)
|
||||
|
||||
class ControlSignals(QPointF):
|
||||
test = Signal(int)
|
@ -2,7 +2,7 @@ import logging
|
||||
from PySide6.QtWidgets import QWidget, QStackedLayout, QSizePolicy
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
from fixtracks.widgets.taskwidgets import FixTracks
|
||||
from fixtracks.widgets.tracks import FixTracks
|
||||
from fixtracks.widgets.detectionmerge import MergeDetections
|
||||
from fixtracks.widgets.taskwidget import TasksWidget
|
||||
from fixtracks.widgets.converter import Json2PandasConverter
|
||||
@ -23,6 +23,7 @@ class CentralWidget(QWidget):
|
||||
self._convertwidget.back.connect(self._on_back)
|
||||
|
||||
self._trackwidget = FixTracks(self)
|
||||
self._trackwidget.back.connect(self._on_back)
|
||||
|
||||
layout = QStackedLayout()
|
||||
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
|
@ -22,7 +22,7 @@ class VideoPreview(QWidget):
|
||||
layout.addWidget(self._view)
|
||||
self.setLayout(layout)
|
||||
|
||||
def set_image(self, img):
|
||||
def setImage(self, img):
|
||||
self._image = img
|
||||
self._scene = QGraphicsScene()
|
||||
self._pixmapitem = self._scene.addPixmap(QPixmap.fromImage(img))
|
||||
@ -36,7 +36,7 @@ class VideoPreview(QWidget):
|
||||
self._scene.addLine(start_x, start_y, start_x, end_y, self._line_pen)
|
||||
self._view.show()
|
||||
|
||||
def set_lineposition(self, position):
|
||||
def setLineposition(self, position):
|
||||
image_rect = self._pixmapitem.boundingRect()
|
||||
for i in self._scene.items():
|
||||
if isinstance(i, QGraphicsLineItem):
|
||||
@ -206,7 +206,7 @@ class MergeDetections(QWidget):
|
||||
frame = self.right_imagereader.frame
|
||||
if frame is not None:
|
||||
img = self._toImage(frame)
|
||||
self.right_preview.set_image(img)
|
||||
self.right_preview.setImage(img)
|
||||
self.right_posspinner.setMaximum(img.width() - 1)
|
||||
self.right_posspinner.setValue(0)
|
||||
self.checkButtons()
|
||||
@ -224,7 +224,7 @@ class MergeDetections(QWidget):
|
||||
frame = self.left_imagereader.frame
|
||||
if frame is not None:
|
||||
img = self._toImage(frame)
|
||||
self.left_preview.set_image(img)
|
||||
self.left_preview.setImage(img)
|
||||
self.left_posspinner.setMaximum(img.width() - 1)
|
||||
self.left_posspinner.setValue(img.width() - 1)
|
||||
self.checkButtons()
|
||||
@ -260,10 +260,10 @@ class MergeDetections(QWidget):
|
||||
self.checkButtons()
|
||||
|
||||
def on_leftmergelinemove(self):
|
||||
self.left_preview.set_lineposition(self.left_posspinner.value())
|
||||
self.left_preview.setLineposition(self.left_posspinner.value())
|
||||
|
||||
def on_rightmergelinemove(self):
|
||||
self.right_preview.set_lineposition(self.right_posspinner.value())
|
||||
self.right_preview.setLineposition(self.right_posspinner.value())
|
||||
|
||||
def on_mergePreview(self):
|
||||
logging.debug("detectionmerge: mergePreview pressed")
|
||||
|
@ -1,12 +1,10 @@
|
||||
import logging
|
||||
import numpy as np
|
||||
|
||||
from PySide6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene, QGraphicsLineItem, QSpacerItem, QProgressDialog, QFileDialog, QSlider
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSizePolicy, QSpinBox, QGraphicsView, QGraphicsScene, QSpacerItem, QSlider
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QPixmap, QBrush, QColor
|
||||
|
||||
from fixtracks.utils.reader import ImageReader
|
||||
|
||||
|
||||
class MergePreview(QWidget):
|
||||
|
||||
@ -88,7 +86,7 @@ class MergePreview(QWidget):
|
||||
self._keypointCombo.clear()
|
||||
self._keypointCombo.addItems([f"keypoint {i}" for i in range(numkeypoints)])
|
||||
|
||||
def set_dataframe(self, newdf):
|
||||
def setDataframe(self, newdf):
|
||||
self._dataframe = newdf
|
||||
self._frames = self._dataframe.frame.values
|
||||
self._keypoints = self._dataframe.keypoints.values
|
||||
@ -115,11 +113,11 @@ class MergePreview(QWidget):
|
||||
self._startLabel.setText(str(self._startSlider.value()))
|
||||
self._stopLabel.setText(str(self._stopSlider.value()))
|
||||
|
||||
def set_image(self, img):
|
||||
def setImage(self, img):
|
||||
self._image = img
|
||||
self.update()
|
||||
|
||||
def _draw_detections(self):
|
||||
def _drawDetections(self):
|
||||
start_frame = self._startSlider.value()
|
||||
stop_frame = self._stopSlider.value()
|
||||
selection = self._keypoints[self._frames[(self._frames >= start_frame) & (self._frames < stop_frame)]]
|
||||
@ -145,7 +143,7 @@ class MergePreview(QWidget):
|
||||
self._view.setScene(self._scene)
|
||||
self._view.fitInView(self._scene.sceneRect(), aspectRadioMode=Qt.AspectRatioMode.KeepAspectRatio)
|
||||
self._view.show()
|
||||
self._draw_detections()
|
||||
self._drawDetections()
|
||||
|
||||
def fit_image_to_view(self):
|
||||
"""Scale the image to fit the QGraphicsView."""
|
||||
|
@ -79,10 +79,6 @@ class TasksWidget(QWidget):
|
||||
l.addWidget(mergeBtn, 1, 1, 1, 1, Qt.AlignmentFlag.AlignCenter)
|
||||
l.addWidget(tracksBtn, 2, 1, 1, 1, Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
# l.addWidget(folderBtn)
|
||||
# l.addWidget(self.convertBtn)
|
||||
# l.addWidget(self.mergeBtn)
|
||||
# l.addWidget(self.tracksBtn)
|
||||
self.setLayout(l)
|
||||
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
import logging
|
||||
|
||||
from PySide6.QtWidgets import QWidget, QGridLayout, QVBoxLayout, QLabel, QPushButton, QFileDialog, QHBoxLayout, QComboBox, QSizePolicy
|
||||
from PySide6.QtCore import QThreadPool
|
||||
from PySide6.QtGui import QImage, QPixmap
|
||||
|
||||
from fixtracks.utils.reader import ImageReader
|
||||
|
||||
class FixTracks(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._files = None
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(QLabel("Fix Tracks!"))
|
||||
self.setLayout(layout)
|
||||
|
||||
@property
|
||||
def fileList(self, file_list):
|
||||
self._files = file_list
|
192
fixtracks/widgets/tracks.py
Normal file
192
fixtracks/widgets/tracks.py
Normal file
@ -0,0 +1,192 @@
|
||||
import logging
|
||||
import pathlib
|
||||
import numpy as np
|
||||
|
||||
from PySide6.QtCore import Qt, QThreadPool, Signal
|
||||
from PySide6.QtGui import QImage, QStandardItemModel, QStandardItem
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QSizePolicy
|
||||
from PySide6.QtWidgets import QSpinBox, QSpacerItem, QFileDialog, QProgressBar, QTableView, QSplitter
|
||||
|
||||
from fixtracks.utils.reader import PickleLoader
|
||||
from fixtracks.widgets.detectionview import DetectionView
|
||||
from fixtracks.widgets.timeline import Timeline
|
||||
|
||||
class FixTracks(QWidget):
|
||||
back = Signal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self._files = []
|
||||
self._threadpool = QThreadPool()
|
||||
self._reader = None
|
||||
self._image = None
|
||||
self._dataframe = None
|
||||
self._unassignedmodel = None
|
||||
self._leftmodel = None
|
||||
self._rightmodel = None
|
||||
|
||||
self._detectionView = DetectionView()
|
||||
self._progress_bar = QProgressBar(self)
|
||||
self._progress_bar.setMaximumHeight(20)
|
||||
# self._progress_bar.setRange(0, 0) # Set the progress bar to be indeterminate
|
||||
self._progress_bar.setValue(0)
|
||||
self._tasklabel = QLabel()
|
||||
|
||||
self._timeline = Timeline()
|
||||
self._timeline.signals.changed.connect(self.on_windowChanged)
|
||||
self._windowspinner = QSpinBox()
|
||||
self._windowspinner.setRange(100, 10000)
|
||||
self._windowspinner.setSingleStep(100)
|
||||
self._windowspinner.valueChanged.connect(self.on_windowSizeChanged)
|
||||
|
||||
timelinebox = QHBoxLayout()
|
||||
timelinebox.addWidget(self._timeline)
|
||||
timelinebox.addWidget(QLabel("Window"))
|
||||
timelinebox.addWidget(self._windowspinner)
|
||||
|
||||
self._left_table = QTableView()
|
||||
assign1 = QPushButton("<<")
|
||||
assign1.clicked.connect(self.on_assignLeft)
|
||||
assign2 = QPushButton(">>")
|
||||
assign2.clicked.connect(self.on_assignRight)
|
||||
self._unassigned_table = QTableView()
|
||||
self._right_table = QTableView()
|
||||
tablebox = QHBoxLayout()
|
||||
tablebox.addWidget(self._left_table)
|
||||
tablebox.addWidget(assign1)
|
||||
tablebox.addWidget(self._unassigned_table)
|
||||
tablebox.addWidget(assign2)
|
||||
tablebox.addWidget(self._right_table)
|
||||
|
||||
self._openBtn = QPushButton("Open")
|
||||
self._openBtn.setEnabled(True)
|
||||
self._openBtn.clicked.connect(self._on_open)
|
||||
self._saveBtn = QPushButton("Save")
|
||||
self._saveBtn.setEnabled(False)
|
||||
self._saveBtn.clicked.connect(self.on_save)
|
||||
self._backBtn = QPushButton("Back")
|
||||
self._backBtn.clicked.connect(self.on_back)
|
||||
|
||||
btnBox = QHBoxLayout()
|
||||
btnBox.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
||||
btnBox.addWidget(self._backBtn)
|
||||
btnBox.addItem(QSpacerItem(100, 10, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed))
|
||||
btnBox.addWidget(self._tasklabel)
|
||||
btnBox.addWidget(self._progress_bar)
|
||||
btnBox.addWidget(self._openBtn)
|
||||
btnBox.addWidget(self._saveBtn)
|
||||
|
||||
vbox = QVBoxLayout()
|
||||
vbox.addLayout(timelinebox)
|
||||
vbox.addLayout(tablebox)
|
||||
vbox.addLayout(btnBox)
|
||||
container = QWidget()
|
||||
container.setLayout(vbox)
|
||||
|
||||
splitter = QSplitter(Qt.Orientation.Horizontal)
|
||||
splitter.addWidget(self._detectionView)
|
||||
splitter.addWidget(container)
|
||||
splitter.setStretchFactor(0, 3)
|
||||
splitter.setStretchFactor(1, 1)
|
||||
layout = QHBoxLayout()
|
||||
layout.addWidget(splitter)
|
||||
self.setLayout(layout)
|
||||
|
||||
def _on_open(self):
|
||||
infile = None
|
||||
imgfile = None
|
||||
|
||||
self._tasklabel.setText( "Select merged image")
|
||||
file_dialog = QFileDialog(self, "Select merged image")
|
||||
file_dialog.setFileMode(QFileDialog.ExistingFile)
|
||||
file_dialog.setNameFilters([
|
||||
"Image Files (*.png *.jpg *.jpeg)",
|
||||
"All Files (*)"
|
||||
])
|
||||
if file_dialog.exec():
|
||||
imgfile = file_dialog.selectedFiles()[0]
|
||||
if imgfile is not None:
|
||||
img = QImage(imgfile)
|
||||
self._detectionView.setImage(img)
|
||||
self._tasklabel.setText( "Open data")
|
||||
file_dialog = QFileDialog(self, "Select pickled DataFrame", "", "Pandas DataFrame (*.pkl)")
|
||||
if file_dialog.exec():
|
||||
infile = file_dialog.selectedFiles()[0]
|
||||
if infile is not None:
|
||||
self._progress_bar.setRange(0,0)
|
||||
self._reader = PickleLoader(infile)
|
||||
self._reader.signals.finished.connect(self._on_dataOpenend)
|
||||
self._threadpool.start(self._reader)
|
||||
|
||||
|
||||
def populateTables(self):
|
||||
left_trackid = 1
|
||||
right_trackid = 2
|
||||
start_frame = self._timeline.sliderPosition - self._windowspinner.value() // 2
|
||||
stop_frame = self._timeline.sliderPosition + self._windowspinner.value() // 2
|
||||
df = self._dataframe[(self._dataframe.frame >= start_frame) & (self._dataframe.frame < stop_frame)]
|
||||
|
||||
assigned_left = df[(df.track == left_trackid)]
|
||||
assigned_right = df[(df.track == right_trackid)]
|
||||
unassigned = df[(df.track != left_trackid) & (df.track != right_trackid)]
|
||||
print(len(assigned_left), len(assigned_right), len(unassigned))
|
||||
columns = ["frame", "track id"]
|
||||
self._unassignedmodel = QStandardItemModel(len(unassigned), 2)
|
||||
self._unassignedmodel.setHorizontalHeaderLabels(columns)
|
||||
self._leftmodel = QStandardItemModel(len(assigned_left), 2)
|
||||
self._leftmodel.setHorizontalHeaderLabels(columns)
|
||||
self._rightmodel = QStandardItemModel(len(assigned_right), 2)
|
||||
self._rightmodel.setHorizontalHeaderLabels(columns)
|
||||
|
||||
# Populate the models with data
|
||||
for i in range(len(unassigned)):
|
||||
row = unassigned.iloc[i]
|
||||
if i == 0: print(row)
|
||||
for j in range(len(columns)):
|
||||
item = QStandardItem(f"{i, j}")
|
||||
self._unassignedmodel.setItem(i, j, item)
|
||||
self._unassigned_table.setModel(self._unassignedmodel)
|
||||
|
||||
for i in range(len(assigned_left)):
|
||||
row = assigned_left.iloc[i]
|
||||
for j in range(len(columns)):
|
||||
item = QStandardItem(f"{i, j}")
|
||||
self._leftmodel.setItem(i, j, item)
|
||||
self._left_table.setModel(self._leftmodel)
|
||||
|
||||
for i in range(len(assigned_right)):
|
||||
row = assigned_right.iloc[i]
|
||||
for j in range(len(columns)):
|
||||
item = QStandardItem(f"{i, j}")
|
||||
self._rightmodel.setItem(i, j, item)
|
||||
self._right_table.setModel(self._rightmodel)
|
||||
|
||||
|
||||
def _on_dataOpenend(self, state):
|
||||
logging.info("Finished loading data with state %s", state)
|
||||
self._tasklabel.setText("")
|
||||
self._progress_bar.setRange(0, 100)
|
||||
self._progress_bar.setValue(0)
|
||||
if state and self._reader is not None:
|
||||
self._dataframe = self._reader.data
|
||||
self._timeline.setRange(np.max(self._dataframe.frame.values), self._windowspinner.value())
|
||||
self.populateTables()
|
||||
|
||||
def on_save(self):
|
||||
logging.debug("Save fixtracks results")
|
||||
|
||||
def on_back(self):
|
||||
logging.debug("Back button pressed!")
|
||||
self.back.emit()
|
||||
|
||||
def on_assignLeft(self):
|
||||
pass
|
||||
|
||||
def on_assignRight(self):
|
||||
pass
|
||||
|
||||
def on_windowChanged(self, value):
|
||||
self.populateTables()
|
||||
|
||||
def on_windowSizeChanged(self, value):
|
||||
self._timeline.setWindowWidth(value)
|
Loading…
Reference in New Issue
Block a user