Wed 28 Aug 21:38:52 CEST 2024
This commit is contained in:
parent
4178db6b67
commit
b3caa51c05
251
src/SimNDT/graphics/graphicView.py
Normal file
251
src/SimNDT/graphics/graphicView.py
Normal file
|
@ -0,0 +1,251 @@
|
|||
from PySide.QtCore import *
|
||||
from PySide.QtGui import *
|
||||
import SimNDT.gui.HelperMethods as HelperMethods
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.cm as cm
|
||||
|
||||
jet = cm.jet(range(0,256))
|
||||
r,g,b,a = jet[:,0], jet[:,1], jet[:,2],jet[:,3]
|
||||
cmap_jet = [QColor(r_*255, g_*255, b_*255).rgb() for r_,g_,b_ in zip(r,g,b)]
|
||||
|
||||
jet = cm.gray(range(0,256))
|
||||
r,g,b,a = jet[:,0], jet[:,1], jet[:,2],jet[:,3]
|
||||
cmap_gray = [QColor(r_*255, g_*255, b_*255).rgb() for r_,g_,b_ in zip(r,g,b)]
|
||||
|
||||
|
||||
def mapValue(data,in_min,in_max,out_min,out_max):
|
||||
return (data-in_min)*(out_max-out_min)/(in_max-in_min) + out_min
|
||||
|
||||
def array2qimage(data, vmin = 0.0, vmax = 255.0, cmap=cmap_jet):
|
||||
"""Convert the 2D numpy array `gray` into a 8-bit QImage with a gray
|
||||
colormap. The first dimension represents the vertical image axis.
|
||||
|
||||
Note
|
||||
----
|
||||
Main Idea taken from http://kogs-www.informatik.uni-hamburg.de/~meine/software/vigraqt/qimage2ndarray.py
|
||||
http://pointsofsail.org/displaying-a-2-d-numpy-array-in-pyside/
|
||||
|
||||
ATTENTION: This QImage carries an attribute `ndimage` with a
|
||||
reference to the underlying numpy array that holds the data. On
|
||||
Windows, the conversion into a QPixmap does not copy the data, so
|
||||
that you have to take care that the QImage does not get garbage
|
||||
collected (otherwise PyQt/PySide will throw away the wrapper, effectively
|
||||
freeing the underlying memory - boom!).
|
||||
"""
|
||||
|
||||
im = data.copy()
|
||||
|
||||
if im.ptp()==0:
|
||||
im = np.uint8(im)
|
||||
else:
|
||||
im = np.uint8(mapValue(im,vmin,vmax, 0.0,255.0))
|
||||
|
||||
qimage = QImage(im.data, im.shape[1], im.shape[0], im.shape[1], QImage.Format_Indexed8)
|
||||
qimage.ndarray = im
|
||||
qimage.setColorTable(cmap)
|
||||
return qimage
|
||||
|
||||
|
||||
class RefreshZoom(QObject):
|
||||
zoomed = Signal(int)
|
||||
def __init__(self):
|
||||
QObject.__init__(self)
|
||||
|
||||
def zoom(self, value):
|
||||
self.zoomed.emit(value)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class GraphicView(QGraphicsView):
|
||||
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
super(GraphicView, self).__init__(*args, **kwargs)
|
||||
|
||||
self.parent = parent
|
||||
#self.setFrameStyle(QFrame.Sunken | QFrame.StyledPanel)
|
||||
self.setFrameStyle(QFrame.NoFrame)
|
||||
self.setViewportUpdateMode(QGraphicsView.MinimalViewportUpdate)
|
||||
self.setTransformationAnchor(QGraphicsView.AnchorViewCenter)
|
||||
#Aself.setRenderHint(QPainter.SmoothPixmapTransform)
|
||||
|
||||
self._zoom = 1
|
||||
self.refreshZoom = RefreshZoom()
|
||||
|
||||
self.scene = QGraphicsScene(0,0, 1000,1000)
|
||||
self.setScene(self.scene)
|
||||
|
||||
self.pixmapItem = None
|
||||
self.textItem = None
|
||||
self.colormapBarItem = None
|
||||
|
||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.customContextMenuRequested.connect(self.showContextMenu)
|
||||
|
||||
def showContextMenu(self, pos):
|
||||
menu = QMenu()
|
||||
HelperMethods.addActions(menu, self.parent.actionAdd_Ellipse)
|
||||
HelperMethods.addActions(menu, self.parent.actionAdd_Rectangle)
|
||||
menu.exec_(self.mapToGlobal(pos))
|
||||
|
||||
|
||||
def setupZoom(self, value):
|
||||
self.setZoom(value)
|
||||
|
||||
|
||||
def setZoom(self, value):
|
||||
self._zoom = 0.3*value/100.0
|
||||
scale = self._zoom/self.transform().m11()
|
||||
self.scale(scale, scale)
|
||||
|
||||
def getZoom(self):
|
||||
return self._zoom*100.0/0.3
|
||||
|
||||
|
||||
def wheelEvent(self, event):
|
||||
#angleDelta
|
||||
numSteps = event.delta() / 8.0 /15.0
|
||||
self.setZoom( self.getZoom() + numSteps )
|
||||
scale = self._zoom/self.transform().m11()
|
||||
self.scale(scale,scale)
|
||||
self.refreshZoom.zoom( int (self.getZoom() ))
|
||||
|
||||
|
||||
def imshow(self, I):
|
||||
|
||||
self.clearUpdate()
|
||||
qimage = array2qimage(I)
|
||||
|
||||
if self.pixmapItem is None:
|
||||
self.pixmapItem = self.scene.addPixmap(QPixmap.fromImage(qimage))
|
||||
self.pixmapItem.setFlags(QGraphicsItem.ItemIsMovable)
|
||||
|
||||
else:
|
||||
self.pixmapItem.setPixmap(QPixmap.fromImage(qimage))
|
||||
|
||||
|
||||
self.drawColormapBar()
|
||||
self.drawAxis()
|
||||
|
||||
qimage = None
|
||||
|
||||
pixmap = self.pixmapItem.pixmap()
|
||||
w, h = pixmap.width(), pixmap.height()
|
||||
self.scene.setSceneRect(0,0,w,h)
|
||||
|
||||
|
||||
def drawAxis(self):
|
||||
|
||||
line1 = QPolygonF()
|
||||
line1.append(QPointF(0,-10))
|
||||
line1.append(QPointF(0,60))
|
||||
line2 = QPolygonF()
|
||||
line2.append(QPointF(0,-10))
|
||||
line2.append(QPointF(60,-10))
|
||||
triangle1 = QPolygonF()
|
||||
triangle1.append(QPointF( 10,60))
|
||||
triangle1.append(QPointF(-10,60))
|
||||
triangle1.append(QPointF(0,65))
|
||||
triangle1.append(QPointF(10,60))
|
||||
triangle2 = QPolygonF()
|
||||
triangle2.append(QPointF( 60,-20))
|
||||
triangle2.append(QPointF( 60, 0))
|
||||
triangle2.append(QPointF(65,-10))
|
||||
triangle2.append(QPointF(60,-20))
|
||||
|
||||
path = QPainterPath()
|
||||
path.addPolygon(line1)
|
||||
path.addPolygon(line2)
|
||||
path.addPolygon(triangle1)
|
||||
path.addPolygon(triangle2)
|
||||
|
||||
pathItem = QGraphicsPathItem(self.pixmapItem)
|
||||
pathItem.setPath(path)
|
||||
pathItem.moveBy(-40,-40)
|
||||
|
||||
def drawColormapBar(self):
|
||||
|
||||
pixmap = self.pixmapItem.pixmap()
|
||||
w, h = pixmap.width(), pixmap.height()
|
||||
C = np.linspace(0,255, w, endpoint=True).astype(np.uint8)
|
||||
C = np.tile(C, (40, 1))
|
||||
Cqimage = array2qimage(C)
|
||||
|
||||
if self.colormapBarItem is None:
|
||||
self.colormapBarItem = QGraphicsPixmapItem(self.pixmapItem)
|
||||
self.colormapBarItem.setPixmap(QPixmap.fromImage(Cqimage))
|
||||
self.colormapBarItem.setPos(0,h+20)
|
||||
self.drawTicksColormapBar(w,h)
|
||||
|
||||
Cqimage = None
|
||||
|
||||
def drawTicksColormapBar(self, w, h):
|
||||
|
||||
font = QFont()
|
||||
font.setPixelSize(w/20)
|
||||
font.setBold(False)
|
||||
font.setFamily("Calibri")
|
||||
|
||||
values_text = [0,40,80,120,160,200,240]
|
||||
tick = [mapValue(i,0, 255, 0, w-15) for i in values_text]
|
||||
for item, pos in zip(values_text, tick):
|
||||
text = QGraphicsTextItem(self.pixmapItem)
|
||||
text.setPlainText("%s"%item)
|
||||
text.setFont(font)
|
||||
text.setPos(pos, h+60)
|
||||
|
||||
def clearUpdate(self):
|
||||
|
||||
self.scene.clear()
|
||||
self.viewport().update()
|
||||
self.pixmapItem = None
|
||||
self.textItem = None
|
||||
self.colormapBarItem = None
|
||||
|
||||
def setImage(self, I, DB=60):
|
||||
vmin, vmax = -DB, 0
|
||||
|
||||
self.clearUpdate()
|
||||
I[ I <-DB] = -DB
|
||||
|
||||
qimage = array2qimage(I, vmin = vmin, vmax = vmax, cmap=self.cmap)
|
||||
self.pixmapItem = self.scene.addPixmap(QPixmap.fromImage(qimage))
|
||||
#pixmap = self.pixmapItem.pixmap()
|
||||
#self.pixmapItem.setOffset(-pixmap.width()/2.0,-pixmap.height()/2.)
|
||||
self.pixmapItem.setGraphicsEffect(QGraphicsBlurEffect())
|
||||
self.pixmapItem.setFlags(QGraphicsItem.ItemIsMovable)
|
||||
qimage = None
|
||||
|
||||
|
||||
if self.textItem is None:
|
||||
pixmap = self.pixmapItem.pixmap()
|
||||
w = pixmap.width()
|
||||
font = QFont()
|
||||
font.setPixelSize(w/25)
|
||||
font.setBold(False)
|
||||
font.setFamily("Calibri")
|
||||
|
||||
self.textItem = QGraphicsTextItem(self.pixmapItem)
|
||||
self.textItem.setPlainText("time:")
|
||||
self.textItem.setPos(0,-(20+ w/25) )
|
||||
self.textItem.setFont(font)
|
||||
|
||||
|
||||
|
||||
def updateWithImage(self, I, time, DB=60):
|
||||
|
||||
vmin, vmax = -DB, 0
|
||||
I[ I <-DB] = -DB
|
||||
qimage = array2qimage(I, vmin = vmin, vmax = vmax, cmap=self.cmap)
|
||||
self.pixmapItem.setPixmap(QPixmap.fromImage(qimage))
|
||||
qimage = None
|
||||
self.textItem.setPlainText("time: %0.2f %ss"%(time,(956)) )
|
||||
|
||||
|
||||
def setColormap(self,value):
|
||||
if value == 0:
|
||||
self.cmap = cmap_jet
|
||||
elif value == 1:
|
||||
self.cmap = cmap_gray
|
Loading…
Reference in New Issue
Block a user