Package pyforms :: Package gui :: Package Controls :: Module ControlImage |
[hide private]
[frames] | no frames]

# Source Code for Module pyforms.gui.Controls.ControlImage

      1  #!/usr/bin/python
      2  # -*- coding: utf-8 -*-
      3
      4  __author__      = "Ricardo Ribeiro"
      5  __credits__     = ["Ricardo Ribeiro"]
      6  __license__     = "MIT"
      7  __version__     = "0.0"
      8  __maintainer__  = "Ricardo Ribeiro"
      9  __email__       = "ricardojvr@gmail.com"
     10  __status__      = "Development"
     11
     12
     13  from pyforms.gui.Controls.ControlBase import ControlBase
     14  import pyforms.Utils.tools as tools
     15  from PyQt4 import uic
     16  import cv2
     17
     18  try:
     19          import OpenGL.GL  as GL
     20          import OpenGL.GLU as GLU
     21          from PyQt4.QtOpenGL import QGLWidget
     22  except:
     23          print ("No OpenGL library available")
     24
     25
     26
     27 -class ImageGLWidget(QGLWidget):
     28
     29          _image2Display = None
     30          _texture = None          #: Opengl texture variable
     31          _zoom = 1.0
     32          _mouseX = 0.0
     33          _mouseY = 0.0
     34          _width = 1.0
     35          _height = 1.0
     36          _glX = 0.0
     37          _glY = 0.0
     38          _glZ = 0.0
     39          _x = 0.0
     40          _y = 0.0
     41          _lastGlX = 0.0
     42          _lastGlY = 0.0
     43          _mouseDown = False
     44          _mouseLeftDown = False
     45          _mouseRightDown = False
     46
     47 -        def __init__(self, parent=None):
     48                  QGLWidget.__init__(self, parent)
     49
     50                  self._image2Display = []
     51                  self._texture = []          #: Opengl texture variable
     52                  self._zoom = 1.0
     53                  self._mouseX = 0.0
     54                  self._mouseY = 0.0
     55                  self._width = 1.0
     56                  self._height = 1.0
     57                  self._glX = 0.0
     58                  self._glY = 0.0
     59                  self._glZ = 0.0
     60                  self._x = 0.0
     61                  self._y = 0.0
     62                  self._lastGlX = 0.0
     63                  self._lastGlY = 0.0
     64                  self._mouseDown = False
     65                  self._mouseLeftDown = False
     66                  self._mouseRightDown = False
     67
     68                  self._mouseStartDragPoint = None
     69
     70                  self.setMinimumHeight(100)
     71                  self.setMouseTracking(True)
     72
     73 -        def initializeGL(self):
     74                  GL.glClearDepth(1.0)
     75                  GL.glClearColor(0, 0, 0, 1.0)
     76                  GL.glEnable(GL.GL_DEPTH_TEST)
     77
     78 -        def resizeGL(self, width, height):
     79                  GL.glViewport(0, 0, width, height)
     80                  GL.glMatrixMode(GL.GL_PROJECTION)
     81                  GL.glLoadIdentity()
     82                  GLU.gluPerspective(40.0, float(width)/float(height), 0.01, 10.0)
     83
     84 -        def drawVideo(self, width, height, x , y, z):
     85                  GL.glPushMatrix()
     86                  GL.glTranslatef(x , y, z)
     87                  GL.glBegin(GL.GL_QUADS )
     88                  GL.glTexCoord2f( 0.0, 1.0 );
     89                  GL.glVertex3f( 0, 0, 0 );#top left
     90                  GL.glTexCoord2f( 0.0, 0.0 );
     91                  GL.glVertex3f( 0, height, 0 ); #bottom left
     92                  GL.glTexCoord2f( 1.0, 0.0 );
     93                  GL.glVertex3f( width, height, 0 );  #bottom right
     94                  GL.glTexCoord2f( 1.0, 1. );
     95                  GL.glVertex3f( width, 0, 0 ); #top right
     96                  GL.glEnd()
     97                  GL.glPopMatrix()
     98
     99 -        def paintGL(self):
    100                  GL.glClearColor(0.5, 0.5, 0.5, 1.0)
    101                  GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
    102                  GL.glMatrixMode(GL.GL_MODELVIEW)
    103                  GL.glLoadIdentity()
    104
    105                  translateX = ( len(self._texture) * self._width ) / 2
    106
    107                  if len(self._texture) > 0:
    108                          GL.glTranslatef( -translateX, -self._height/2, -self._zoom)
    109
    110                          GL.glDisable(GL.GL_TEXTURE_2D)
    111                          GL.glColor4f(0.5, 0.5, 0.5, 1.0)
    112                          GL.glBegin(GL.GL_QUADS)
    113                          GL.glVertex3f(20, -20, -.001)
    114                          GL.glVertex3f(20, 20, -.001)
    115                          GL.glVertex3f(-20, 20, -.001)
    116                          GL.glVertex3f(-20, -20, -.001)
    117                          GL.glEnd()
    118
    119                          GL.glColor4f(1, 1, 1, 1.0)
    120
    121                          GL.glEnable(GL.GL_TEXTURE_2D)
    122
    123                          for texture_index in range(0, len(self._texture) ):
    124                                  if texture_index>0: GL.glTranslatef( self._width,  0, 0)
    125
    126                                  GL.glBindTexture(GL.GL_TEXTURE_2D, self._texture[ texture_index ])
    127
    128                                  if self._mouseRightDown:
    129                                          self.drawVideo( self._width, self._height, self._x- (self._lastGlX - self._glX) , self._y - (self._lastGlY - self._glY), 0.0)
    130                                  else:
    131                                          self.drawVideo( self._width, self._height, self._x , self._y, 0.0)
    132
    133                          if self._mouseDown:
    134                                  modelview = GL.glGetDoublev( GL.GL_MODELVIEW_MATRIX )
    135                                  projection = GL.glGetDoublev( GL.GL_PROJECTION_MATRIX )
    136                                  viewport = GL.glGetIntegerv( GL.GL_VIEWPORT )
    137                                  winX = float(self._mouseX);
    138                                  winY = float(viewport[3] - self._mouseY)
    139                                  winZ = GL.glReadPixels(winX, winY, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT)
    140                                  self._glX, self._glY, self._glZ = GLU.gluUnProject( winX, winY, winZ[0][0], modelview, projection, viewport)
    141
    142
    143
    144 -        def reset(self):
    145                  self._texture = []
    146                  self._image2Display = []
    147
    148 -        def paint(self, frames):
    149                  if len(frames)==0: return
    150
    151                  if len(self._image2Display) == 0:
    152                          self.imgHeight, self.imgWidth = frames[0].shape[:2]
    153                          if self.imgWidth>self.imgHeight:
    154                                  self._width = 1
    155                                  self._height = float(self.imgHeight) / float(self.imgWidth)
    156                                  self._x = -float(self._width)/2
    157                                  self._y = 0
    158                          else:
    159                                  self._height = 1
    160                                  self._width = float(self.imgWidth) / float(self.imgHeight)
    161                                  self._y = 0.5
    162
    163                  #self._x = -self._width/2
    164
    165
    166                  if len(self._texture)>len(frames):
    167                          for i in range( len(self._texture)-len(frames) ):
    168                                  GL.glDeleteTextures( self._texture.pop() )
    169
    170                  self._image2Display = frames
    171
    172                  for index, frame in enumerate(frames):
    173                          if len(frame.shape)==2:
    174                                  color = GL.GL_LUMINANCE
    175                          else:
    176                                  color = GL.GL_BGR
    177
    178                          if len(self._texture)<len(self._image2Display): self._texture.append( GL.glGenTextures(1) )
    179
    180                          w = len(frame[0])
    181                          h = len(frame)
    182
    183                          GL.glEnable(GL.GL_TEXTURE_2D)
    184                          GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT,1)
    185                          GL.glBindTexture(GL.GL_TEXTURE_2D, self._texture[index])
    186                          GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_BORDER)
    187                          GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_BORDER)
    188                          GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
    189                          GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
    190                          GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, w, h, 0, color, GL.GL_UNSIGNED_BYTE, frame)
    191
    192                  self.repaint()
    193
    194
    195 -        def wheelEvent(self, event):
    196                  if event.delta()<0: self._zoom += 0.1
    197                  else: self._zoom -= 0.1
    198                  if self._zoom<0.01: self._zoom = 0.02
    199                  self.repaint()
    200
    201 -        def mouseReleaseEvent(self, event):
    202                  self._mouseDown = False
    203
    204                  if event.button()==2:
    205                          self._mouseRightDown = False
    206                          self._x -= self._lastGlX - self._glX
    207                          self._y -= self._lastGlY - self._glY
    208                          self._lastGlX = self._glX
    209                          self._lastGlY = self._glY
    210
    211                  if event.button()==1:
    212                          if self._mouseLeftDown:
    213                                  self.onEndDrag( self._mouseStartDragPoint, (self._glX - self._x, self._height-self._glY + self._y ) )
    214                          self._mouseLeftDown = False
    215
    216 -        def mousePressEvent(self, event):
    217                  QGLWidget.mousePressEvent(self, event)
    218                  self._mouseDown = True
    219                  self._mouseX = event.x()
    220                  self._mouseY = event.y()
    221                  self.repaint()
    222
    223                  if event.button()==1:
    224                          self._mouseLeftDown = True
    225                          self._mouseStartDragPoint = (self._glX  - self._x, self._height-self._glY + self._y )
    226
    227                  if event.button()==2:
    228                          self._mouseRightDown = True
    229                          self._lastGlX = self._glX
    230                          self._lastGlY = self._glY
    231
    232                  self.onPress(event.button(), (self._glX  - self._x, self._height-self._glY + self._y ) )
    233
    234 -        def mouseMoveEvent(self, event):
    235                  QGLWidget.mouseMoveEvent(self, event)
    236                  self._mouseX = event.x()
    237                  self._mouseY = event.y()
    238                  self.repaint()
    239                  self.onMove( (self._glX - self._x, self._height-self._glY + self._y ) )
    240
    241                  if self._mouseDown:
    242                          if self._mouseLeftDown:
    243                                  self.onDrag( self._mouseStartDragPoint, (self._glX - self._x, self._height-self._glY + self._y ) )
    244
    245 -        def onMove(self, point):
    246                  pass
    247
    248 -        def onPress(self, button, point):
    249                  pass
    250
    251 -        def onDrag(self, startPoint, endPoint):
    252                  pass
    253
    254 -        def onEndDrag(self, startPoint, endPoint):
    255                  pass
    256
    257
    258 -class ControlImage(ControlBase):
    259
    260          _imageWidget = None
    261
    262 -        def initForm(self):
    263                  control_path = tools.getFileInSameDirectory(__file__,"image.ui")
    264                  self._form = uic.loadUi( control_path )
    265                  self._imageWidget = ImageGLWidget()
    266                  self._form.imageLayout.addWidget( self._imageWidget )
    267
    268 -        def save(self, data):
    269                  if self.value!=None: data['value'] = self._value
    270
    271 -        def load(self, data):
    272                  if 'value' in data: self.value = data['value']
    273
    274 -        def repaint(self):
    275                  self._imageWidget.repaint()
    276
    277          @property
    278 -        def value(self): return ControlBase.value.fget(self)
    279
    280          @value.setter
    281 -        def value(self, value):
    282                  ControlBase.value.fset(self, value)
    283                  if isinstance(value, str):
    284                          self._value = cv2.imread(value, 1)
    285                  else:
    286                          self._value = value
    287
    288                  if isinstance(self._value, list) or isinstance(self._value, tuple):
    289                          self._imageWidget.paint( self._value )
    290                  else:
    291                          self._imageWidget.paint( [self._value] )
    292
    293
    294                  self._imageWidget.repaint()
    295