conan/uiwidget/widgetpose.py

148 lines
5.9 KiB
Python

import numpy as np
import pyqtgraph as pg
from PyQt5 import QtWidgets, QtGui, QtCore
class WidgetPose(QtWidgets.QWidget):
video_label_signal = QtCore.pyqtSignal(list)
def __init__(self, parent=None):
super(WidgetPose, self).__init__(parent)
layout = QtWidgets.QGridLayout()
self.poseGraph = QtWidgets.QWidget()
self.measures = QtWidgets.QWidget()
self.measuresLayout = QtWidgets.QHBoxLayout()
# Setup Movement Graph Plot Widget
self.movementGraph = pg.PlotWidget()
self.movementGraph.setBackground('w')
self.movementGraph.setYRange(0, 400, padding=0)
self.movementGraph.getPlotItem().getAxis('bottom').setTickSpacing(minor=50, major=100)
self.movementGraph.getPlotItem().setTitle(title='Body Movement over Time')
self.movementPlots = []
layout.addWidget(self.movementGraph, 1, 0, 1, 1)
layout.addWidget(self.measures, 1, 1, 1, 1)
layout.setColumnStretch(0, 1)
layout.setColumnStretch(1, 1)
self.setLayout(layout)
self.colors = None
self.labels = dict()
@QtCore.pyqtSlot(list)
def onSelectedID(self, lst):
"""Change color of movement graph plot if ID should not be visible"""
for i, button in enumerate(lst):
if not button.isChecked():
self.movementPlots[i].setPen(None)
elif self.colors is not None:
color = tuple([int(a * 255) for a in self.colors[i]])
pen = pg.mkPen(color=color)
self.movementPlots[i].setPen(pen)
@QtCore.pyqtSlot(dict, list, int)
def updateMovementGraph(self, data, colors, numberIDs):
"""Plot ID specific movement data from processing class
data[id: (movements, frames)]
"""
# handle NaN https://github.com/pyqtgraph/pyqtgraph/issues/1057
# downgrade to 5.13 fixes the issue
for id_no in range(numberIDs):
if data.get(id_no):
if not np.all(np.isnan(data.get(id_no)[0])):
self.movementPlots[id_no].setData(data.get(id_no)[1], data.get(id_no)[0]) # Update the data.
self.movementGraph.setXRange(np.min(data.get(id_no)[1]), np.max(data.get(id_no)[1]))
@QtCore.pyqtSlot(dict, int)
def updateHandVelocity(self, data, numberIDs):
"""Update Velocity Label
data[id: velocity for frame]"""
for id_no in range(numberIDs):
if data.get(id_no) is not None:
self.labels['Velocity'][id_no].setText('%.2f' % data[id_no])
else:
self.labels['Velocity'][id_no].setText(' ')
@QtCore.pyqtSlot(list, int)
def initMovementGraph(self, colors, numberIDs):
"""Initialize plot lines with 0
colors: plot color for each ID
"""
for i in range(numberIDs):
x = list(range(-200, 0)) # 100 time points
y = [0 for _ in range(200)] # 100 data points
color = tuple([int(a * 255) for a in colors[i]])
pen = pg.mkPen(color=color)
dataLine = self.movementGraph.plot(x, y, pen=pen)
self.movementPlots.append(dataLine)
@QtCore.pyqtSlot(dict, dict, list, int)
def setInit(self, mostActivity, hand, colors, numberIDs):
self.colors = colors
idLayout = QtWidgets.QVBoxLayout()
labelID = QtWidgets.QLabel(' ')
labelID.setFixedWidth(60)
labelID.setFixedHeight(20)
label = QtWidgets.QLabel('Most body activity in frame: ')
labelA = QtWidgets.QLabel('Hands above table (relative): ')
labelG = QtWidgets.QLabel('Gestures (relative): ')
labelVel = QtWidgets.QLabel('Hand velocity: ')
idLayout.addWidget(labelID)
idLayout.addWidget(label)
idLayout.addWidget(labelA)
idLayout.addWidget(labelG)
idLayout.addWidget(labelVel)
self.measuresLayout.insertLayout(-1, idLayout)
activityLabel = []
aboveLabel = []
gestureLabel = []
velLabel = []
for id_no in range(numberIDs):
idLayout = QtWidgets.QVBoxLayout()
[total, tracked, high_vel] = hand.get(id_no)
color = tuple([int(a * 255) for a in colors[id_no]])
labelID = QtWidgets.QLabel('ID%i' % id_no)
labelID.setStyleSheet('font: bold 12px; color: black; background-color: rgb(%i,%i,%i)' % color)
labelID.setFixedWidth(60)
labelID.setFixedHeight(20)
label = QtWidgets.QLabel('%i' % mostActivity.get(id_no))
activityLabel.append(label)
labelG = QtWidgets.QLabel('%.2f' % (high_vel / total))
gestureLabel.append(labelG)
labelA = QtWidgets.QLabel('%.2f' % (tracked / total))
aboveLabel.append(labelA)
labelVel = QtWidgets.QLabel(' ')
velLabel.append(labelVel)
idLayout.addWidget(labelID)
idLayout.addWidget(label)
idLayout.addWidget(labelA)
idLayout.addWidget(labelG)
idLayout.addWidget(labelVel)
self.measuresLayout.insertLayout(-1, idLayout)
# Velocity will be updated each frame, rest is updated in _updateLabels
self.labels['Velocity'] = velLabel
self.labels['Above'] = aboveLabel
self.labels['Gesture'] = gestureLabel
self.labels['Activity'] = activityLabel
self.measures.setLayout(self.measuresLayout)
@QtCore.pyqtSlot(dict, dict, int)
def updateLables(self, mostActivity, hand, numberIDs):
""" Update above hands, gestures and most activity labels when segment was changed"""
for id_no in range(numberIDs):
[total, tracked, high_vel] = hand[id_no]
self.labels['Activity'][id_no].setText('%i' % mostActivity[id_no])
self.labels['Above'][id_no].setText('%.2f' % (tracked / total))
self.labels['Gesture'][id_no].setText('%.2f' % (high_vel / total))