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