Пример #1
0
def test_Vector_interface():
    """Test various aspects of the Vector API."""
    v = pg.Vector(-1, 2)

    # len
    assert len(v) == 3

    # indexing
    assert v[0] == -1
    assert v[2] == 0
    with pytest.raises(IndexError):
        x = v[4]

    assert v[1] == 2
    v[1] = 5
    assert v[1] == 5

    # iteration
    v2 = pg.Vector(*v)
    assert v2 == v

    assert abs(v).x() == 1

    # angle
    v1 = pg.Vector(1, 0)
    v2 = pg.Vector(1, 1)
    assert abs(v1.angle(v2) - 45) < 0.001
Пример #2
0
    def plot3d(self, dim = "z", point_size=1, cmap='Spectral_r', max_points=5e5, n_bin=8, plot_trees=False):
        """
        Plots the three dimensional point cloud using a `Qt` backend. By default, if the point cloud exceeds 5e5 \
         points, then it is downsampled using a uniform random distribution. This is for performance purposes.

        :param point_size: The size of the rendered points.
        :param dim: The dimension upon which to color (i.e. "z", "intensity", etc.)
        :param cmap: The matplotlib color map used to color the height distribution.
        :param max_points: The maximum number of points to render.
        """
        from pyqtgraph.Qt import QtCore, QtGui
        import pyqtgraph as pg
        import pyqtgraph.opengl as gl

        # Randomly sample down if too large
        if dim == 'user_data' and plot_trees:
            dim = 'random_id'
            self._set_discrete_color(n_bin, self.data.points['user_data'])
            cmap = self._discrete_cmap(n_bin, base_cmap=cmap)

        if self.data.count > max_points:
                sample_mask = np.random.randint(self.data.count,
                                                size = int(max_points))
                coordinates = np.stack([self.data.points.x, self.data.points.y, self.data.points.z], axis = 1)[sample_mask,:]

                color_dim = np.copy(self.data.points[dim].iloc[sample_mask].values)
                print("Too many points, down sampling for 3d plot performance.")
        else:
            coordinates = np.stack([self.data.points.x, self.data.points.y, self.data.points.z], axis = 1)
            color_dim = np.copy(self.data.points[dim].values)

        # If dim is user data (probably TREE ID or some such thing) then we want a discrete colormap
        if dim != 'random_id':
            color_dim = (color_dim - np.min(color_dim)) / (np.max(color_dim) - np.min(color_dim))
            cmap = cm.get_cmap(cmap)
            colors = cmap(color_dim)

        else:
            colors = cmap(color_dim)

        # Start Qt app and widget
        pg.mkQApp()
        view = gl.GLViewWidget()


        # Create the points, change to opaque, set size to 1
        points = gl.GLScatterPlotItem(pos = coordinates, color = colors)
        points.setGLOptions('opaque')
        points.setData(size = np.repeat(point_size, len(coordinates)))

        # Add points to the viewer
        view.addItem(points)

        # Center on the arithmetic mean of the point cloud and display
        center = np.mean(coordinates, axis = 0)
        view.opts['center'] = pg.Vector(center[0], center[1], center[2])
        # Very ad-hoc
        view.opts['distance'] = (self.data.max[0] - self.data.min[0]) * 1.2
        #return(view.opts)
        view.show()
Пример #3
0
    def drawNewVehiclePosition(self, newPosition):
        """
		Handles update of the plane in the window, NEVER CALLED directly.

		:param newPosition: new position as a list
		"""
        # print(newPosition)
        # we simply create a new set of vertices

        rawPoints = self.vehicleDrawInstance.getNewPoints(*newPosition)
        # print(rawPoints)
        newVertices = numpy.array([[y * metersToPixelRatio for y in x]
                                   for x in rawPoints])
        # print(newVertices)
        self.vehicleMeshData.setVertexes(
            newVertices)  # update our mesh with them
        self.openGLVehicle.setMeshData(
            meshdata=self.vehicleMeshData, smooth=False, computeNormals=False
        )  # and setMeshData automatically invokes a redraw
        self.lastPlanePos = pyqtgraph.Vector(newPosition[1], newPosition[0],
                                             -newPosition[2])
        if self.trackPlane:
            self.openGLWindow.setCameraPosition(pos=self.lastPlanePos)
        if self.leavePlaneTrail:
            self.planeTrailPoints.append(
                [newPosition[1], newPosition[0], -newPosition[2]])
            hmm = numpy.array(self.planeTrailPoints)
            tempColor = numpy.array([[1., 0., 0., 1]])
            colors = numpy.tile(tempColor, (hmm.shape[0], 1))
            self.planeTrailLine.setData(pos=numpy.array(self.planeTrailPoints),
                                        color=colors)
        return
Пример #4
0
    def update(self):
        if(self.w.count >= len(self.cameras)):
            self.w.close()
            self.app.exit()
            return

        self.w.update()

        # get the camera
        cam = self.cameras[self.w.count]

        # set camera parameters
        self.w.opts["center"] = pg.Vector(cam["x"],cam["y"],cam["z"])
        self.w.opts["distance"] = cam["distance"]
        self.w.opts["elevation"] = cam["elevation"]
        self.w.opts["azimuth"] = cam["azimuth"]
        self.w.update()

        # get image from window
        im = self.convertQImageToMat(self.w.readQImage()).astype(np.uint64)
        im = im[:,:,:3] # get only the first 3 channels
        im[:,:,2] *= 256*256
        im[:,:,1] *= 256
        im = im.sum(axis=2)
        im -= 1 #we added 1 to handle the background

        # save the matrix
        np.savez(os.path.join(self.dir_images,"views", self.filename+("_%04d" % self.w.count)), im)
        self.w.count+=1
Пример #5
0
    def ManualButtonResponse(self):
        """
		Sets camera to manual mode
		"""
        self.trackPlane = False
        self.__setCameraModeButtons()
        self.openGLWindow.setCameraPosition(pos=pyqtgraph.Vector(0, 0, 0))
        return
Пример #6
0
 def _default__widget(self, parent=None):
     """ Create a GLViewWidget and add plot, grid, and orientation axes.
     
     """
     w = MyGLViewWidget(parent)
     self._grid = g = gl.GLGridItem()
     w.addItem(g)
     self._orientation_axes = ax = gl.GLAxisItem(size=pg.Vector(5, 5, 5))
     w.addItem(ax)
     w.addItem(self.plot._plot)
     w.sigUpdate.connect(self._update_model)
     for attr in ['azimuth', 'distance', 'fov', 'center', 'elevation']:
         w.opts[attr] = getattr(self, attr)
     return w
Пример #7
0
def test_Vector_init():
    """Test construction of Vector objects from a variety of source types."""
    # separate values without z
    v = pg.Vector(0, 1)
    assert v.z() == 0

    v = pg.Vector(0.0, 1.0)
    assert v.z() == 0

    # separate values with 3 args
    v = pg.Vector(0, 1, 2)
    assert v.x() == 0
    assert v.y() == 1
    assert v.z() == 2
    v = pg.Vector(0.0, 1.0, 2.0)
    assert v.x() == 0
    assert v.y() == 1
    assert v.z() == 2

    # all in a list
    v = pg.Vector([0, 1])
    assert v.z() == 0
    v = pg.Vector([0, 1, 2])

    # QSizeF
    v = pg.Vector(QtCore.QSizeF(1, 2))
    assert v.x() == 1
    assert v.z() == 0

    # QPoint
    v = pg.Vector(QtCore.QPoint(0, 1))
    assert v.z() == 0
    v = pg.Vector(QtCore.QPointF(0, 1))
    assert v.z() == 0

    # QVector3D
    qv = QtGui.QVector3D(1, 2, 3)
    v = pg.Vector(qv)
    assert v == qv

    with pytest.raises(Exception):
        v = pg.Vector(1, 2, 3, 4)
Пример #8
0
    def __init__(self, parent=None):
        super(brainView, self).__init__(parent)

        HVC_L_file = resource_path("zfbrain/data/HVC_L.surf")
        HVC_R_file = resource_path("zfbrain/data/HVC_R.surf")
        RA_L_file = resource_path("zfbrain/data/RA_L.surf")
        RA_R_file = resource_path("zfbrain/data/RA_R.surf")
        X_L_file = resource_path("zfbrain/data/AreaX_L.surf")
        X_R_file = resource_path("zfbrain/data/AreaX_R.surf")
        brain_L_file = resource_path("zfbrain/data/whole_brain_L.surf")
        brain_R_file = resource_path("zfbrain/data/whole_brain_R.surf")

        verts_HVC_L, faces_HVC_L = sp.read_surface(HVC_L_file)
        verts_HVC_R, faces_HVC_R = sp.read_surface(HVC_R_file)
        verts_RA_L, faces_RA_L = sp.read_surface(RA_L_file)
        verts_RA_R, faces_RA_R = sp.read_surface(RA_R_file)
        verts_X_L, faces_X_L = sp.read_surface(X_L_file)
        verts_X_R, faces_X_R = sp.read_surface(X_R_file)
        verts_brain_L, faces_brain_L = sp.read_surface(brain_L_file)
        verts_brain_R, faces_brain_R = sp.read_surface(brain_R_file)

        self.hvc_L = gl.GLMeshItem(vertexes=verts_HVC_L,
                                   faces=faces_HVC_L,
                                   color=(1, 0, 0, 0.2),
                                   smooth=True,
                                   drawEdges=False,
                                   shader='balloon',
                                   glOptions='additive')

        self.hvc_R = gl.GLMeshItem(vertexes=verts_HVC_R,
                                   faces=faces_HVC_R,
                                   color=(0.5, 0.5, 0, 0.2),
                                   smooth=True,
                                   drawEdges=False,
                                   shader='balloon',
                                   glOptions='additive')

        self.ra_L = gl.GLMeshItem(vertexes=verts_RA_L,
                                  faces=faces_RA_L,
                                  color=(0, 1, 0, 0.2),
                                  smooth=True,
                                  drawEdges=False,
                                  shader='balloon',
                                  glOptions='additive')

        self.ra_R = gl.GLMeshItem(vertexes=verts_RA_R,
                                  faces=faces_RA_R,
                                  color=(0.5, 1, 0.5, 0.2),
                                  smooth=True,
                                  drawEdges=False,
                                  shader='balloon',
                                  glOptions='additive')

        self.areaX_L = gl.GLMeshItem(vertexes=verts_X_L,
                                     faces=faces_X_L,
                                     color=(0, 0.5, 0.5, 0.2),
                                     smooth=True,
                                     drawEdges=False,
                                     shader='balloon',
                                     glOptions='additive')

        self.areaX_R = gl.GLMeshItem(vertexes=verts_X_R,
                                     faces=faces_X_R,
                                     color=(1, 0.5, 1, 0.2),
                                     smooth=True,
                                     drawEdges=False,
                                     shader='balloon',
                                     glOptions='additive')

        self.outer_L = gl.GLMeshItem(vertexes=verts_brain_L,
                                     faces=faces_brain_L,
                                     color=(200 / 255, 100 / 255, 100 / 255,
                                            0.5),
                                     drawEdges=False,
                                     drawFaces=True,
                                     shader='shaded',
                                     glOptions='opaque')

        self.outer_R = gl.GLMeshItem(vertexes=verts_brain_R,
                                     faces=faces_brain_R,
                                     color=(200 / 255, 100 / 255, 100 / 255,
                                            0.5),
                                     drawEdges=False,
                                     drawFaces=True,
                                     shader='shaded',
                                     glOptions='opaque')

        self.addItem(self.outer_L)
        self.addItem(self.outer_R)
        self.addItem(self.hvc_L)
        self.addItem(self.hvc_R)
        self.addItem(self.ra_L)
        self.addItem(self.ra_R)
        self.addItem(self.areaX_L)
        self.addItem(self.areaX_R)

        self.setBackgroundColor(50, 50, 50)

        # choose center of whole-brain
        x_center = np.average(
            np.concatenate((verts_brain_L[:, 0], verts_brain_R[:, 0])))
        y_center = np.average(
            np.concatenate((verts_brain_L[:, 1], verts_brain_R[:, 1])))
        z_center = np.average(
            np.concatenate((verts_brain_L[:, 2], verts_brain_R[:, 2])))

        # set camera settings
        # sets center of rotation for field
        new_center = np.array([x_center, y_center, z_center])
        self.opts['center'] = pg.Vector(new_center)
        self.setCameraPosition(distance=2400, elevation=20, azimuth=50)
Пример #9
0
 def getTranslation(self):
     return pg.Vector(self._state['pos'])
Пример #10
0
 def getRotation(self):
     """Return (angle, axis) of rotation"""
     return self._state['angle'], pg.Vector(self._state['axis'])
Пример #11
0
 def getScale(self):
     return pg.Vector(self._state['scale'])
Пример #12
0
def track3D(state):
    '''
    描绘目标状态的3d轨迹
    :param state: 【np.array】目标的状态
    :return:
    '''
    app = QtGui.QApplication([])
    w = gl.GLViewWidget()
    # w.setWindowTitle('3d trajectory')
    w.resize(600, 500)
    # instance of Custom3DAxis
    axis = Custom3DAxis(w, color=(0.6, 0.6, 0.2, .6))
    w.addItem(axis)
    w.opts['distance'] = 75
    w.opts['center'] = pg.Vector(0, 0, 0)
    # add xy grid
    gx = gl.GLGridItem()
    gx.setSize(x=40, y=40, z=10)
    gx.setSpacing(x=5, y=5)
    w.addItem(gx)
    # trajectory line
    pos0 = np.array([[0, 0, 0]])
    pos, q = np.array(state[:3]), state[3:7]
    uAxis, angle = q2ua(q)
    track0 = np.concatenate((pos0, pos.reshape(1, 3)))
    plt = gl.GLLinePlotItem(pos=track0, width=2, color=(1, 0, 0, 0.6))
    w.addItem(plt)
    # orientation arrow
    sphereData = gl.MeshData.sphere(rows=20, cols=20, radius=0.6)
    sphereMesh = gl.GLMeshItem(meshdata=sphereData,
                               smooth=True,
                               shader='shaded',
                               glOptions='opaque')
    w.addItem(sphereMesh)
    ArrowData = gl.MeshData.cylinder(rows=20,
                                     cols=20,
                                     radius=[0.5, 0],
                                     length=1.5)
    ArrowMesh = gl.GLMeshItem(meshdata=ArrowData,
                              smooth=True,
                              color=(1, 0, 0, 0.6),
                              shader='balloon',
                              glOptions='opaque')
    ArrowMesh.rotate(angle, uAxis[0], uAxis[1], uAxis[2])
    w.addItem(ArrowMesh)
    w.setWindowTitle('position={}cm'.format(np.round(pos * 100, 1)))
    w.show()

    i = 1
    pts = pos.reshape(1, 3)

    def update():
        '''update position and orientation'''
        nonlocal i, pts, state
        pos, q = np.array(state[:3]) * 100, state[3:7]
        uAxis, angle = q2ua(q)
        pt = (pos).reshape(1, 3)
        if pts.size < 150:
            pts = np.concatenate((pts, pt))
        else:
            pts = np.concatenate((pts[-50:, :], pt))
        plt.setData(pos=pts)
        ArrowMesh.resetTransform()
        sphereMesh.resetTransform()
        ArrowMesh.rotate(angle, uAxis[0], uAxis[1], uAxis[2])
        ArrowMesh.translate(*pos)
        sphereMesh.translate(*pos)
        w.setWindowTitle('position={}cm'.format(np.round(pos, 1)))
        i += 1

    timer = QtCore.QTimer()
    timer.timeout.connect(update)
    timer.start(50)

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
Пример #13
0
    def __init__(self, parent=None):
        """
		sets up the full window with the plane along with a row of camera controls
		"""
        super().__init__(parent)

        self.usedLayout = QtWidgets.QVBoxLayout()
        self.setLayout(self.usedLayout)
        self.trackPlane = True
        self.leavePlaneTrail = True

        self.lastPlanePos = pyqtgraph.Vector(0, 0, 0)

        # we will always have the openGLBase Widget
        self.openGLWindow = pyqtgraph.opengl.GLViewWidget()
        self.usedLayout.addWidget(self.openGLWindow)

        # a random grid, will likely be changed afterwards
        self.openGLWindow.setGeometry(0, 0, 1000, 1000)
        self.grid = pyqtgraph.opengl.GLGridItem()
        self.grid.scale(200, 200, 200)
        self.grid.setSize(2000, 2000, 2000)
        self.openGLWindow.addItem(self.grid)

        # and an arbitrary camera starting position
        self.openGLWindow.setCameraPosition(distance=defaultZoom,
                                            elevation=defaultElevation,
                                            azimuth=defaultAzimuth)

        # a copy of the vehicle, we assume we will always want a vehicle
        self.vehicleDrawInstance = VehicleGeometry.VehicleGeometry()

        # we need to grab the vertices for the vehicle each update
        rawPoints = [[
            y * metersToPixelRatio for y in x
        ] for x in self.vehicleDrawInstance.getNewPoints(0, 0, 0, 0, 0, 0)]
        newVertices = numpy.array(rawPoints)

        # faces and colors only need to be done once
        newFaces = numpy.array(self.vehicleDrawInstance.faces)
        newColors = numpy.array(self.vehicleDrawInstance.colors)

        # we convert the vertices to meshdata which allows us not to have to translate points every time
        self.vehicleMeshData = pyqtgraph.opengl.MeshData(vertexes=newVertices,
                                                         faces=newFaces,
                                                         faceColors=newColors)

        # and we create the meshItem, we do not smooth to make the triangles be clean colors
        self.openGLVehicle = pyqtgraph.opengl.GLMeshItem(
            meshdata=self.vehicleMeshData,
            drawEdges=True,
            smooth=False,
            computeNormals=False)

        # always add the vehicle to the display
        self.openGLWindow.addItem(self.openGLVehicle)

        # and add an axis

        self.Axis = pyqtgraph.opengl.GLAxisItem(glOptions='additive')
        self.Axis.setSize(2000, 2000, 2000)
        self.openGLWindow.addItem(self.Axis)
        self.updateVehiclePositionSignal.connect(self.drawNewVehiclePosition)

        #  we are going to add a line for tracking the plane here, if not on it does nothing
        self.planeTrailLine = pyqtgraph.opengl.GLLinePlotItem()
        # self.planeTrailLine.setData(color=PyQt5.QtGui.QColor("red"), width=2)
        self.planeTrailLine.setData(color=(1, 0, 0, 1), width=1)
        self.openGLWindow.addItem(self.planeTrailLine)
        self.planeTrailLine.mode = 'line_strip'
        self.planeTrailPoints = list()

        self.aribtraryLines = list()
        # #  and another line for supposed paths and the like
        # self.arbitraryLine = pyqtgraph.opengl.GLLinePlotItem()
        # # self.arbitraryLine.setData(color=PyQt5.QtGui.QColor("blue"), width=1)
        # self.arbitraryLine.setData(color=(0, 0, 1, .5), width=1)
        # self.arbitraryLine.mode = 'line_strip'
        # self.openGLWindow.addItem(self.arbitraryLine)
        # self.arbitraryLinePoints = list()

        # self.setAribtraryLine(testLine)
        # self.setAribtraryLine([[0,0,0],[10,10, 0]])
        # self.clearAribtraryLine()
        # we add another hbox for camera controls

        cameraControlBox = QtWidgets.QHBoxLayout()
        self.usedLayout.addLayout(cameraControlBox)

        zoomInButton = QtWidgets.QPushButton("Zoom In")
        zoomInButton.clicked.connect(self.ZoomIn)
        zoomOutButton = QtWidgets.QPushButton("Zoom Out")
        zoomOutButton.clicked.connect(self.ZoomOut)
        cameraControlBox.addWidget(zoomInButton)
        cameraControlBox.addWidget(zoomOutButton)

        self.trackButton = QtWidgets.QPushButton("Track")
        self.trackButton.clicked.connect(self.TrackButtonResponse)
        cameraControlBox.addWidget(self.trackButton)

        self.manualButton = QtWidgets.QPushButton("Manual")
        self.manualButton.clicked.connect(self.ManualButtonResponse)
        cameraControlBox.addWidget(self.manualButton)

        self.resetCameraButton = QtWidgets.QPushButton("Reset")
        self.resetCameraButton.clicked.connect(self.resetCameraView)
        cameraControlBox.addWidget(self.resetCameraButton)

        self.__setCameraModeButtons()
        # self.setAribtraryLine(testLine)
        # self.drawLine(testLine)
        # print(self.buildRandomPoints())
        # self.addAribtraryLine(self.buildRandomPoints())
        # self.addAribtraryLine(self.buildRandomPoints())
        # hmm = self.addAribtraryLine(self.buildRandomPoints())
        # self.removeAribtraryLine(hmm)
        # self.removeAllAribtraryLines()
        return
Пример #14
0
class Scatter3DScene(Atom):
    """ A Scatter3D Scene Manager.
    
    Maintains a scatter plot and its scene.
    
    """
    __slots__ = '__weakref__'
    
    #: Scatter3D Point manager
    plot = Typed(Scatter3DPlot, ())
    
    #: Camera FOV center 
    center = Value(pg.Vector(0, 0, 0)) 
    
    #: Distance of camera from center
    distance = Float(100.) 
    
    #: Horizontal field of view in degrees
    fov = Float(60.)   
    
    #: Camera's angle of elevation in degrees.
    elevation = Coerced(float, (30.,)) 
    
    #: Camera's azimuthal angle in degrees.
    azimuth = Float(45.)  
    
    #: MyGLViewWidget instance.
    _widget = Typed(MyGLViewWidget, ())
    
    #: GLGridItem instance
    _grid = Value()
    
    #: GLAxisItem instance.
    _orientation_axes = Value()
    
    #: Cyclic notification guard flags.
    _guard = Int(0)
    
    def _default__widget(self, parent=None):
        """ Create a GLViewWidget and add plot, grid, and orientation axes.
        
        """
        w = MyGLViewWidget(parent)
        self._grid = g = gl.GLGridItem()
        w.addItem(g)
        self._orientation_axes = ax = gl.GLAxisItem(size=pg.Vector(5, 5, 5))
        w.addItem(ax)
        w.addItem(self.plot._plot)
        w.sigUpdate.connect(self._update_model)
        for attr in ['azimuth', 'distance', 'fov', 'center', 'elevation']:
            w.opts[attr] = getattr(self, attr)
        return w
    
    def show(self, title=''):
        """ Show the view in a graphics window.
        """
        if not title:
            title = 'pyqtgraph Atom example: GLScatterPlotItem'
        app = pg.mkQApp()
        self._widget.show()
        app.exec_()
    
    def _observe_plot(self, change):
        """ Synchronize plot changing with the scene.
        
        """
        if change['type'] == 'create':
            return
        self._guard |= PLOT_CHANGE_FLAG
        self._widget.removeItem(change['oldvalue']._plot)
        self._widget.addItem(change['value']._plot)
        self._guard &= ~PLOT_CHANGE_FLAG
    
    @observe('azimuth', 'distance', 'fov', 'center', 'elevation')
    def _update_view(self, change):
        """ Synchronize model attributes to the view.
        
        """
        if self._guard & (VIEW_SYNC_FLAG) or change['type'] == 'create':
            return
        self._widget.opts[change['name']] = change['value']
        self._widget.update()
    
    def _update_model(self):
        """ Synchronize view attributes to the model.
        
        """
        if self._guard & PLOT_CHANGE_FLAG:
            return
        self._guard &= VIEW_SYNC_FLAG
        for (key, value) in self._widget.opts.items():
            setattr(self, key, value)
        self._guard &= ~VIEW_SYNC_FLAG