[skeletong] with slider

This commit is contained in:
Jan Grewe 2025-02-05 09:20:54 +01:00
parent f8e3b34fd4
commit c740d1b65d

View File

@ -1,10 +1,10 @@
import logging
import numpy as np
from PySide6.QtWidgets import QWidget, QVBoxLayout, QSizePolicy, QGraphicsView
from PySide6.QtWidgets import QWidget, QVBoxLayout, QSizePolicy, QGraphicsView, QSlider, QPushButton
from PySide6.QtWidgets import QGraphicsScene, QGraphicsEllipseItem, QGraphicsRectItem, QGraphicsLineItem
from PySide6.QtCore import Qt, QPointF, QRectF, QPointF
from PySide6.QtGui import QPixmap, QBrush, QColor, QImage, QPen
from PySide6.QtGui import QPixmap, QBrush, QColor, QImage, QPen, QPainter
class Skeleton(QGraphicsRectItem):
@ -12,26 +12,27 @@ class Skeleton(QGraphicsRectItem):
def __init__(self, x, y, width, height, keypoint_coordinates, brush):
super().__init__(x, y, width, height)
b = QBrush(QColor(255,255,255,64))
p = QPen(brush.color())
markersize = 5
p.setWidth(1)
p.setStyle(Qt.PenStyle.SolidLine)
self.setBrush(b)
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] - x - markersize/2
ky = kc[1] - y - markersize/2
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] - x # grid start x
gsy = keypoint_coordinates[sg[0], 1] - y
gex = keypoint_coordinates[sg[1], 0] - x
gey = keypoint_coordinates[sg[1], 1] - y
l = QGraphicsLineItem(gsx, gsy, gex, gey, self)
p.color().setAlpha(255/(i+1))
l.setPen(p)
# self.setBrush(brush)
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)
@ -44,37 +45,81 @@ class Skeleton(QGraphicsRectItem):
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._img = None
self._slider = QSlider(Qt.Orientation.Horizontal)
self._slider.sliderMoved.connect(self.on_sliderMoved)
self._btn = QPushButton("clear")
self._btn.clicked.connect(self.clear)
self._scene = QGraphicsScene()
# self.setRenderHint(QGraphicsView.RenderFlag.Ren Antialiasing)
self._skeletons = []
self._current_skeleton = None
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)
lyt.addWidget(self._btn)
self.setLayout(lyt)
def addSkeleton(self, coords, id, brush):
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, id)
self._scene.addItem(item)
item.setData(0, detection_id)
self._skeletons.append(item)
if update:
self.update()
def addSkeletons(self, coordinates:np.array, detection_ids:np.array, brush:QBrush):
def addSkeletons(self, coordinates, detection_ids, brush):
num_detections = coordinates.shape[0]
for i in range(num_detections):
c = brush.color()
c.setAlpha(int(i * 255 / num_detections))
brush.setColor(c)
self.addSkeleton(coordinates[i,:,:], detection_ids[i], brush=brush)
logging.debug("DetectionView: Number of items in scene: %i", len(self._scene.items()))
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():
@ -104,14 +149,14 @@ def main():
window = QWidget()
window.setMinimumSize(200, 200)
layout = QVBoxLayout()
view = SkeletonWidget()
# view.signals.itemsSelected.connect(items_selected)
layout.addWidget(view)
# view.addSkeleton(focus_coords[10,:,:], focus_ids[10], focus_brush)
count = 20
count = 100
view.addSkeletons(focus_coords[:count,:,:], focus_ids[:count], focus_brush)
view.addSkeletons(scnd_coords[:count,:,:], scnd_ids[:count], second_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)