[detectionpreview] nice and shiny
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import logging
|
||||
import pickle
|
||||
import pandas as pd
|
||||
from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QFileDialog, QProgressBar
|
||||
from PySide6.QtCore import QThreadPool
|
||||
from PySide6.QtGui import QImage
|
||||
|
||||
from fixtracks.widgets.mergepreview import MergePreview
|
||||
from fixtracks.utils.reader import PickleLoader
|
||||
@@ -24,16 +23,8 @@ class PreviewDialog(QDialog):
|
||||
self._opendataBtn = QPushButton("open data")
|
||||
self._opendataBtn.clicked.connect(self.on_openData)
|
||||
|
||||
self._openleftBtn = QPushButton("open left video")
|
||||
self._openleftBtn.clicked.connect(self.on_openleftVideo)
|
||||
|
||||
self._openrightBtn = QPushButton("open right video")
|
||||
self._openrightBtn.clicked.connect(self.on_openrightVideo)
|
||||
|
||||
btn_box = QHBoxLayout()
|
||||
btn_box.addWidget(self._opendataBtn)
|
||||
btn_box.addWidget(self._openleftBtn)
|
||||
btn_box.addWidget(self._openrightBtn)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addLayout(btn_box)
|
||||
@@ -43,9 +34,22 @@ class PreviewDialog(QDialog):
|
||||
self.setLayout(layout)
|
||||
|
||||
def on_openData(self):
|
||||
file_dialog = QFileDialog(self, "Select pickled DataFrame", "", "Pandas DataFrame (*.pkl)")
|
||||
infile = None
|
||||
imgfile = None
|
||||
|
||||
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.merge_preview.set_image(img)
|
||||
|
||||
file_dialog = QFileDialog(self, "Select pickled DataFrame", "", "Pandas DataFrame (*.pkl)")
|
||||
if file_dialog.exec():
|
||||
infile = file_dialog.selectedFiles()[0]
|
||||
if infile is not None:
|
||||
@@ -62,11 +66,6 @@ class PreviewDialog(QDialog):
|
||||
self.merge_preview.set_dataframe(self._df)
|
||||
self._reader = None
|
||||
|
||||
def on_openleftVideo(self):
|
||||
pass
|
||||
|
||||
def on_openrightVideo(self):
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -323,11 +323,11 @@ class MergeDetections(QWidget):
|
||||
|
||||
lrect = QRect(0, 0, left_cut, limg.height())
|
||||
rrect = QRect(right_cut, 0, rimg.width() - right_cut, rimg.height())
|
||||
imgsize = QSize(lrect.width() + rrect.width(), rrect.height())
|
||||
lselection = limg.copy(lrect)
|
||||
rselection = rimg.copy(rrect)\
|
||||
|
||||
rselection = rimg.copy(rrect)
|
||||
imgsize = QSize(lrect.width() + rrect.width(), rrect.height())
|
||||
img = QImage(imgsize, limg.format())
|
||||
|
||||
painter = QPainter(img)
|
||||
painter.drawImage(QPoint(0,0), lselection)
|
||||
painter.drawImage(QPoint(lrect.width(), 0), rselection)
|
||||
|
||||
@@ -3,6 +3,7 @@ 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.QtCore import Qt
|
||||
from PySide6.QtGui import QPixmap, QBrush, QColor
|
||||
|
||||
from fixtracks.utils.reader import ImageReader
|
||||
|
||||
@@ -13,20 +14,66 @@ class MergePreview(QWidget):
|
||||
super().__init__(parent)
|
||||
self._dataframe = None
|
||||
self._image = None
|
||||
self._pixmapitem = None
|
||||
self._frames = None
|
||||
self._keypoints = None
|
||||
self._scene = None
|
||||
self._view = QGraphicsView()
|
||||
self._view.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
self._brush = QBrush(QColor.fromString("red"))
|
||||
self._brush2 = QBrush(QColor.fromString("white"))
|
||||
|
||||
self._startSlider = QSlider(orientation=Qt.Orientation.Horizontal)
|
||||
self._stopSlider = QSlider(orientation=Qt.Orientation.Horizontal)
|
||||
self._startSlider.setTickPosition(QSlider.TickPosition.TicksBelow)
|
||||
self._startSlider.setRange(0, 100)
|
||||
self._stopSlider.setRange(0, 100)
|
||||
self._startSlider.setTickInterval(self._startSlider.maximum() // 10)
|
||||
self._startSlider.sliderReleased.connect(self._on_startSliderReleased)
|
||||
self._startSlider.valueChanged.connect(self._on_sliderChanged)
|
||||
|
||||
self._startSlider.valueChanged.connect(self._on_start_slider_changed)
|
||||
self._stopSlider.valueChanged.connect(self._on_stop_slider_changed)
|
||||
self._stopSlider = QSlider(orientation=Qt.Orientation.Horizontal)
|
||||
self._stopSlider.setTickPosition(QSlider.TickPosition.TicksBelow)
|
||||
self._stopSlider.setRange(0, 100)
|
||||
self._stopSlider.setTickInterval(self._stopSlider.maximum() // 10)
|
||||
self._stopSlider.sliderReleased.connect(self._on_stopSliderReleased)
|
||||
self._stopSlider.valueChanged.connect(self._on_sliderChanged)
|
||||
|
||||
self._keypointCombo = QComboBox()
|
||||
self._keypointCombo.currentIndexChanged.connect(self._on_keypointSelection)
|
||||
|
||||
self._numpointsSpinner = QSpinBox()
|
||||
self._numpointsSpinner.setRange(500, 50000)
|
||||
self._numpointsSpinner.setValue(25000)
|
||||
self._numpointsSpinner.setSingleStep(500)
|
||||
self._numpointsSpinner.valueChanged.connect(self.update)
|
||||
settingsbox = QHBoxLayout()
|
||||
settingsbox.addWidget(QLabel("Select keypoint"))
|
||||
settingsbox.addWidget(self._keypointCombo)
|
||||
settingsbox.addWidget(QLabel("Number of displayed points"))
|
||||
settingsbox.addWidget(self._numpointsSpinner)
|
||||
|
||||
startsliderbox = QHBoxLayout()
|
||||
startsliderbox.addWidget(QLabel("Start position"))
|
||||
startsliderbox.addWidget(self._startSlider)
|
||||
|
||||
stopsliderbox = QHBoxLayout()
|
||||
stopsliderbox.addWidget(QLabel("Stop position"))
|
||||
stopsliderbox.addWidget(self._stopSlider)
|
||||
|
||||
self._startLabel = QLabel("0")
|
||||
self._stopLabel = QLabel("100")
|
||||
messagebox = QHBoxLayout()
|
||||
messagebox.addWidget(QLabel("Current segment from frame:"))
|
||||
messagebox.addWidget(self._startLabel)
|
||||
messagebox.addWidget(QLabel("to"))
|
||||
messagebox.addWidget(self._stopLabel)
|
||||
messagebox.addSpacerItem(QSpacerItem(100, 10, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed))
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(QLabel("Start Slider"))
|
||||
layout.addWidget(self._startSlider)
|
||||
layout.addWidget(QLabel("Stop Slider"))
|
||||
layout.addWidget(self._stopSlider)
|
||||
layout.addWidget(self._view)
|
||||
layout.addLayout(settingsbox)
|
||||
layout.addLayout(startsliderbox)
|
||||
layout.addLayout(stopsliderbox)
|
||||
layout.addLayout(messagebox)
|
||||
self.setLayout(layout)
|
||||
|
||||
def resetSlider(self, framecount=100):
|
||||
@@ -34,20 +81,78 @@ class MergePreview(QWidget):
|
||||
self._stopSlider.setRange(0, framecount)
|
||||
self._startSlider.setSliderPosition(0)
|
||||
self._stopSlider.setSliderPosition(framecount)
|
||||
self._startSlider.setTickInterval(self._startSlider.maximum() // 10)
|
||||
self._stopSlider.setTickInterval(self._stopSlider.maximum() // 10)
|
||||
|
||||
def resetKeypointcombo(self, numkeypoints):
|
||||
self._keypointCombo.clear()
|
||||
self._keypointCombo.addItems([f"keypoint {i}" for i in range(numkeypoints)])
|
||||
|
||||
def set_dataframe(self, newdf):
|
||||
self._dataframe = newdf
|
||||
self._frames = self._dataframe.frame.values
|
||||
self._keypoints = self._dataframe.keypoints.values
|
||||
self.resetSlider(np.max(self._dataframe.frame))
|
||||
self.resetKeypointcombo(len(self._keypoints[0]))
|
||||
self.update()
|
||||
|
||||
def _on_start_slider_changed(self, value):
|
||||
def _on_keypointSelection(self):
|
||||
self.update()
|
||||
|
||||
def _on_startSliderReleased(self):
|
||||
value = self._startSlider.value()
|
||||
if value > self._stopSlider.value():
|
||||
self._stopSlider.setValue(value)
|
||||
self.update()
|
||||
|
||||
def _on_stop_slider_changed(self, value):
|
||||
def _on_stopSliderReleased(self):
|
||||
value = self._stopSlider.value()
|
||||
if value < self._startSlider.value():
|
||||
self._startSlider.setValue(value)
|
||||
self.update()
|
||||
|
||||
@staticmethod
|
||||
def mergeImages(left, right, left_cut, right_cut):
|
||||
def _on_sliderChanged(self, value):
|
||||
self._startLabel.setText(str(self._startSlider.value()))
|
||||
self._stopLabel.setText(str(self._stopSlider.value()))
|
||||
|
||||
pass
|
||||
def set_image(self, img):
|
||||
self._image = img
|
||||
self.update()
|
||||
|
||||
def _draw_detections(self):
|
||||
start_frame = self._startSlider.value()
|
||||
stop_frame = self._stopSlider.value()
|
||||
selection = self._keypoints[self._frames[(self._frames >= start_frame) & (self._frames < stop_frame)]]
|
||||
image_rect = self._pixmapitem.boundingRect()
|
||||
keypoint = self._keypointCombo.currentIndex()
|
||||
num_points = self._numpointsSpinner.value()
|
||||
step = 1 if len(selection) < num_points else int(len(selection) // num_points)
|
||||
for coords in selection[::step]:
|
||||
x = coords[keypoint, 0]
|
||||
y = coords[keypoint, 1]
|
||||
self._scene.addEllipse(image_rect.left() + x, image_rect.top() + y, 10, 10, brush=self._brush)
|
||||
|
||||
def update(self):
|
||||
if self._image is not None:
|
||||
self._scene = QGraphicsScene()
|
||||
self._pixmapitem = self._scene.addPixmap(QPixmap.fromImage(self._image))
|
||||
self._view.setScene(self._scene)
|
||||
self._view.fitInView(self._scene.sceneRect(), aspectRadioMode=Qt.AspectRatioMode.KeepAspectRatio)
|
||||
self._view.show()
|
||||
if self._dataframe is not None:
|
||||
self._scene = QGraphicsScene()
|
||||
self._pixmapitem = self._scene.addPixmap(QPixmap.fromImage(self._image))
|
||||
self._view.setScene(self._scene)
|
||||
self._view.fitInView(self._scene.sceneRect(), aspectRadioMode=Qt.AspectRatioMode.KeepAspectRatio)
|
||||
self._view.show()
|
||||
self._draw_detections()
|
||||
|
||||
def fit_image_to_view(self):
|
||||
"""Scale the image to fit the QGraphicsView."""
|
||||
if self._pixmapitem is not None:
|
||||
self._view.fitInView(self._pixmapitem, Qt.KeepAspectRatio)
|
||||
|
||||
def resizeEvent(self, event):
|
||||
"""Handle window resizing to fit the image."""
|
||||
super().resizeEvent(event)
|
||||
self.fit_image_to_view()
|
||||
Reference in New Issue
Block a user