add graphics scale

add rfmat dec
This commit is contained in:
flandre 2025-04-13 22:58:17 +08:00
parent 74ce48c7a4
commit c0be9b687e
6 changed files with 228 additions and 30 deletions

View File

@ -1,7 +1,10 @@
import sys import sys
import time
import cv2
import numpy as np
from PyQt6.QtCore import QByteArray, Qt from PyQt6.QtCore import QByteArray, Qt
from PyQt6.QtGui import QImage, QPixmap, QKeyEvent from PyQt6.QtGui import QImage, QPixmap, QKeyEvent, QWheelEvent
from PyQt6.QtWidgets import QMainWindow, QApplication, QGraphicsPixmapItem, QGraphicsScene from PyQt6.QtWidgets import QMainWindow, QApplication, QGraphicsPixmapItem, QGraphicsScene
from flandre.config import C from flandre.config import C
@ -9,6 +12,7 @@ from flandre.nodes.Node import Node
from flandre.pyqt.Image import Ui_MainWindow from flandre.pyqt.Image import Ui_MainWindow
from flandre.pyqt.ZMQReceiver import ZMQReceiver from flandre.pyqt.ZMQReceiver import ZMQReceiver
from flandre.utils.Msg import KillMsg, Msg, BMMsg, RfMatMsg, KeyPressMsg from flandre.utils.Msg import KillMsg, Msg, BMMsg, RfMatMsg, KeyPressMsg
from flandre.utils.RfMat import RfMat
class Adv(QMainWindow, Ui_MainWindow): class Adv(QMainWindow, Ui_MainWindow):
@ -23,9 +27,11 @@ class Adv(QMainWindow, Ui_MainWindow):
self.s = QGraphicsScene() self.s = QGraphicsScene()
self.s.addItem(self.g) self.s.addItem(self.g)
self.graphicsView.setScene(self.s) self.graphicsView.setScene(self.s)
self.grey = True self.grey = False
self.scale = False self.scale = False
self.watermark = True self.watermark = True
self.zoom = 1.0
self.need_fit = False
def keyPressEvent(self, a0: QKeyEvent): def keyPressEvent(self, a0: QKeyEvent):
t = a0.text() t = a0.text()
@ -34,42 +40,58 @@ class Adv(QMainWindow, Ui_MainWindow):
self.grey = not self.grey self.grey = not self.grey
case 's': case 's':
self.scale = not self.scale self.scale = not self.scale
if not self.scale:
self.need_fit = True
case 't': case 't':
self.watermark = not self.watermark self.watermark = not self.watermark
def wheelEvent(self, a0: QWheelEvent):
if a0.angleDelta().y() > 0:
self.zoom += 0.1
if a0.angleDelta().y() < 0:
self.zoom -= 0.1
def on_zmq_event(self, msg: QByteArray): def on_zmq_event(self, msg: QByteArray):
t0 = time.time()
msg = Msg.decode_msg(msg.data()) msg = Msg.decode_msg(msg.data())
t1 = time.time()
print(t1 - t0)
if isinstance(msg, KillMsg): if isinstance(msg, KillMsg):
if msg.name == '': if msg.name == '':
self.close() self.close()
elif isinstance(msg, RfMatMsg): elif isinstance(msg, RfMatMsg):
w = msg.rfmat.m.shape[1] w = msg.rfmat.w
h = msg.rfmat.m.shape[0] h = msg.rfmat.h
d: RfMat = msg.rfmat
d2 = (d
.pseudo_color(cond=not self.grey)
.grey(cond=self.grey)
.resize((int(w * self.zoom), int(h * self.zoom)))
.watermark(cond=self.watermark)
)
w = d2.w
h = d2.h
if self.grey: if self.grey:
d2 = msg.rfmat.grey()
if self.watermark:
d2 = d2.watermark()
qImg = QImage( qImg = QImage(
d2.__bytes__(), d2.__bytes__(),
w, h, w, w, h, w,
QImage.Format.Format_Grayscale8 QImage.Format.Format_Grayscale8
) )
else: else:
d2 = msg.rfmat.pseudo_color()
if self.watermark:
d2 = d2.watermark()
qImg = QImage( qImg = QImage(
d2.__bytes__(), d2.__bytes__(),
w, h, 3 * w, w, h, 3 * w,
QImage.Format.Format_BGR888 QImage.Format.Format_BGR888
) )
self.g.setPixmap(QPixmap(qImg)) self.g.setPixmap(QPixmap(qImg))
self.s.setSceneRect(0.0, 0.0, w, h) self.s.setSceneRect(0.0, 0.0, w, h)
if self.scale: if self.scale:
self.graphicsView.fitInView(self.s.sceneRect()) self.graphicsView.fitInView(self.s.sceneRect())
else: else:
if self.need_fit:
self.graphicsView.fitInView(self.s.sceneRect(), Qt.AspectRatioMode.KeepAspectRatio) self.graphicsView.fitInView(self.s.sceneRect(), Qt.AspectRatioMode.KeepAspectRatio)
self.need_fit = False
class ImageQt(Node): class ImageQt(Node):

View File

@ -17,7 +17,7 @@ class Ui_MainWindow(object):
self.centralwidget.setObjectName("centralwidget") self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout") self.gridLayout.setObjectName("gridLayout")
self.graphicsView = QtWidgets.QGraphicsView(parent=self.centralwidget) self.graphicsView = MyGraphicsView(parent=self.centralwidget)
self.graphicsView.setDragMode(QtWidgets.QGraphicsView.DragMode.ScrollHandDrag) self.graphicsView.setDragMode(QtWidgets.QGraphicsView.DragMode.ScrollHandDrag)
self.graphicsView.setResizeAnchor(QtWidgets.QGraphicsView.ViewportAnchor.AnchorUnderMouse) self.graphicsView.setResizeAnchor(QtWidgets.QGraphicsView.ViewportAnchor.AnchorUnderMouse)
self.graphicsView.setObjectName("graphicsView") self.graphicsView.setObjectName("graphicsView")
@ -37,3 +37,4 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow): def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
from flandre.pyqt.MyGraphicsView import MyGraphicsView

View File

@ -16,7 +16,7 @@
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0"> <item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView"> <widget class="MyGraphicsView" name="graphicsView">
<property name="dragMode"> <property name="dragMode">
<enum>QGraphicsView::DragMode::ScrollHandDrag</enum> <enum>QGraphicsView::DragMode::ScrollHandDrag</enum>
</property> </property>
@ -39,6 +39,13 @@
</widget> </widget>
<widget class="QStatusBar" name="statusbar"/> <widget class="QStatusBar" name="statusbar"/>
</widget> </widget>
<customwidgets>
<customwidget>
<class>MyGraphicsView</class>
<extends>QGraphicsView</extends>
<header>flandre.pyqt.MyGraphicsView.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@ -0,0 +1,10 @@
from PyQt6.QtWidgets import *
class MyGraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
def wheelEvent(self, event):
event.ignore()
pass

View File

@ -1,3 +1,5 @@
import inspect
import cupyx import cupyx
import cv2 import cv2
import matplotlib import matplotlib
@ -18,19 +20,108 @@ from flandre.utils.RfFile import RfFrame, RfSequenceMeta
from flandre.utils.RfMeta import RfFrameMeta from flandre.utils.RfMeta import RfFrameMeta
def hsv_to_rgb(hsv):
"""
Convert HSV values to RGB.
Parameters
----------
hsv : (..., 3) array-like
All values assumed to be in range [0, 1]
Returns
-------
(..., 3) `~numpy.ndarray`
Colors converted to RGB values in range [0, 1]
"""
hsv = np.asarray(hsv)
# check length of the last dimension, should be _some_ sort of rgb
if hsv.shape[-1] != 3:
raise ValueError("Last dimension of input array must be 3; "
f"shape {hsv.shape} was found.")
in_shape = hsv.shape
hsv = np.array(
hsv, copy=False,
dtype=np.promote_types(hsv.dtype, np.float32), # Don't work on ints.
ndmin=2, # In case input was 1D.
)
h = hsv[..., 0]
s = hsv[..., 1]
v = hsv[..., 2]
r = np.empty_like(h)
g = np.empty_like(h)
b = np.empty_like(h)
i = (h * 6.0).astype(int)
f = (h * 6.0) - i
p = v * (1.0 - s)
q = v * (1.0 - s * f)
t = v * (1.0 - s * (1.0 - f))
idx = i % 6 == 0
r[idx] = v[idx]
g[idx] = t[idx]
b[idx] = p[idx]
# #
idx = i == 1
r[idx] = q[idx]
g[idx] = v[idx]
b[idx] = p[idx]
#
idx = i == 2
r[idx] = p[idx]
g[idx] = v[idx]
b[idx] = t[idx]
idx = i == 3
r[idx] = p[idx]
g[idx] = q[idx]
b[idx] = v[idx]
idx = i == 4
r[idx] = t[idx]
g[idx] = p[idx]
b[idx] = v[idx]
idx = i == 5
r[idx] = v[idx]
g[idx] = p[idx]
b[idx] = q[idx]
idx = s == 0
r[idx] = v[idx]
g[idx] = v[idx]
b[idx] = v[idx]
rgb = np.stack([r, g, b], axis=-1)
return rgb.reshape(in_shape)
def bypass(f): def bypass(f):
def wrapper(self, *args, **kwargs): def wrapper(self, *args, **kwargs):
if 'bypass' not in kwargs: if 'cond' not in kwargs:
return f(self, *args, **kwargs)
if kwargs['cond']:
del kwargs['cond']
return f(self, *args, **kwargs) return f(self, *args, **kwargs)
if kwargs['bypass']:
return self
else: else:
del kwargs['bypass'] return self
return f(self, *args, **kwargs)
return wrapper return wrapper
def bypassClass(original_class):
for name, f in inspect.getmembers(original_class, inspect.isfunction):
setattr(original_class, name, bypass(f))
return original_class
@bypassClass
class RfMat: class RfMat:
def __init__(self, def __init__(self,
data: cp.ndarray, data: cp.ndarray,
@ -64,6 +155,14 @@ class RfMat:
def duration(self): def duration(self):
return self.m.shape[1] return self.m.shape[1]
@property
def w(self):
return self.m.shape[1]
@property
def h(self):
return self.m.shape[0]
@property @property
def p(self): def p(self):
if self.device == 'cpu': if self.device == 'cpu':
@ -98,9 +197,9 @@ class RfMat:
v = p.zeros_like(h) + 1 v = p.zeros_like(h) + 1
hsv = p.stack((h, s, v), axis=2) hsv = p.stack((h, s, v), axis=2)
if p == cp: if p == cp:
rgb = matplotlib.colors.hsv_to_rgb(hsv.get()) rgb = hsv_to_rgb(hsv.get())
else: else:
rgb = matplotlib.colors.hsv_to_rgb(hsv) rgb = hsv_to_rgb(hsv)
return self.copy((rgb * 255).astype(np.uint8)) return self.copy((rgb * 255).astype(np.uint8))
def cpu(self): def cpu(self):
@ -125,12 +224,19 @@ class RfMat:
line1 = self.frame_meta.name line1 = self.frame_meta.name
if self.seq_meta is not None: if self.seq_meta is not None:
line2 = self.seq_meta.name line2 = self.seq_meta.name
if canvas.shape.__len__() == 2:
color1 = (255,)
color2 = (128,)
elif canvas.shape[2] == 3:
color1 = (255, 255, 255)
color2 = (128, 128, 128)
else:
raise NotImplementedError()
cv2.putText(canvas, line1, (0, 60), cv2.FONT_HERSHEY_PLAIN, 4, color1, 8)
cv2.putText(canvas, line1, (0, 60), cv2.FONT_HERSHEY_PLAIN, 4, color2, 4)
cv2.putText(canvas, line1, (0, 60), cv2.FONT_HERSHEY_PLAIN, 4, (255,), 8) cv2.putText(canvas, line2, (0, 120), cv2.FONT_HERSHEY_PLAIN, 4, color1, 8)
cv2.putText(canvas, line1, (0, 60), cv2.FONT_HERSHEY_PLAIN, 4, (128,), 4) cv2.putText(canvas, line2, (0, 120), cv2.FONT_HERSHEY_PLAIN, 4, color2, 4)
cv2.putText(canvas, line2, (0, 120), cv2.FONT_HERSHEY_PLAIN, 4, (255,), 8)
cv2.putText(canvas, line2, (0, 120), cv2.FONT_HERSHEY_PLAIN, 4, (128,), 4)
if canvas.shape.__len__() == 2: if canvas.shape.__len__() == 2:
ccp.m[canvas == 255] = 255 ccp.m[canvas == 255] = 255
@ -159,7 +265,6 @@ class RfMat:
print(self.seq_meta) print(self.seq_meta)
return self return self
@bypass
def resize(self, shape): def resize(self, shape):
if self.device == 'cpu': if self.device == 'cpu':
return self.copy(cv2.resize(self.m, shape)) return self.copy(cv2.resize(self.m, shape))

View File

@ -16,12 +16,63 @@ class ASD:
def b(self): def b(self):
return self.aaa return self.aaa
class EE(Enum): class EE(Enum):
asd = ASD asd = ASD
x = 1 x = 1
def skip1(f):
def wrapper(self, *args, **kwargs):
if 'cond' not in kwargs:
return f(self, *args, **kwargs)
if kwargs['cond']:
del kwargs['cond']
return f(self, *args, **kwargs)
else:
return self
return wrapper
def skip(original_class):
def f2(self, x):
print(x)
for name, f in inspect.getmembers(original_class, inspect.isfunction):
print(name, f)
setattr(original_class, name, skip1(f))
return original_class
class Decorator(object):
def __init__(self, arg):
self.arg = arg
def __call__(self, cls):
pass
# def wrappedClass(*args):
# return cls(*args)
#
# return type("TestClass", (cls,), dict(newMethod=self.newMethod, classattr=self.arg))
def newMethod(self, value):
return value * 2
@skip
class DC:
def __init__(self):
pass
def f1(self, arg):
print('f1', arg)
def f2(self, arg):
print('f2', arg)
if __name__ == '__main__': if __name__ == '__main__':
print(sys.argv) # print(sys.argv)
# print(dir(ASD())) # print(dir(ASD()))
# print(ASD.__dict__) # print(ASD.__dict__)
# print(inspect.getmembers(ASD)) # print(inspect.getmembers(ASD))
@ -46,4 +97,6 @@ if __name__ == '__main__':
# print(3) # print(3)
# case _: # case _:
# print(2) # print(2)
print() dc = DC()
dc.f1(11,cond=False)
dc.f2(22)