169 lines
6.5 KiB
Python
169 lines
6.5 KiB
Python
import logging
|
|
import numpy as np
|
|
|
|
from PySide6.QtWidgets import QWidget, QVBoxLayout, QSizePolicy, QGraphicsView, QSlider, QPushButton
|
|
from PySide6.QtWidgets import QGraphicsScene, QGraphicsEllipseItem, QGraphicsRectItem, QGraphicsLineItem
|
|
from PySide6.QtCore import Qt
|
|
from PySide6.QtGui import QBrush, QColor, QPen, QPainter
|
|
|
|
|
|
class Skeleton(QGraphicsRectItem):
|
|
skeleton_grid = [(0, 1), (1, 2), (1, 3), (1, 4), (2, 5)]
|
|
|
|
def __init__(self, x, y, width, height, keypoint_coordinates, brush):
|
|
super().__init__(x, y, width, height)
|
|
skeleton_pen = QPen(brush.color())
|
|
skeleton_pen.setWidthF(1.0)
|
|
skeleton_marker = 5
|
|
bg_brush = QBrush(QColor(127,127,127,32))
|
|
bg_pen = QPen(QColor(127, 127, 127, 255))
|
|
bg_pen.setWidth(0.5)
|
|
bg_pen.setStyle(Qt.PenStyle.DashDotLine)
|
|
self.setBrush(bg_brush)
|
|
self.setPen(bg_pen)
|
|
for i, kc in enumerate(keypoint_coordinates):
|
|
kx = kc[0] - skeleton_marker/2
|
|
ky = kc[1] - skeleton_marker/2
|
|
kp = QGraphicsEllipseItem(kx, ky, 5, 5, self)
|
|
kp.setBrush(brush)
|
|
for i, sg in enumerate(self.skeleton_grid):
|
|
gsx = keypoint_coordinates[sg[0], 0] # grid start x
|
|
gsy = keypoint_coordinates[sg[0], 1]
|
|
gex = keypoint_coordinates[sg[1], 0]
|
|
gey = keypoint_coordinates[sg[1], 1]
|
|
QGraphicsLineItem(gsx, gsy, gex, gey, self)
|
|
|
|
# self.setAcceptHoverEvents(True) # Enable hover events if needed
|
|
self.setFlags(QGraphicsRectItem.ItemIsSelectable)
|
|
|
|
# def mousePressEvent(self, event):
|
|
# self.signals.clicked.emit(self.data(0), QPointF(event.scenePos().x(), event.scenePos().y()))
|
|
|
|
# def hoverEnterEvent(self, event):
|
|
# self.signals.hover.emit(self.data(0), QPointF(event.scenePos().x(), event.scenePos().y()))
|
|
# super().hoverEnterEvent(event)
|
|
|
|
|
|
class SkeletonWidget(QWidget):
|
|
#FIXME May be more efficient to set hide and show skeletons instead of adding and removing them when moving the slider
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self._skeletons = []
|
|
self._current_skeleton = None
|
|
self._slider = QSlider(Qt.Orientation.Horizontal)
|
|
self._slider.sliderMoved.connect(self.on_sliderMoved)
|
|
self._scene = QGraphicsScene()
|
|
self._view = QGraphicsView()
|
|
self._view.setRenderHint(QPainter.Antialiasing)
|
|
self._view.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
|
self._view.setMouseTracking(True)
|
|
self._view.setScene(self._scene)
|
|
|
|
lyt = QVBoxLayout()
|
|
lyt.addWidget(self._view)
|
|
lyt.addWidget(self._slider)
|
|
self.setLayout(lyt)
|
|
|
|
def clear(self):
|
|
for i in range(len(self._skeletons)):
|
|
item = self._skeletons.pop()
|
|
if item.scene() == self._scene:
|
|
self._scene.removeItem(item)
|
|
del item
|
|
self._skeletons = []
|
|
self.update()
|
|
|
|
def on_sliderMoved(self):
|
|
if self._current_skeleton is not None and self._current_skeleton.scene() == self._scene:
|
|
self._scene.removeItem(self._current_skeleton)
|
|
if self._slider.value() < len(self._skeletons):
|
|
self._current_skeleton = self._skeletons[self._slider.value()]
|
|
self._scene.addItem(self._current_skeleton)
|
|
|
|
def update(self):
|
|
if len(self._skeletons) > 0:
|
|
self._scene.addItem(self._skeletons[-1])
|
|
self._current_skeleton = self._skeletons[-1]
|
|
self._slider.setMaximum(len(self._skeletons))
|
|
self._slider.setMinimum(0)
|
|
self._slider.setValue(len(self._skeletons))
|
|
if len(self._skeletons) == 0:
|
|
self._slider.setEnabled(False)
|
|
|
|
def addSkeleton(self, coords, detection_id, brush, update=True):
|
|
boxx = np.min(coords[:,0])
|
|
boxy = np.min(coords[:,1])
|
|
boxw = np.max(coords[:, 0]) - boxx
|
|
boxh = np.max(coords[:, 1]) - boxy
|
|
item = Skeleton(boxx, boxy, boxw, boxh, coords, brush)
|
|
item.setData(0, detection_id)
|
|
self._skeletons.append(item)
|
|
if update:
|
|
self.update()
|
|
|
|
def addSkeletons(self, coordinates, detection_ids, brush):
|
|
num_detections = coordinates.shape[0]
|
|
for i in range(num_detections):
|
|
self.addSkeleton(coordinates[i,:,:], detection_ids[i], brush=brush, update=False)
|
|
self.update()
|
|
|
|
# def addSkeleton(self, coords, detection_id, brush):
|
|
# item = self.createSkeleton(coords, detection_id, brush)
|
|
# self._skeletons.append(item)
|
|
# self._scene.addItem(item)
|
|
|
|
# def addSkeletons(self, coordinates:np.array, detection_ids:np.array, brush:QBrush):
|
|
# skeletons = self.createSkeletons(coordinates, detection_ids, brush)
|
|
# self._skeletons.extend(skeletons)
|
|
# for s in skeletons:
|
|
# self._scene.addItem(s)
|
|
|
|
|
|
def main():
|
|
import pickle
|
|
import numpy as np
|
|
from IPython import embed
|
|
from PySide6.QtWidgets import QApplication
|
|
from fixtracks.info import PACKAGE_ROOT
|
|
|
|
datafile = PACKAGE_ROOT / "data/merged_small.pkl"
|
|
print(datafile)
|
|
with open(datafile, "rb") as f:
|
|
df = pickle.load(f)
|
|
|
|
focus_brush = QBrush(QColor.fromString("red"))
|
|
second_brush = QBrush(QColor.fromString("blue"))
|
|
|
|
scnd_coords = np.stack(df.keypoints[(df.track == 2)].values,).astype(np.float32)[:,:,:]
|
|
scnd_tracks = df.track[df.track == 2].values
|
|
scnd_ids = df.track[(df.track == 2)].index.values
|
|
|
|
focus_coords = np.stack(df.keypoints[df.track == 1].values,).astype(np.float32)[:,:,:]
|
|
focus_tracks = df.track[df.track == 1].values
|
|
focus_ids = df.track[(df.track == 2)].index.values
|
|
|
|
app = QApplication([])
|
|
window = QWidget()
|
|
window.setMinimumSize(200, 200)
|
|
layout = QVBoxLayout()
|
|
|
|
view = SkeletonWidget()
|
|
# view.signals.itemsSelected.connect(items_selected)
|
|
layout.addWidget(view)
|
|
btn = QPushButton("clear")
|
|
btn.clicked.connect(view.clear)
|
|
layout.addWidget(btn)
|
|
# view.addSkeleton(focus_coords[10,:,:], focus_ids[10], focus_brush)
|
|
count = 100
|
|
view.addSkeletons(focus_coords[:count,:,:], focus_ids[:count], focus_brush)
|
|
# view.addSkeletons(scnd_coords[:count,:,:], scnd_ids[:count], second_brush)
|
|
|
|
# view.addSkeletons(focus_coords[:10,:,:], focus_ids[:10], focus_brush)
|
|
# view.addDetections(focus_coords, focus_tracks, focus_ids, focus_brush)
|
|
# view.addDetections(scnd_coords, scnd_tracks, scnd_ids, second_brush)
|
|
window.setLayout(layout)
|
|
window.show()
|
|
app.exec()
|
|
|
|
if __name__ == "__main__":
|
|
main() |