Exemple #1
0
    def gazePointsToHeatmaps(self):
        self.XYHeatmap = []
        self.XZHeatmap = []
        for sx in range(self.gaze_points.shape[2]):
            XYG = []
            XZG = []
            for f in range(self.gaze_points.shape[0]):
                d = self.gaze_points[f, :, sx]
                xyg = self.gaussian(mu=d[0], max=self.frame_size[0])
                xzg = self.gaussian(mu=d[1], max=self.frame_size[1])
                XYG.append(xyg)
                XZG.append(xzg)
            self.XYHeatmap.append(np.array(XYG))
            self.XZHeatmap.append(np.array(XZG))

        self.XYHeatmap = np.sum(self.XYHeatmap, 0)
        self.XZHeatmap = np.sum(self.XZHeatmap, 0)
        self.XYHeatmap = gl.GLImageItem(self.getColors(self.XYHeatmap, cm.jet))
        self.XZHeatmap = gl.GLImageItem(self.getColors(self.XZHeatmap, cm.jet))

        self.XYHeatmap.scale(self.image_spacing, 1, 1)
        self.XZHeatmap.scale(self.image_spacing, 1, 1)

        self.XYHeatmap.rotate(90, -1, 0, 0)
        self.XYHeatmap.translate(0, -50 * self.scaling_factor, 0)
        self.XZHeatmap.translate(
            0, 0, -self.frame_size[0] - 50 * self.scaling_factor)
Exemple #2
0
def mkTexture(w, img, T):
    W = img.shape[1]
    if img.shape[2] == 3:
        obj = gl.GLImageItem(data=img2tex(img.transpose(1, 0, 2)))
    else:
        obj = gl.GLImageItem(data=img2texA(img.transpose(1, 0, 2)))
    w.addItem(obj)
    S = scale((1 / W, 1 / W, 1))
    D = desp((0, 0, -DC))

    def update(H):
        transform(D @ H @ T @ S, obj)

    return update
Exemple #3
0
    def loadFrameByNumber(self,
                          number,
                          rotation=[90, 0, 1, 0],
                          x_shift=0,
                          y_shift=0,
                          option='translucent'):
        # list and sort all frames in folder
        frame_paths = sorted(listdir(self.image_path))
        frame_paths = [path.join(self.image_path, p) for p in frame_paths]
        if number >= len(frame_paths):
            return None
        frame = misc.imread(frame_paths[number])
        if not self.scaling_factor == 1.:
            frame = misc.imresize(frame, self.scaling_factor)
        if self.frame_size is None:
            self.frame_size = frame.shape[:2]
            self.z_shift = 0  #self.frame_size[0]
        # convert frame into RGBA image
        frame = pg.makeRGBA(frame, levels=[frame.min(), frame.max()])[0]
        frame = gl.GLImageItem(frame)
        frame.rotate(rotation[0], rotation[1], rotation[2], rotation[3])
        frame.translate(number * self.image_spacing + x_shift, y_shift,
                        self.z_shift)
        frame.setGLOptions(option)

        return frame
Exemple #4
0
    def _initialize_planes(self):
        """ Create the xy plane, the arbitrary cut plane and the view in the 
        selector panel.
        """
        # xy
        super()._initialize_planes()
        # selector
        xy = self.get_xy_slice(0)
        self.selector.set_image(xy, lut=self.lut)
        # cutline in selector
        if not hasattr(self, 'cutline'):
            self.cutline = Cutline(self.selector)
        self.cutline.initialize()
        # cut plane
        if hasattr(self, 'cutplane'):
            self.glview.removeItem(self.cutplane)
        cut, coords = self.get_cutline_cut()
        cut_texture = self.make_texture(cut)
        self.cutplane = gl.GLImageItem(cut_texture, glOptions=self.gloptions)

        # Scale and move to origin in upright position
        self.cutplane.scale(self.xscale, self.zscale, 1)
        self.cutplane.rotate(90, 1, 0, 0)
        self.cutplane.translate(T, 0, T)
        self.transform0 = self.cutplane.transform()

        self.glview.addItem(self.cutplane)
        self.cutline.sig_region_changed.connect(self.update_cut)
Exemple #5
0
def prepare_RA(w, size, fov, dist=20):
    WIDTH, HEIGHT = size
    # Ponemos el punto de vista de la visualización gráfica en el origen del sistema
    # de referencia, con elevación y azimuth de modo que el eje x apunte hacia la
    # derecha, el eje y hacia abajo y el eje z mirando hacia delante.
    # Es la posición "inicial" de una cámara en el origen.
    # (ponemos distancia > 0 que luego se compensa porque cero da problemas)
    setCameraPosition(w, distance=DC, elevation=-90, azimuth=-90, fov=fov)

    # Preparamos el objeto textura que contendrá la imagen de cámara en vivo. La vamos
    # a situar centrada delante del punto de vista del visor gráfico, a la distancia
    # justa para que ocupe toda la ventana, teniendo en cuenta el FOV. Es el fondo
    # de la escena, delante pondremos los objetos virtuales.
    W2 = WIDTH / 2
    d = dist
    s = (d + DC) / W2 * np.tan(np.radians(fov) / 2)
    camera_image = gl.GLImageItem(data=np.zeros([100, 100, 4]))
    transform(
        scale((s, s, 1)) @ desp((-WIDTH // 2, -HEIGHT // 2, d)), camera_image)
    w.addItem(camera_image)

    def update(frame):
        camera_image.setData(data=img2tex(frame.transpose(1, 0, 2)))

    return update
 def updateXY(self):
     try:
         self.w.removeItem(self.v3)
     except:
         pass
     tex3 = pg.makeRGBA(self.data[:,:,self.slice3], levels=self.levels)[0]   # xy plane
     self.v3 = gl.GLImageItem(tex3)
     self.v3.translate(-self.slice1, -self.slice2, 0)
     self.w.addItem(self.v3)
     return
 def updateXZ(self):
     try:
         self.w.removeItem(self.v2)
     except:
         pass
     tex2 = pg.makeRGBA(self.data[:,self.slice2], levels=self.levels)[0]     # xz plane
     self.v2 = gl.GLImageItem(tex2)
     self.v2.translate(-self.slice1, -self.slice3, 0)
     self.v2.rotate(-90, 1,0,0)
     self.w.addItem(self.v2)
     return
 def updateYZ(self):
     try:
         self.w.removeItem(self.v1)
     except:
         pass
     tex1 = pg.makeRGBA(self.data[self.slice1], levels=self.levels)[0]       # yz plane
     self.v1 = gl.GLImageItem(tex1)
     self.v1.translate(-self.slice2, -self.slice3, 0)
     self.v1.rotate(90, 0,0,1)
     self.v1.rotate(-90, 0,1,0)
     self.w.addItem(self.v1)
     return
Exemple #9
0
 def slice(self):
     if( len(self.mesh) == 0):
         self.message('Load mesh first!')
         return
 
     self.slices.clear()
     curdir = os.getcwd()        
     if(path.isdir("images")):
         #remove all files in images
         filelist = [ f for f in os.listdir("./images") if f.endswith(".png") ]            
         for f in filelist:
             os.remove(os.path.join(curdir+"/images", f))  
     else:
         os.mkdir("images")
     self.out_path = os.path.join(curdir, "images/slice-%d.png")
 
     self.message('Slicing mesh...')
 
     self.update_var()
     self.mesh_info.first_layer_thicknes = self.conf.get("first_layer_thickness")
     self.mesh_info.layer_thickness = self.conf.get("layer_thickness")
     nLayer = self.mesh_info.get_layers()
     z_list = self.mesh_info.get_z_list()
     str_layers = str(nLayer)
 
     x_pixel_size, y_pixel_size, x0, y0 = stl2pngfunc.stl2png(self.mesh_info.path, 
                                                                  z_list, 
                                                                  self.mesh_info.image_width, self.mesh_info.image_height, 
                                                                  self.out_path,
                                                                  self.mesh_info.border_size,
                                                                  func = lambda i: self.message("slicing layer " + str(i+1) + "/" + str_layers, False)
                             )
 
 
     self.mesh_info.real_pixel_size, self.mesh_info.real_pixel_size, self.gcode_minx, self.gcode_miny = x_pixel_size, y_pixel_size, x0, y0 
     self.message('Slicing mesh into ' + self.out_path)
     self.message(self.mesh_info.get_info() )
 
     im = cv2.imread(self.out_path % 0)
     tex1 = cv2.cvtColor(im, cv2.COLOR_BGR2RGBA) 
     v1 = gl.GLImageItem(tex1)
     v1.translate(0, 0, 0)        
     self.view_slice.addItem(v1)  
 
     # activate slider 
     self.sl.setMinimum(0)
     self.sl.setMaximum(self.mesh_info.get_layers() - 1)  
     self.sl.setValue(0)
     self.sl.setTickPosition(QSlider.TicksBelow)
     self.sl.setTickInterval(1) 
     self.sl.valueChanged.connect(self.show_slice)
     return
Exemple #10
0
 def show_slice(self):
     i = self.sl.value()
     self.message("Show slice {}.".format(i+1), False)
     curdir = os.getcwd()
     
     im = cv2.imread(self.out_path % i)
     #self.slices[i] = im
     tex1 = cv2.cvtColor(im, cv2.COLOR_BGR2RGBA) 
     v1 = gl.GLImageItem(tex1)
     
     v1.translate(0, 0, i * self.mesh_info.layer_thickness)        
     self.view_slice.items = []
     self.view_slice.addItem(v1)
 def updateXZ(self):
     try:
         self.w.removeItem(self.v2)
     except:
         pass
     tex2 = pg.makeRGBA(self.data[:,self.slice2], levels=self.levels)[0]     # xz plane
     self.v2 = gl.GLImageItem(tex2)
     #self.v2.translate(-self.slice1, -self.slice3, int(self.shape[1]/2)-self.slice2)
     self.v2.translate(-self.slice1, -self.slice3, -int(self.shape[1]/2)+self.slice2)        
     self.v2.rotate(-90, 1,0,0)
     #self.v2.scale(-1, 1, 1, local=False) #fliplr
     self.w.addItem(self.v2)
     return
Exemple #12
0
 def loadKeyFrames(self, key_frame_list, rotation=[90, 0, 1, 0], scale=.5):
     self.keyFrames = []
     for kf in key_frame_list:
         if kf >= len(self.frames) or kf < 0:
             print('key frame value not in list: {0}'.format(kf))
             continue
         data = self.frames[kf].data.copy()
         keyFrame = gl.GLImageItem(data)
         keyFrame.rotate(*rotation)
         keyFrame.scale(scale, scale, 1)
         keyFrame.translate(self.image_spacing * kf,
                            self.frame_size[1] * 1.15, 0)
         #-self.frame_size[0]*1.15)
         self.keyFrames.append(keyFrame)
Exemple #13
0
def img2glimage(img_path, gloptions):
    imgarr, sizex, sizey, xcols, yrows, midpt = image2array(img_path)
    v1 = gl.GLImageItem(imgarr)
    sx = sizex / xcols
    sy = sizey / yrows
    v1.scale(sx, sy, 0)

    dx = sizex / 2  #sizex/2
    dy = sizey / 2  #sizey/2
    v1.translate(-1 * dx, -1 * dy, 0)
    v1.rotate(180, 0, 1, 0)
    v1.rotate(180, 0, 0, 1)

    v1.translate(midpt[0], midpt[1], 0)
    v1.setGLOptions(gloptions)
    return v1
Exemple #14
0
    def fill(self):
        try:
            i = self.sl.value()
            self.message("Show slice {}.".format(i + 1), False)
            curdir = os.getcwd()
            filepath = self.out_path % i
            offset = self.conf.get("infill_offset")
            line_width = 1  # int(abs(offset)/2)
            pe = pathengine.pathEngine()
            pe.generate_contours_from_img(filepath, True)
            pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR)
            contour_tree = pe.convert_hiearchy_to_PyPolyTree()
            group_contour = pe.get_contours_from_each_connected_region(
                contour_tree, '0')

            # draw boundaries
            #################################
            # Generate N color list
            #################################
            def generate_RGB_list(N):
                import colorsys
                HSV_tuples = [(x * 1.0 / N, 0.8, 0.9) for x in range(N)]
                RGB_tuples = map(lambda x: colorsys.hsv_to_rgb(*x), HSV_tuples)
                rgb_list = tuple(RGB_tuples)
                return np.array(rgb_list) * 255
            N = 50
            colors = generate_RGB_list(N)

            bg_img = pe.im.copy()
            bg_img = np.full(bg_img.shape, 255, dtype=np.uint8)
            for boundary in group_contour.values():
                spiral = mkspiral.spiral(pe, boundary, offset)
                pathengine.suPath2D.draw_line(
                    spiral, bg_img, colors[0], line_width)

            # for show
            cv2.imwrite(filepath, bg_img)
            tex1 = cv2.cvtColor(bg_img, cv2.COLOR_BGR2RGBA)
            v1 = gl.GLImageItem(tex1)

            v1.translate(0, 0, i * self.mesh_info.layer_thickness)
            self.view_slice.items = []
            self.view_slice.addItem(v1)

        except Exception as e:
            self.message(str(e))
        return
Exemple #15
0
 def initialize_xy(self):
     """ Create the xy plane. """
     # Get out if no data is present
     if self.data.get_value() is None: return
     # Remove any old planes
     if hasattr(self, 'xy'):
         self.glview.removeItem(self.xy)
     # Get the data and texture to create the GLImageItem object
     cut = self.get_xy_slice(self.slider_xy.pos.get_value())
     texture = self.make_texture(cut)
     self.xy = gl.GLImageItem(texture, glOptions=self.gloptions)
     # Scale and translate to origin and add to glview
     self.xy.scale(self.xscale, self.yscale, 1)
     self.xy.translate(T, T, T)
     # Put to position in accordance with slider
     self.old_z = 0  #self.slider_xy.pos.get_value()
     self.update_xy()
     # Add to GLView
     self.glview.addItem(self.xy)
Exemple #16
0
 def initialize_zx(self):
     """ Create the zx plane. """
     # Get out if no data is present
     if self.data.get_value() is None: return
     # Remove any old planes
     if hasattr(self, 'zx'):
         self.glview.removeItem(self.zx)
     # Get the data and texture to create the GLImageItem object
     cut = self.get_zx_slice(0)
     texture = self.make_texture(cut)
     self.zx = gl.GLImageItem(texture, glOptions=self.gloptions)
     # Scale and translate to origin and add to glview (this plane has
     # shape (x, z))
     self.zx.scale(self.xscale, self.zscale, 1)
     self.zx.translate(T, T, 0)
     self.zx.rotate(90, 1, 0, 0)
     self.zx.translate(0, T, 0)
     # Put to position in accordance with slider
     self.update_zx()
     # Add to GLView
     self.glview.addItem(self.zx)
Exemple #17
0
    def gazePointsToGaussians(self,
                              sigma=20,
                              rotation=[90, 0, 1, 0],
                              x_shift=0,
                              y_shift=0,
                              option='additive'):
        '''
        Transforms the csv data into a list of GLImageItems. Each item contains the 
        viewpoints (AOIs) of every subject represented as Gaussians
        '''
        self.gaussians = []
        self.XYHeatmap = []
        self.XZHeatmap = []
        for frame_idx in range(self.gaze_points.shape[0]):
            print('computing gaussian overlay #{0}'.format(frame_idx))
            frame_data = self.gaze_points[frame_idx, :2, :]
            gaussians = []
            for subject in range(self.gaze_points.shape[2]):
                # mus are simply pixel indices of eye tracking
                subject_data = frame_data[:, subject]
                #
                gaussian = self.gaussian2d([subject_data[0], subject_data[1]],
                                           self.sigma)
                gaussians.append(gaussian)
            # add all gaussians
            gaussians = np.sum(gaussians, 0)
            # divide by number of subjects to renormalize gaussians (0,1)
            gaussians /= (subject + 1)
            # transform to RGBA
            gaussians = self.getColors(gaussians, cm.jet)
            # transform into GLImageItem
            gaussians = gl.GLImageItem(gaussians)
            # rotate, translate, scale, set option
            gaussians.rotate(rotation[0], rotation[1], rotation[2],
                             rotation[3])
            gaussians.translate(frame_idx * self.image_spacing + x_shift + 1,
                                y_shift, 0)

            gaussians.setGLOptions(option)
            self.gaussians.append(gaussians)
Exemple #18
0
    def __init__(self, w, path, sensor_no):
        super().__init__()
        a = self._anchor = gl.GLGraphicsItem.GLGraphicsItem()
        self._gizmo = gl.GLAxisItem(size=self.SIZE)
        self._gizmo.setParentItem(a)
        name = "{} {}".format(path[1:], sensor_no)
        sd_font = ImageFont.truetype(str(SQUARE_DEAL), 20)

        temp_image = Image.new('RGBA', (2, 2), (0, 0, 0, 0))
        width, height = ImageDraw.Draw(temp_image).textsize(name, sd_font)
        txt_image = Image.new('RGBA', (width + 2, height + 2), (0, 0, 0, 0))
        draw = ImageDraw.Draw(txt_image)
        draw.text((1, 1), name, font=sd_font, fill=(255, 255, 255, 128))
        tex1 = np.asarray(txt_image)
        v1 = gl.GLImageItem(tex1)
        v1.setParentItem(a)
        v1.scale(0.05, 0.05, 0.05)
        w.addItem(a)
        w.addItem(v1)
        w.addItem(self._gizmo)
        self._sensor_no = sensor_no
        self.update(QtGui.QQuaternion())
## create volume data set to slice three images from
shape = (100, 100, 70)
data = pg.gaussianFilter(np.random.normal(size=shape), (4, 4, 4))
data += pg.gaussianFilter(np.random.normal(size=shape), (15, 15, 15)) * 15

## slice out three planes, convert to RGBA for OpenGL texture
levels = (-0.08, 0.08)
tex1 = pg.makeRGBA(data[shape[0] // 2], levels=levels)[0]  # yz plane
tex2 = pg.makeRGBA(data[:, shape[1] // 2], levels=levels)[0]  # xz plane
tex3 = pg.makeRGBA(data[:, :, shape[2] // 2], levels=levels)[0]  # xy plane
#tex1[:,:,3] = 128
#tex2[:,:,3] = 128
#tex3[:,:,3] = 128

## Create three image items from textures, add to view
v1 = gl.GLImageItem(tex1)
v1.translate(-shape[1] / 2, -shape[2] / 2, 0)
v1.rotate(90, 0, 0, 1)
v1.rotate(-90, 0, 1, 0)
w.addItem(v1)
v2 = gl.GLImageItem(tex2)
v2.translate(-shape[0] / 2, -shape[2] / 2, 0)
v2.rotate(-90, 1, 0, 0)
w.addItem(v2)
v3 = gl.GLImageItem(tex3)
v3.translate(-shape[0] / 2, -shape[1] / 2, 0)
w.addItem(v3)

ax = gl.GLAxisItem()
w.addItem(ax)
Exemple #20
0
if show_time:
    w.addItem(make_grid_item((-radius, 0, time_length/2), (90, 0, 1, 0), (time_length/20, radius/10, radius/10)))
    w.addItem(make_grid_item((-radius, 0, time_length*3/2), (90, 0, 1, 0), (time_length/20, radius/10, radius/10)))
    w.addItem(make_grid_item((0, -radius, time_length/2), (90, 1, 0, 0), (radius/10, time_length/20, radius/10)))
    w.addItem(make_grid_item((0, -radius, time_length*3/2), (90, 1, 0, 0), (radius/10, time_length/20, radius/10)))
w.addItem(make_grid_item((0, 0, 0), (0, 0, 0, 0), (radius/10, radius/10, radius/10)))

# Make Image Base

# Determine the background image according to meta phase
bg_path = 'maze.png'
img = imread(os.path.join(local_directory, bg_path))

image_scale = (radius * 2.0) / float(img.shape[0])
tex1 = pg.makeRGBA(img)[0]
base_image = gl.GLImageItem(tex1)
base_image.translate(-radius, -radius, 0)
base_image.rotate(270, 0, 0, 1)
base_image.scale(image_scale, image_scale, image_scale)
w.addItem(base_image)

# Generate Path Line

color = (255, 255, 255, 255)
line_color = np.empty((len(iterations), 4))
line_color_state = np.empty((len(iterations), 4))
x = []
y = []
z = []
for idx, i in enumerate(iterations):
    x.append(float(i['x']))
Exemple #21
0
ax = gl.GLAxisItem(glOptions='opaque')
ax.setSize(2, 2, 2)

win.addItem(ax)
ax.setTransform(
    QtGui.QMatrix4x4(*(rotation((1, 0, 0), 0.0001, homog=True).flatten())))
ax.translate(0, 0, -0.02)

axc = gl.GLAxisItem(glOptions='opaque')
axc.setSize(1, 1, 1)
#axc.translate(0,0,0.02)
win.addItem(axc)

# imagen
view = gl.GLImageItem(data=np.zeros([100, 100, 4]))
win.addItem(view)

# marker
gmark = gl.GLLinePlotItem(pos=np.vstack([marker, marker[0]]),
                          color=(255, 0, 0, 1),
                          antialias=True,
                          width=3)
gmark.setGLOptions('opaque')
gmark.translate(0, 0, 0.01)
win.addItem(gmark)

# camera
cam = gl.GLLinePlotItem(pos=np.array([[0, 0, 0]]),
                        color=(255, 255, 255, 1),
                        antialias=True,
Exemple #22
0
    def fill(self):
        try:
            i = self.sl.value()
            self.message("Show slice {}.".format(i + 1), False)
            curdir = os.getcwd()
            filepath = self.out_path % i
            offset = -6
            line_width = 1  #int(abs(offset)/2)
            pe = pathengine.pathEngine()
            pe.generate_contours_from_img(filepath, True)
            pe.im = cv2.cvtColor(pe.im, cv2.COLOR_GRAY2BGR)
            contour_tree = pe.convert_hiearchy_to_PyPolyTree()
            group_contour = pe.get_contours_from_each_connected_region(
                contour_tree, '0')

            #draw boundaries
            #################################
            # Generate N color list
            #################################
            def generate_RGB_list(N):
                import colorsys
                HSV_tuples = [(x * 1.0 / N, 0.8, 0.9) for x in range(N)]
                RGB_tuples = map(lambda x: colorsys.hsv_to_rgb(*x), HSV_tuples)
                rgb_list = tuple(RGB_tuples)
                return np.array(rgb_list) * 255

            N = 50
            colors = generate_RGB_list(N)

            for boundary in group_contour.values():
                iso_contours = pe.fill_closed_region_with_iso_contours(
                    boundary, offset)
                idx = 0
                for cs in iso_contours:
                    for c in cs:
                        pathengine.suPath2D.draw_line(np.vstack([c,
                                                                 c[0]]), pe.im,
                                                      colors[idx], line_width)
                    idx += 1

            cv2.imwrite(filepath, pe.im)
            tex1 = cv2.cvtColor(pe.im, cv2.COLOR_BGR2RGBA)
            v1 = gl.GLImageItem(tex1)

            v1.translate(0, 0, i * self.mesh_info.layer_thickness)
            self.view_slice.items = []
            self.view_slice.addItem(v1)

        except Exception as e:
            self.message(str(e))

        # gen fermat's curve
        # gen 3d point n*3 matrix

        #n = 51
        #y = np.linspace(-10,10,n)
        #x = np.linspace(-10,10,100)
        #for i in range(n):
        #yi = np.array([y[i]]*100)
        #d = (x**2 + yi**2)**0.5
        #z = 10 * np.cos(d) / (d+1)
        #pts = np.vstack([x,yi,z]).transpose()
        #plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,n*1.3)), width=(i+1)/10., antialias=True)
        #self.view_slice.addItem(plt)
        return
    def init_ui(self):
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setMinimumSize(250, 250)
        layout = QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        positions = np.vstack([self.x_points, self.y_points,
                               self.z_points]).transpose()

        self.view = GLViewWidgetFix.GLViewWidgetFix()
        self.view.setBackgroundColor(119, 181, 254)
        self.view.setCameraPosition(distance=1950, elevation=90, azimuth=0)

        self.plot = opengl.GLLinePlotItem(pos=positions,
                                          color=[1, 0, 0, 1],
                                          width=3)
        self.plot.setGLOptions("opaque")
        self.view.addItem(self.plot)

        # self.grid = opengl.GLGridItem(color="white")
        # self.grid.setSize(x=(self.lon_max-self.lon_min)*self.meters_per_lon,
        #                   y=(self.lat_max-self.lat_min)*self.meters_per_lat)
        # self.grid.setSpacing(x=100, y=100)
        # self.view.addItem(self.grid)

        self.image_file = Image.open(self.image_name)
        self.image = opengl.GLImageItem(np.asarray(self.image_file))
        self.view.addItem(self.image)
        self.image.scale((self.lat_max - self.lat_min) * self.meters_per_lat /
                         self.image_file.size[1],
                         (self.lon_max - self.lon_min) * self.meters_per_lon /
                         self.image_file.size[0], 1)
        self.image.translate(
            -(self.lat_max - self.lat_min) * self.meters_per_lat / 2,
            -(self.lon_max - self.lon_min) * self.meters_per_lon / 2, 0)

        flat_earth = opengl.GLMeshItem(meshdata=opengl.MeshData.cylinder(
            1, 64, [6371000, 0], 0),
                                       color=[84 / 255, 89 / 255, 72 / 255, 1],
                                       smooth=True)
        flat_earth.translate(0, 0, -10000)
        flat_earth.setGLOptions("opaque")
        self.view.addItem(flat_earth)

        crosshair_mesh = mesh.Mesh.from_file("DisplayModels/Crosshairs.stl")
        crosshair_mesh_data = opengl.MeshData(vertexes=crosshair_mesh.vectors)
        self.crosshair = opengl.GLMeshItem(meshdata=crosshair_mesh_data,
                                           color=[1, 0, 0, 1])
        self.set_crosshair_pos(0, 0, 0)
        self.view.addItem(self.crosshair)

        self.view_btn = QPushButton("2D")
        self.view_btn.clicked.connect(self.switch_3d)
        self.view_btn.setMaximumWidth(30)

        self.coords_label = QLineEdit("0,0")
        self.coords_label.setAlignment(Qt.AlignCenter)
        self.coords_label.setReadOnly(True)

        self.clear_btn = QPushButton("CLR")
        self.clear_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.clear_btn.setToolTip("Clear Data")
        self.clear_btn.setFixedWidth(35)
        self.clear_btn.setParent(self.view)
        self.clear_btn.clicked.connect(self.clear_plot)

        self.sats_label = QLineEdit("0")
        self.sats_label.setAlignment(Qt.AlignCenter)
        self.sats_label.setReadOnly(True)
        self.sats_label.setToolTip("Number of Satellites")
        self.sats_label.setMaximumWidth(50)

        layout.addWidget(self.view, 0, 0, 1, 4)
        layout.addWidget(self.clear_btn, 1, 3)
        layout.addWidget(self.view_btn, 1, 0)
        layout.addWidget(self.coords_label, 1, 1)
        layout.addWidget(self.sats_label, 1, 2)
Exemple #24
0
    data = pickle.load(f)

nx, ny, nz = data.shape
print(nx, ny, nz)
x0, y0, z0 = 0, 0, 0
x0, y0, z0 = [int(2 * n / 5) for n in [nx, ny, nz]]

# Create Textures
levels = [data.min(), data.max()]
cmap = cmaps[cmap]
lut = cmap.getLookupTable()
textures = [
    pg.makeRGBA(d, levels=levels, lut=lut)[0]
    for d in [data[x0], data[:, y0], data[:, :, z0]]
]
planes = [gl.GLImageItem(texture, glOptions=gloption) for texture in textures]

## Apply transformations to get lanes where they need to go
xscale, yscale, zscale = 1 / nx, 1 / ny, 1 / nz
# xy plane
xy = planes[2]
xy.scale(xscale, yscale, 1)
xy.translate(-1 / 2, -1 / 2, -1 / 2 + z0 * zscale)
main.addItem(xy)

# yz plane (appears in the coordinate system along xy)
yz = planes[0]
yz.scale(yscale, zscale, 1)
yz.rotate(90, 0, 0, 1)
yz.rotate(90, 0, 1, 0)
yz.translate(-1 / 2 + x0 * xscale, -1 / 2, -1 / 2)
Exemple #25
0
    def __init__(self):
        super(MyView, self).__init__()
        self.opts['distance'] = 10
        self.opts['center'].setX(floor_sz[0] * 0.5)
        self.opts['center'].setY(floor_sz[1] * 0.5)
        self.opts['center'].setZ(wall_height * 0.5)
        self.opts['elevation'] = 0
        self.show()
        self.setWindowTitle('Hack4Sweden')

        # Floor
        floor_tex = scipy.ndimage.imread('textures/wood.jpeg', mode='RGBA')
        floor_tex = tile(floor_tex, floor_sz)
        floor = gl.GLImageItem(floor_tex)
        self.addItem(floor)

        # Walls
        wall1_tex = scipy.ndimage.imread('textures/wall_tex.jpg', mode='RGBA')
        wall1_tex = tile(wall1_tex, [floor_sz[0], wall_height])
        wall1 = gl.GLImageItem(wall1_tex)
        wall1.rotate(90, 1, 0, 0)
        self.addItem(wall1)

        wall2 = gl.GLImageItem(wall1_tex)
        wall2.rotate(90, 1, 0, 0)
        wall2.translate(0, floor_sz[1], 0)
        self.addItem(wall2)

        # Lighting

        globAmb = [0.3, 0.3, 0.3, 1.0]
        lightAmb = [0.75, 0.75, 0.75, 1.0]
        lightDifAndSpec = [0.7, 0.7, 0.7, 1.0]

        # glEnable(GL_LIGHTING)
        # glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb)
        # glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec)
        # glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec)
        # # glLightfv(GL_LIGHT0, GL_POSITION, [500, 250, 100, 0])
        # glEnable(GL_LIGHT0)
        # glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb)
        # glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE)
        # glEnable(GL_DEPTH_TEST)

        # Load paintings
        db = TinyDB('paintings/db.json')

        # db.insert({'name': 'Captain Planet', 'img': 'test.jpg'})

        added = 0
        for item in db.all():
            painting_tex = scipy.ndimage.imread('paintings/' + item['img'], mode='RGBA')
            painting = gl.GLImageItem(painting_tex, smooth=True)
            scale = painting_width * 1.0 / painting_tex.shape[1]
            painting.rotate(90, 0, 1, 0)
            painting.rotate(90, 0, 0, 1)
            painting.scale(scale, scale, scale)

            added += painting_spacing + painting_width
            painting.translate(added, 5, painting_tex.shape[0] * scale / 2 + wall_height / 2)
            self.addItem(painting)
Exemple #26
0
def visualize(path=None):
    """
    This function visualizes data for the virtual morris water maze task.

    :param path: a path to a log file from the virtual morris water maze task

    :return: Nothing
    """
    # noinspection PyGlobalUndefined
    global path_line, idx, timer, iterations, num_points_to_update, line_color_state, line_color

    ####################################################################################################################
    # Setup
    ####################################################################################################################

    show_time = False

    if path is None:
        path = easygui.fileopenbox()
    if path is '':
        logging.info('No file selected. Closing.')
        exit()
    if not os.path.exists(path):
        logging.error('File not found. Closing.')
        exit()

    meta = None
    # noinspection PyBroadException
    try:
        meta = get_filename_meta_data(os.path.basename(path))  # The meta filename information for convenience
    except:
        logging.error('There was an error reading the filename meta-information. Please confirm this is a valid log '
                      'file.')
        exit()

    logging.info("Parsing file (" + str(path) + ")...")
    # First we populate a list of each iteration's data
    # This section of code contains some custom binary parser data which won't be explained here
    iterations = read_binary_file(path)
    # Output the iterations count for debugging purposes
    logging.info("Plotting " + str(len(iterations)) + " iterations.")

    # Generate UI Window and Set Camera Settings

    app = QtGui.QApplication([])
    w = gl.GLViewWidget()
    w.opts['center'] = pg.Qt.QtGui.QVector3D(0, 0, 0)
    w.opts['elevation'] = 90
    w.opts['azimuth'] = 0
    w.opts['distance'] = 200
    w.setWindowTitle('MSL Virtual Morris Water Maze Visualizer' + ' - Subject {0}, Trial {1}, iteration {2}'.format(
        meta['subid'],
        meta['trial'],
        trial_num_to_str(meta['iteration'])))

    ####################################################################################################################
    # Generate static graphical items
    ####################################################################################################################

    # Make Grid

    grid_items = []

    def make_grid_item(loc, rot, scale):
        g = gl.GLGridItem()
        g.scale(scale[0], scale[1], scale[2])
        g.rotate(rot[0], rot[1], rot[2], rot[3])
        g.translate(loc[0], loc[1], loc[2])
        return g

    radius = 60
    time_length = 60
    if show_time:
        g0 = make_grid_item((-radius, 0, time_length/2), (90, 0, 1, 0), (time_length/20, radius/10, radius/10))
        g1 = make_grid_item((-radius, 0, time_length*3/2), (90, 0, 1, 0), (time_length/20, radius/10, radius/10))
        g2 = make_grid_item((0, -radius, time_length/2), (90, 1, 0, 0), (radius/10, time_length/20, radius/10))
        g3 = make_grid_item((0, -radius, time_length*3/2), (90, 1, 0, 0), (radius/10, time_length/20, radius/10))
        grid_items.append(g0)
        grid_items.append(g1)
        grid_items.append(g2)
        grid_items.append(g3)
        w.addItem(g0)
        w.addItem(g1)
        w.addItem(g2)
        w.addItem(g3)
    gn = make_grid_item((0, 0, 0), (0, 0, 0, 0), (radius/10, radius/10, radius/10))
    grid_items.append(gn)
    w.addItem(gn)

    # Make Image Base

    # Determine the background image according to meta phase
    bg_path = 'maze.png'
    img = imread(os.path.join('./media/virtual_morris_water_maze', bg_path))

    image_scale = (radius * 2.0) / float(img.shape[0])
    tex1 = pg.makeRGBA(img)[0]
    base_image = gl.GLImageItem(tex1)
    base_image.translate(-radius, -radius, 0)
    base_image.rotate(270, 0, 0, 1)
    base_image.scale(image_scale, image_scale, image_scale)
    w.addItem(base_image)

    # Generate Path Line

    color = (255, 255, 255, 255)
    line_color = np.empty((len(iterations), 4))
    line_color_state = np.empty((len(iterations), 4))
    x = []
    y = []
    z = []
    for idx, i in enumerate(iterations):
        x.append(float(i['x']))
        y.append(float(i['z']))
        if show_time:
            z.append(float(i['time']))
        else:
            z.append(0.0)
        line_color[idx] = pg.glColor(color)
        line_color_state[idx] = pg.glColor((0, 0, 0, 0))

    pts = np.vstack([x, y, z]).transpose()
    path_line = gl.GLLinePlotItem(pos=pts, color=line_color_state, mode='line_strip', antialias=True)
    w.addItem(path_line)

    ####################################################################################################################
    # Show UI
    ####################################################################################################################

    w.show()
    logging.info("Showing plot. Close plot to exit program.")

    ####################################################################################################################
    # Custom Keyboard Controls
    ####################################################################################################################

    # These variables are modified by the keyboard controls
    idx = 0
    num_points_to_update = 5
    saved_points_to_update = 0
    paused = False

    # GUI Callbacks
    def speed_up():
        global num_points_to_update, paused
        if not paused:
            num_points_to_update += 5
            logging.info("Setting speed to " + str(num_points_to_update) + " points per tick.")

    def speed_down():
        global num_points_to_update, paused
        if not paused:
            num_points_to_update -= 5
            logging.info("Setting speed to " + str(num_points_to_update) + " points per tick.")

    def pause():
        global num_points_to_update, saved_points_to_update, paused
        if not paused:
            logging.info("Paused.")
            saved_points_to_update = num_points_to_update
            num_points_to_update = 0
            paused = True
        else:
            logging.info("Unpaused.")
            num_points_to_update = saved_points_to_update
            saved_points_to_update = -0.5
            paused = False

    def reset():
        global idx, line_color_state
        logging.info("Resetting to time zero.")
        idx = 0
        for index in range(0, len(line_color_state) - 1):
            line_color_state[index] = (0, 0, 0, 0)

    def go_to_end():
        global idx, line_color_state, line_color
        logging.info("Going to end.")
        idx = len(line_color_state) - 1
        for index in range(0, len(line_color_state) - 1):
            line_color_state[index] = line_color[index]

    def close_all():
        global timer, app
        logging.info("User Shutdown Via Button Press")
        timer.stop()
        app.closeAllWindows()

    # Visibility Variables
    grid_visible = True
    base_visible = True
    path_line_visible = True

    def toggle_grid_visible():
        global grid_visible
        if grid_visible:
            for g in grid_items:
                g.hide()
            grid_visible = False
        else:
            for g in grid_items:
                g.show()
            grid_visible = True

    def toggle_base_visible():
        global base_visible
        if base_visible:
            base_image.hide()
            base_visible = False
        else:
            base_image.show()
            base_visible = True

    def toggle_path_line_visible():
        global path_line_visible
        if path_line_visible:
            path_line.hide()
            path_line_visible = False
        else:
            path_line.show()
            path_line_visible = True

    # GUI Initialization
    sh = QtGui.QShortcut(QtGui.QKeySequence("+"), w, speed_up)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("-"), w, speed_down)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence(" "), w, pause)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("R"), w, reset)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("E"), w, go_to_end)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("Escape"), w, close_all)
    sh.setContext(QtCore.Qt.ApplicationShortcut)

    sh = QtGui.QShortcut(QtGui.QKeySequence("1"), w, toggle_grid_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("2"), w, toggle_base_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("5"), w, toggle_path_line_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)

    ####################################################################################################################
    # Animation Loop
    ####################################################################################################################

    timer = QtCore.QTimer()
    # noinspection PyUnresolvedReferences
    timer.timeout.connect(update)
    timer.start(1)

    ####################################################################################################################
    # PyQtGraph Initialization
    ####################################################################################################################

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        # noinspection PyArgumentList
        QtGui.QApplication.instance().exec_()
plt_yaxis = gl.GLLinePlotItem(pos=pts_yaxis, width=linewidth, antialias=True)
w.addItem(plt_yaxis)
## make x-axis
xaxis = np.linspace(-x_length, x_length, 10)
y_xaxis = np.zeros(10)
z_xaxis = np.zeros(10)
pts_xaxis = np.vstack([y_xaxis, z_xaxis, xaxis]).transpose()
plt_xaxis = gl.GLLinePlotItem(pos=pts_xaxis, width=linewidth, antialias=True)
w.addItem(plt_xaxis)

## make images
image_shape = (8, 8)
uniform_values = np.ones(image_shape) * 255
uniform_image_transparent = pg.makeARGB(uniform_values)[0]
uniform_image_transparent[:, :, 3] = 65
v1 = gl.GLImageItem(uniform_image_transparent)
v1.translate(-image_shape[0] / 2, -image_shape[1] / 2, 0)
v1.rotate(90, 1, 0, 0)
#w.addItem(v1)
v = []
for i in range(0, 20):
    vtemp = gl.GLImageItem(uniform_image_transparent)
    vtemp.translate(-image_shape[0] / 2, -image_shape[1] / 2, 0)
    vtemp.rotate(90, 1, 0, 0)
    dz = float(i - 10)
    vtemp.translate(0, dz, 0)
    v.append(vtemp)
    w.addItem(v[i])

# Set up some animation parameters
frametime = 50  # frame refresh time in ms
Exemple #28
0
 def make_color_bar(rgb, p, r, s):
     v = gl.GLImageItem(np.array([[rgb + (255,)]]))
     v.translate(p[0], p[1], p[2])
     v.scale(s[0], s[1], s[2])
     v.rotate(r[0], r[1], r[2], r[3])
     return v
Exemple #29
0
def visualize_time_travel_data(path=None, automatically_rotate=True):
    """
    This function visualizes data from the Time Travel Task in 3D.

    :param path: the path to a data file to visualize
    :param automatically_rotate: If True, the figure will automatically rotate in an Abs(Sin(x)) function shape,
                                 otherwise the user can interact with the figure.

    :return: Nothing
    """
    # noinspection PyGlobalUndefined
    global path_line, idx, timer, iterations, click_scatter, click_pos, click_color, click_size, window, meta, \
        reconstruction_items, num_points_to_update, line_color, line_color_state, auto_rotate

    auto_rotate = automatically_rotate

    ####################################################################################################################
    # Setup
    ####################################################################################################################

    # Get Log File Path and Load File
    local_directory = os.path.dirname(os.path.realpath(__file__))  # The directory of this script
    # filename = '001_1_1_1_2016-08-29_10-26-03.dat'  # The relative path to the data file (CHANGE ME)
    # path = os.path.join(local_directory, filename)
    if path is None:
        path = easygui.fileopenbox()
    if path is '':
        logging.info('No file selected. Closing.')
        exit()
    if not os.path.exists(path):
        logging.error('File not found. Closing.')
        exit()

    meta = None
    # noinspection PyBroadException
    try:
        meta = get_filename_meta_data(os.path.basename(path))  # The meta filename information for convenience
    except:
        logging.error('There was an error reading the filename meta-information. Please confirm this is a valid log '
                      'file.')
        exit()

    logging.info("Parsing file (" + str(path) + ")...")
    # First we populate a list of each iteration's data
    # This section of code contains some custom binary parser data which won't be explained here
    iterations = read_binary_file(path)
    # Output the iterations count for debugging purposes
    logging.info("Plotting " + str(len(iterations)) + " iterations.")

    # Generate UI Window and Set Camera Settings

    app = QtGui.QApplication([])
    window = gl.GLViewWidget()
    window.opts['center'] = pg.Qt.QtGui.QVector3D(0, 0, 30)
    window.opts['distance'] = 200
    window.setWindowTitle('Timeline Visualizer' +
                          ' - Subject {0}, Trial {1}, Phase {2}'.format(meta['subID'], meta['trial'],
                                                                        phase_num_to_str(int(meta['phase']))))

    ####################################################################################################################
    # Generate static graphical items
    ####################################################################################################################

    # Make Grid

    grid_items = []

    def make_grid_item(loc, rot, scale):
        g = gl.GLGridItem()
        g.scale(scale[0], scale[1], scale[2])
        g.rotate(rot[0], rot[1], rot[2], rot[3])
        g.translate(loc[0], loc[1], loc[2])
        return g

    if meta['phase'] == '0' or meta['phase'] == '3' or meta['phase'] == '6':
        g0 = make_grid_item((-19, 0, 15), (90, 0, 1, 0), (1.5, 1.9, 1.9))
        g1 = make_grid_item((0, -19, 15), (90, 1, 0, 0), (1.9, 1.5, 1.9))
        grid_items.append(g0)
        grid_items.append(g1)
        window.addItem(g0)
        window.addItem(g1)
    else:
        g0 = make_grid_item((-19, 0, 15), (90, 0, 1, 0), (1.5, 1.9, 1.9))
        g1 = make_grid_item((-19, 0, 45), (90, 0, 1, 0), (1.5, 1.9, 1.9))
        g2 = make_grid_item((0, -19, 15), (90, 1, 0, 0), (1.9, 1.5, 1.9))
        g3 = make_grid_item((0, -19, 45), (90, 1, 0, 0), (1.9, 1.5, 1.9))
        grid_items.append(g0)
        grid_items.append(g1)
        grid_items.append(g2)
        grid_items.append(g3)
        window.addItem(g0)
        window.addItem(g1)
        window.addItem(g2)
        window.addItem(g3)
    gn = make_grid_item((0, 0, 0), (0, 0, 0, 0), (1.9, 1.9, 1.9))
    grid_items.append(gn)
    window.addItem(gn)

    # Make Image Base

    # Determine the background image according to meta phase
    img_location = './media/time_travel_task/'
    bg_path = 'studyBG.png'
    if meta['phase'] == '0' or meta['phase'] == '3':
        bg_path = 'practiceBG.png'
    elif meta['phase'] == '6':
        bg_path = 'practiceBG.png'
    elif meta['phase'] == '7' or meta['phase'] == '8':
        bg_path = 'studyBG.png'
    img = imread(os.path.abspath(os.path.join(img_location, bg_path)))

    image_scale = (19.0 * 2.0) / float(img.shape[0])
    tex1 = pg.makeRGBA(img)[0]
    base_image = gl.GLImageItem(tex1)
    base_image.translate(-19, -19, 0)
    base_image.rotate(270, 0, 0, 1)
    base_image.scale(image_scale, image_scale, image_scale)
    window.addItem(base_image)

    # Make Timeline Colored Bars

    color_bars = []

    def make_color_bar(rgb, p, r, s):
        v = gl.GLImageItem(np.array([[rgb + (255,)]]))
        v.translate(p[0], p[1], p[2])
        v.scale(s[0], s[1], s[2])
        v.rotate(r[0], r[1], r[2], r[3])
        return v

    color_bar_length = 15

    if meta['phase'] == '0' or meta['phase'] == '3' or meta['phase'] == '6':
        times = [0, 7.5, 15, 22.5]
        color_bar_length = 7.5
    else:
        times = [0, 15, 30, 45]
    if meta['inverse'] == '1':
        times.reverse()

    v0 = make_color_bar((255, 255, 0), (19, times[0], 19), (90, 1, 0, 0), (5, color_bar_length, 0))
    v1 = make_color_bar((255, 0, 0), (19, times[1], 19), (90, 1, 0, 0), (5, color_bar_length, 0))
    v2 = make_color_bar((0, 255, 0), (19, times[2], 19), (90, 1, 0, 0), (5, color_bar_length, 0))
    v3 = make_color_bar((0, 0, 255), (19, times[3], 19), (90, 1, 0, 0), (5, color_bar_length, 0))
    color_bars.append(v0)
    color_bars.append(v1)
    color_bars.append(v2)
    color_bars.append(v3)
    window.addItem(v0)
    window.addItem(v1)
    window.addItem(v2)
    window.addItem(v3)

    # Generate Path Line

    forwardColor = (255, 255, 255, 255)
    backwardColor = (255, 0, 255, 255)
    line_color = np.empty((len(iterations), 4))
    line_color_state = np.empty((len(iterations), 4))
    x = []
    y = []
    z = []
    for idx, i in enumerate(iterations):
        x.append(float(i['x']))
        y.append(float(i['z']))
        z.append(float(i['time_val']))
        c = forwardColor
        if i['timescale'] <= 0:
            c = backwardColor
        line_color[idx] = pg.glColor(c)
        line_color_state[idx] = pg.glColor((0, 0, 0, 0))

    pts = np.vstack([x, y, z]).transpose()
    path_line = gl.GLLinePlotItem(pos=pts, color=line_color_state, mode='line_strip', antialias=True)
    window.addItem(path_line)

    # Generate Item Lines (ground truth)
    # noinspection PyUnusedLocal
    items, times, directions = get_items_solutions(meta)

    if meta['phase'] == '0' or meta['phase'] == '3' or meta['phase'] == '6':
        times = [2, 12, 18, 25]
        directions = [2, 1, 2, 1]  # Fall = 2, Fly = 1, Stay = 0
        if meta['inverse'] == '1':
            times.reverse()
            directions.reverse()
        items = [{'direction': directions[0], 'pos': (2, -12, times[0]), 'color': (255, 255, 0)},
                 {'direction': directions[1], 'pos': (2, 13, times[1]), 'color': (255, 0, 0)},
                 {'direction': directions[2], 'pos': (-13, 2, times[2]), 'color': (0, 255, 0)},
                 {'direction': directions[3], 'pos': (-12, -17, times[3]), 'color': (0, 0, 255)},
                 {'direction': 0, 'pos': (13, 5, 0), 'color': (128, 0, 128)}]
    # elif meta['phase'] == '7' or meta['phase'] == '8':
    #    times = [2, 8, 17, 23]
    #    directions = [2, 1, 1, 2]  # Fall = 2, Fly = 1, Stay = 0
    #    if meta['inverse'] == '1':
    #        times.reverse()
    #        directions.reverse()
    #    items = [{'direction': directions[0], 'pos': (16, -14, times[0]), 'color': (255, 255, 0)},
    #             {'direction': directions[1], 'pos': (-10, -2, times[1]), 'color': (255, 0, 0)},
    #             {'direction': directions[2], 'pos': (15, -8, times[2]), 'color': (0, 255, 0)},
    #             {'direction': directions[3], 'pos': (-15, -15, times[3]), 'color': (0, 0, 255)},
    #             {'direction': 0, 'pos': (-2, 10, 0), 'color': (128, 0, 128)}]
    else:
        times = [4, 10, 16, 25, 34, 40, 46, 51]
        directions = [2, 1, 1, 2, 2, 1, 2, 1]  # Fall = 2, Fly = 1, Stay = 0
        if meta['inverse'] == '1':
            times.reverse()
            directions.reverse()
        items = [{'direction': directions[0], 'pos': (18, -13, times[0]), 'color': (255, 255, 0)},
                 {'direction': directions[1], 'pos': (-13, 9, times[1]), 'color': (255, 255, 0)},
                 {'direction': directions[2], 'pos': (-10, -2, times[2]), 'color': (255, 0, 0)},
                 {'direction': directions[3], 'pos': (6, -2, times[3]), 'color': (255, 0, 0)},
                 {'direction': directions[4], 'pos': (17, -8, times[4]), 'color': (0, 255, 0)},
                 {'direction': directions[5], 'pos': (-2, -7, times[5]), 'color': (0, 255, 0)},
                 {'direction': directions[6], 'pos': (-15, -15, times[6]), 'color': (0, 0, 255)},
                 {'direction': directions[7], 'pos': (6, 18, times[7]), 'color': (0, 0, 255)},
                 {'direction': 0, 'pos': (14, 6, 0), 'color': (128, 0, 128)},
                 {'direction': 0, 'pos': (-2, 10, 0), 'color': (128, 0, 128)}]

    item_lines = []
    pos = np.empty((len(items), 3))
    size = np.empty((len(items)))
    color = np.empty((len(items), 4))
    end_time = 60
    if meta['phase'] == '0' or meta['phase'] == '3' or meta['phase'] == '6':
        end_time = 30
    for idx, i in enumerate(items):
        pos[idx] = i['pos']
        size[idx] = 2
        if i['direction'] == 0:
            size[idx] = 0
        color[idx] = (i['color'][0] / 255, i['color'][1] / 255, i['color'][2] / 255, 1)
        idx += 1
        end = i['pos']
        if i['direction'] == 1:
            end = (end[0], end[1], 0)
        elif i['direction'] == 2 or i['direction'] == 0:
            end = (end[0], end[1], end_time)
        line = gl.GLLinePlotItem(pos=np.vstack([[i['pos'][0], end[0]],
                                                [i['pos'][1], end[1]],
                                                [i['pos'][2], end[2]]]).transpose(),
                                 color=pg.glColor(i['color']), width=3, antialias=True)
        item_lines.append(line)
        window.addItem(line)

    item_scatter_plot = gl.GLScatterPlotItem(pos=pos, size=size, color=color, pxMode=False)
    window.addItem(item_scatter_plot)

    ####################################################################################################################
    # Generate data graphical items
    ####################################################################################################################

    # If Study/Practice, label click events
    '''click_pos = np.empty((len(items), 3))
    click_size = np.zeros((len(iterations), len(items)))
    click_color = np.empty((len(items), 4))
    if meta['phase'] == '0' or meta['phase'] == '1' or meta['phase'] == '3' or meta['phase'] == '4' \
            or meta['phase'] == '6' or meta['phase'] == '7':
        for idx, i in enumerate(iterations):
            if idx + 1 < len(iterations):
                for idxx, (i1, i2) in enumerate(zip(i['itemsclicked'], iterations[idx + 1]['itemsclicked'])):
                    if i['itemsclicked'][idxx]:
                        click_size[idx][idxx] = 0.5
                    if not i1 == i2:
                        click_pos[idxx] = (i['x'], i['z'], i['time_val'])
                        click_color[idxx] = (128, 128, 128, 255)
            else:
                for idxx, i1 in enumerate(i['itemsclicked']):
                    if i['itemsclicked'][idxx]:
                        click_size[idx][idxx] = 0.5
    '''
    click_pos, _, click_size, click_color = get_click_locations_and_indicies(iterations, items, meta)
    click_scatter = gl.GLScatterPlotItem(pos=click_pos, size=click_size[0], color=click_color, pxMode=False)
    window.addItem(click_scatter)

    # If Test, Generate Reconstruction Items

    event_state_labels, item_number_label, item_label_filename, cols = get_item_details()

    # if meta['phase'] == '7' or meta['phase'] == '8':
    #    item_number_label = ['bottle', 'clover', 'boot', 'bandana', 'guitar']
    #    item_label_filename = ['bottle.jpg', 'clover.jpg', 'boot.jpg', 'bandana.jpg', 'guitar.jpg']
    #    cols = [(255, 255, pastel_factor), (255, pastel_factor, pastel_factor), (pastel_factor, 255, pastel_factor),
    #            (pastel_factor, pastel_factor, 255), (128, pastel_factor / 2, 128)]
    reconstruction_item_scatter_plot = None
    reconstruction_item_lines = []
    if meta['phase'] == '2' or meta['phase'] == '5' or meta['phase'] == '8':
        reconstruction_items, order = parse_test_items(iterations, cols,
                                                       item_number_label, event_state_labels)
        pos = np.empty((len(reconstruction_items), 3))
        size = np.empty((len(reconstruction_items)))
        color = np.empty((len(reconstruction_items), 4))
        # Iterate through the reconstruction items and visualize them
        for idx, i in enumerate(reconstruction_items):
            pos[idx] = i['pos']
            size[idx] = 2
            if i['direction'] == 0:
                size[idx] = 0
            color[idx] = (i['color'][0] / 255, i['color'][1] / 255, i['color'][2] / 255, 1)
            end = pos[idx]
            if i['direction'] == 1:
                end = (end[0], end[1], 0)
            elif i['direction'] == 2 or i['direction'] == 0:
                end = (end[0], end[1], end_time)
            line = gl.GLLinePlotItem(pos=np.vstack([[pos[idx][0], end[0]],
                                                    [pos[idx][1], end[1]],
                                                    [pos[idx][2], end[2]]]).transpose(),
                                     color=pg.glColor(i['color']), width=3, antialias=True)
            reconstruction_item_lines.append(line)
            window.addItem(line)

            img_path = item_label_filename[idx]
            img = imread(os.path.join(local_directory, img_path))
            expected_size = 2.0
            image_scale = expected_size / float(img.shape[0])
            offset_param = 0.0 - image_scale / 2 - expected_size / 2
            tex = pg.makeRGBA(img)[0]
            label_image = gl.GLImageItem(tex)
            t = pos[idx][2]
            if i['direction'] == 0:
                t = end_time
            label_image.translate(pos[idx][0] + offset_param, pos[idx][1] + offset_param, t)
            label_image.scale(image_scale, image_scale, image_scale)
            window.addItem(label_image)
            billboard_item_labels.append(label_image)
        reconstruction_item_scatter_plot = gl.GLScatterPlotItem(pos=pos, size=size, color=color, pxMode=False)
        window.addItem(reconstruction_item_scatter_plot)

    ####################################################################################################################
    # Show UI
    ####################################################################################################################

    window.show()
    logging.info("Showing plot. Close plot to exit program.")

    ####################################################################################################################
    # Custom Keyboard Controls
    ####################################################################################################################

    # These variables are modified by the keyboard controls
    idx = 0
    num_points_to_update = 5
    saved_points_to_update = 0
    paused = False

    # GUI Callbacks
    def speed_up():
        global num_points_to_update, paused
        if not paused:
            num_points_to_update += 5
            logging.info("Setting speed to " + str(num_points_to_update) + " points per tick.")

    def speed_down():
        global num_points_to_update, paused
        if not paused:
            num_points_to_update -= 5
            logging.info("Setting speed to " + str(num_points_to_update) + " points per tick.")

    def pause():
        global num_points_to_update, saved_points_to_update, paused
        if not paused:
            logging.info("Paused.")
            saved_points_to_update = num_points_to_update
            num_points_to_update = 0
            paused = True
        else:
            logging.info("Unpaused.")
            num_points_to_update = saved_points_to_update
            saved_points_to_update = -0.5
            paused = False

    def reset():
        global idx, line_color_state
        logging.info("Resetting to time zero.")
        idx = 0
        for index in range(0, len(line_color_state) - 1):
            line_color_state[index] = (0, 0, 0, 0)

    def go_to_end():
        global idx, line_color_state, line_color
        logging.info("Going to end.")
        idx = len(line_color_state) - 1
        for index in range(0, len(line_color_state) - 1):
            line_color_state[index] = line_color[index]

    def close_all():
        global timer, app
        logging.info("User Shutdown Via Button Press")
        timer.stop()
        app.closeAllWindows()

    # Visibility Variables
    grid_visible = True
    base_visible = True
    color_bars_visible = True
    items_visible = True
    path_line_visible = True
    reconstruction_item_lines_visible = True
    billboard_item_labels_visible = True

    def toggle_grid_visible():
        global grid_visible
        if grid_visible:
            for g in grid_items:
                g.hide()
            grid_visible = False
        else:
            for g in grid_items:
                g.show()
            grid_visible = True

    def toggle_base_visible():
        global base_visible
        if base_visible:
            base_image.hide()
            base_visible = False
        else:
            base_image.show()
            base_visible = True

    def toggle_color_bars_visible():
        global color_bars_visible
        if color_bars_visible:
            for bar in color_bars:
                bar.hide()
            color_bars_visible = False
        else:
            for bar in color_bars:
                bar.show()
            color_bars_visible = True

    def toggle_items_visible():
        global items_visible
        if items_visible:
            item_scatter_plot.hide()
            for il in item_lines:
                il.hide()
            items_visible = False
        else:
            item_scatter_plot.show()
            for il in item_lines:
                il.show()
            items_visible = True

    def toggle_path_line_visible():
        global path_line_visible
        if path_line_visible:
            path_line.hide()
            click_scatter.hide()
            path_line_visible = False
        else:
            path_line.show()
            click_scatter.show()
            path_line_visible = True

    def toggle_reconstruction_item_lines_visible():
        global reconstruction_item_lines_visible
        if reconstruction_item_lines_visible:
            if reconstruction_item_scatter_plot is not None:
                reconstruction_item_scatter_plot.hide()
            for ril in reconstruction_item_lines:
                ril.hide()
            reconstruction_item_lines_visible = False
        else:
            if reconstruction_item_scatter_plot is not None:
                reconstruction_item_scatter_plot.show()
            for ril in reconstruction_item_lines:
                ril.show()
            reconstruction_item_lines_visible = True

    def toggle_billboard_item_labels_visible():
        global billboard_item_labels_visible
        if billboard_item_labels_visible:
            for il in billboard_item_labels:
                il.hide()
                billboard_item_labels_visible = False
        else:
            for il in billboard_item_labels:
                il.show()
                billboard_item_labels_visible = True

    # GUI Initialization
    sh = QtGui.QShortcut(QtGui.QKeySequence("+"), window, speed_up)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("-"), window, speed_down)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence(" "), window, pause)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("R"), window, reset)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("E"), window, go_to_end)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("Escape"), window, close_all)
    sh.setContext(QtCore.Qt.ApplicationShortcut)

    sh = QtGui.QShortcut(QtGui.QKeySequence("1"), window, toggle_grid_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("2"), window, toggle_base_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("3"), window, toggle_color_bars_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("4"), window, toggle_items_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("5"), window, toggle_path_line_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("6"), window, toggle_reconstruction_item_lines_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)
    sh = QtGui.QShortcut(QtGui.QKeySequence("7"), window, toggle_billboard_item_labels_visible)
    sh.setContext(QtCore.Qt.ApplicationShortcut)

    ####################################################################################################################
    # Animation Loop
    ####################################################################################################################

    timer = QtCore.QTimer()
    # noinspection PyUnresolvedReferences
    timer.timeout.connect(update)
    timer.start(1)

    ####################################################################################################################
    # PyQtGraph Initialization
    ####################################################################################################################

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        # noinspection PyArgumentList
        QtGui.QApplication.instance().exec_()
Exemple #30
0
def make_freeslice():
    #_Parameters________________________________________________________________

    DATA_PATH = pkg_resources.resource_filename('data_slicer', 'data/')
    datafile = DATA_PATH + 'pit.p'

    ## Visual
    gloption = 'translucent'
    cmap = 'ocean'

    #_GUI_setup_________________________________________________________________

    # Set up the main window and set a central widget
    window = QtGui.QMainWindow()
    window.resize(800, 800)
    central_widget = QtGui.QWidget()
    window.setCentralWidget(central_widget)

    # Create a layout
    layout = QtGui.QGridLayout()
    central_widget.setLayout(layout)

    # Add the selector view
    selector = ImagePlot()
    #selector = gl.GLViewWidget()
    layout.addWidget(selector, 1, 0, 1, 1)

    # Set up the main 3D view widget
    main = gl.GLViewWidget()
    layout.addWidget(main, 0, 0, 1, 1)

    # Somehow this is needed for both widets to be visible
    layout.setRowStretch(0, 1)
    layout.setRowStretch(1, 1)

    #_Data_loading_and_presenting_______________________________________________

    # Load data
    with open(datafile, 'rb') as f:
        data = pickle.load(f)

    nx, ny, nz = data.shape
    x0, y0, z0 = 0, 0, 0
    x0, y0, z0 = [int(2 * n / 5) for n in [nx, ny, nz]]

    # Create Textures
    levels = [data.min(), data.max()]
    cmap = load_cmap(cmap)
    lut = cmap.getLookupTable()
    cuts = [data[x0], data[:, y0], data[:, :, z0]]
    textures = [pg.makeRGBA(d, levels=levels, lut=lut)[0] for d in cuts]
    planes = [
        gl.GLImageItem(texture, glOptions=gloption) for texture in textures
    ]

    ## Apply transformations to get lanes where they need to go
    xscale, yscale, zscale = 1 / nx, 1 / ny, 1 / nz
    # xy plane
    xy = planes[2]
    xy.scale(xscale, yscale, 1)
    xy.translate(-1 / 2, -1 / 2, -1 / 2 + z0 * zscale)
    main.addItem(xy)

    #_Selector__________________________________________________________________

    # Set an image in the selector plot
    selector.set_image(cuts[2], lut=lut)
    cutline = Cutline(selector)
    cutline.initialize()

    # A plane representing the cutline
    cut, coords = cutline.get_array_region(data,
                                           selector.image_item,
                                           returnMappedCoords=True)
    cut_texture = pg.makeRGBA(cut, levels=levels, lut=lut)[0]
    cutplane = gl.GLImageItem(cut_texture, glOptions=gloption)

    # Scale and move it to origin in upright position
    # Upon initialization, this is like an xz plane
    cutplane.scale(xscale, zscale, 1)
    cutplane.rotate(90, 1, 0, 0)
    cutplane.translate(-1 / 2, 0, -1 / 2)
    transform0 = cutplane.transform()

    main.addItem(cutplane)

    # Conversion from ROI coordinates to Scene coordinates
    roi_coords = cutline.roi.getLocalHandlePositions()
    # also usefule for later
    original_roi_x0 = roi_coords[0][1].x()
    original_roi_x1 = roi_coords[1][1].x()
    # length in ROI coordinates
    length_in_roi = np.abs(original_roi_x1 - original_roi_x0)
    # length in data coordinates
    length_in_data = np.abs(coords[0, 0] - coords[0, -1])
    # conversion in units of "roi/data"
    roi_data_conversion = length_in_roi / length_in_data
    # distance from left handle to M in data coords
    distance_p0_m = length_in_data / 2
    print('Distance: ', distance_p0_m)

    def update_texture():
        print('==')
        print('LocalHandles: ', cutline.roi.getLocalHandlePositions())
        print('Scene: ', cutline.roi.getSceneHandlePositions())
        print('++')
        transform = cutline.roi.getArraySlice(data, selector.image_item)[1]

        cut, coords = cutline.get_array_region(data,
                                               selector.image_item,
                                               returnMappedCoords=True)
        texture = pg.makeRGBA(cut, levels=levels, lut=lut)[0]
        cutplane.setData(texture)

        ## Find the original center of mass (if no length changes would have been applied)
        # The current handle positions in data coordinates are in p0 and p1
        p0 = coords[[0, 1], [0, 0]]
        p1 = coords[[0, 1], [-1, -1]]
        # Find how much they have been stretched or compressed with respect to
        # the original handles
        new_roi_coords = cutline.roi.getLocalHandlePositions()
        delta0 = (original_roi_x0 -
                  new_roi_coords[0][1].x()) / roi_data_conversion
        # Construct a unit vector pointing from P0 to P1
        diff = p1 - p0
        e_pp = diff / np.sqrt(diff.dot(diff))
        print('p0: ', p0)
        print('p1: ', p1)
        print('diff', diff)
        print('e_pp: ', e_pp)

        # Now the original midpoint is at p0 + e_pp*(distance_p0_m+delta0)
        print('delta0: ', delta0)
        M = p0
        tx, ty = M[0], M[1]
        print('tx, ty: {}, {}'.format(tx, ty))

        tx *= xscale
        ty *= yscale
        print('tx, ty: {}, {}'.format(tx, ty))

        # Rotate around origin
        try:
            alpha = np.arctan((p1[1] - p0[1]) / (p1[0] - p0[0]))
        except ZeroDivisionError:
            alpha = np.sign(p1[1] - p0[1]) * np.pi / 2
        # Correct for special cases
        if p1[0] < p0[0]:
            alpha -= np.sign(p1[1] - p0[1]) * np.pi
        alpha_deg = alpha * 180 / np.pi
        print('alpha_deg: {}'.format(alpha_deg))

        nt = QtGui.QMatrix4x4()
        nt.translate(tx - 1 / 2, ty - 1 / 2, -1 / 2)
        nt.scale(xscale, yscale, 1)
        nt.rotate(alpha_deg, 0, 0, 1)
        nt.rotate(90, 1, 0, 0)
        nt.scale(1, zscale, 1)
        cutplane.setTransform(nt)

    cutline.sig_region_changed.connect(update_texture)

    # Draw a coordinate system
    axis = gl.GLAxisItem()
    main.addItem(axis)

    return window