Пример #1
0
    def __init__(self, g_pool, mode="Show Markers and Frames"):
        super(Offline_Marker_Detector, self).__init__(g_pool)
        self.order = .2

        # all markers that are detected in the most recent frame
        self.markers = []
        # all registered surfaces

        if g_pool.app == 'capture':
            raise Exception('For Player only.')
        #in player we load from the rec_dir: but we have a couple options:
        self.surface_definitions = Persistent_Dict(
            os.path.join(g_pool.rec_dir, 'surface_definitions'))
        if self.surface_definitions.get('offline_square_marker_surfaces',
                                        []) != []:
            logger.debug(
                "Found ref surfaces defined or copied in previous session.")
            self.surfaces = [
                Offline_Reference_Surface(self.g_pool, saved_definition=d)
                for d in self.surface_definitions.get(
                    'offline_square_marker_surfaces', [])
                if isinstance(d, dict)
            ]
        elif self.surface_definitions.get('realtime_square_marker_surfaces',
                                          []) != []:
            logger.debug(
                "Did not find ref surfaces def created or used by the user in player from earlier session. Loading surfaces defined during capture."
            )
            self.surfaces = [
                Offline_Reference_Surface(self.g_pool, saved_definition=d)
                for d in self.surface_definitions.get(
                    'realtime_square_marker_surfaces', [])
                if isinstance(d, dict)
            ]
        else:
            logger.debug("No surface defs found. Please define using GUI.")
            self.surfaces = []

        # ui mode settings
        self.mode = mode
        self.min_marker_perimeter = 20  #if we make this a slider we need to invalidate the cache on change.
        # edit surfaces
        self.edit_surfaces = []

        #check if marker cache is available from last session
        self.persistent_cache = Persistent_Dict(
            os.path.join(g_pool.rec_dir, 'square_marker_cache'))
        self.cache = Cache_List(
            self.persistent_cache.get('marker_cache',
                                      [False for _ in g_pool.timestamps]))
        logger.debug(
            "Loaded marker cache %s / %s frames had been searched before" %
            (len(self.cache) - self.cache.count(False), len(self.cache)))
        self.init_marker_cacher()

        #debug vars
        self.show_surface_idx = c_int(0)

        self.img_shape = None
        self.img = None
Пример #2
0
 def load_surface_definitions_from_file(self):
     self.surface_definitions = Persistent_Dict(
         os.path.join(self.g_pool.rec_dir, 'surface_definitions'))
     if self.surface_definitions.get('offline_square_marker_surfaces',
                                     []) != []:
         logger.debug(
             "Found ref surfaces defined or copied in previous session.")
         self.surfaces = [
             Offline_Reference_Surface(self.g_pool, saved_definition=d)
             for d in self.surface_definitions.get(
                 'offline_square_marker_surfaces', [])
         ]
     elif self.surface_definitions.get('realtime_square_marker_surfaces',
                                       []) != []:
         logger.debug(
             "Did not find ref surfaces def created or used by the user in player from earlier session. Loading surfaces defined during capture."
         )
         self.surfaces = [
             Offline_Reference_Surface(self.g_pool, saved_definition=d)
             for d in self.surface_definitions.get(
                 'realtime_square_marker_surfaces', [])
         ]
     else:
         logger.debug("No surface defs found. Please define using GUI.")
         self.surfaces = []
Пример #3
0
    def __init__(self,g_pool,gui_settings={'pos':(220,200),'size':(300,300),'iconified':False}):
        super(Offline_Marker_Detector, self).__init__()
        self.g_pool = g_pool
        self.gui_settings = gui_settings
        self.order = .2


        # all markers that are detected in the most recent frame
        self.markers = []
        # all registered surfaces

        if g_pool.app == 'capture':
           raise Exception('For Player only.')
        #in player we load from the rec_dir: but we have a couple options:
        self.surface_definitions = Persistent_Dict(os.path.join(g_pool.rec_dir,'surface_definitions'))
        if self.load('offline_square_marker_surfaces',[]) != []:
            logger.debug("Found ref surfaces defined or copied in previous session.")
            self.surfaces = [Offline_Reference_Surface(self.g_pool,saved_definition=d,gaze_positions_by_frame=self.g_pool.positions_by_frame) for d in self.load('offline_square_marker_surfaces',[]) if isinstance(d,dict)]
        elif self.load('realtime_square_marker_surfaces',[]) != []:
            logger.debug("Did not find ref surfaces def created or used by the user in player from earlier session. Loading surfaces defined during capture.")
            self.surfaces = [Offline_Reference_Surface(self.g_pool,saved_definition=d,gaze_positions_by_frame=self.g_pool.positions_by_frame) for d in self.load('realtime_square_marker_surfaces',[]) if isinstance(d,dict)]
        else:
            logger.debug("No surface defs found. Please define using GUI.")
            self.surfaces = []


        # ui mode settings
        self.mode = c_int(0)
        # edit surfaces
        self.edit_surfaces = []

        #detector vars
        self.robust_detection = c_bool(1)
        self.aperture = c_int(11)
        self.min_marker_perimeter = 80

        #check if marker cache is available from last session
        self.persistent_cache = Persistent_Dict(os.path.join(g_pool.rec_dir,'square_marker_cache'))
        self.cache = Cache_List(self.persistent_cache.get('marker_cache',[False for _ in g_pool.timestamps]))
        logger.debug("Loaded marker cache %s / %s frames had been searched before"%(len(self.cache)-self.cache.count(False),len(self.cache)) )
        self.init_marker_cacher()

        #debug vars
        self.show_surface_idx = c_int(0)
        self.recent_pupil_positions = []

        self.img_shape = None
        self.img = None
Пример #4
0
    def add_surface(self):
        self.surfaces.append(Offline_Reference_Surface(self.g_pool))
        self.timeline.content_height += self.timeline_line_height

        self.surfaces[0].name = 'Screen'
        self.surfaces[0].real_world_size['x'] = self.screen_x
        self.surfaces[0].real_world_size['y'] = self.screen_y
        self.update_gui_markers()
Пример #5
0
 def add_surface(self):
     self.surfaces.append(Offline_Reference_Surface(self.g_pool))
     self.timeline.height += self.timeline_line_height
     self.update_gui_markers()
Пример #6
0
 def add_surface(self):
     self.surfaces.append(Offline_Reference_Surface(self.g_pool))
     self.update_gui_markers()
Пример #7
0
 def add_surface(self):
     self.surfaces.append(
         Offline_Reference_Surface(
             self.g_pool,
             gaze_positions_by_frame=self.g_pool.positions_by_frame))
     self.update_bar_markers()
Пример #8
0
def map_surface(folder,loadCache = True,loadSurface = True):
    # if you want to redo it, put loadCache to false
    
    # How a surface in pupil labs works (took me many days to figure that out...)
    #  1. detect all markers in tracker (this starts its own slave process)
    #  2. add some markers to a surface via build_correspondence
    #  3. for all markers detect the surface (init_cache)
    #  4. add the surface to the tracker
    #  5. map the observed pupil data to the surface (done in surface_map_data)
    
                
    fake_gpool = fake_gpool_surface(folder)

    
    # Step 1.    
    print('Starting Tracker - WARNING: ROBUST_DETECTION IS CURRENTLY FALSE')
    
    # TODO Decide robust detection (not really sure what it does)
    tracker = offline_surface_tracker.Offline_Surface_Tracker(fake_gpool,min_marker_perimeter=30,robust_detection=False)
    tracker.timeline = None
    
    if loadSurface and len(tracker.surfaces)==1 and tracker.surfaces[0].defined:
        print('Surface already defined, loadSurface=TRUE, thus returning tracker')
        tracker.cleanup()
        return(tracker)
    # Remove the cache if we do not need it
    if not loadCache:
        tracker.invalidate_marker_cache()
    
    start = time.time()
    
    print('Finding Markers')
    # This does what offline_surface_tracker.update_marker_cache() does (except the update surface, we dont need it), 
    # but in addition gives us feedback & has a stopping criterion
    while True:
        if (time.time()-start)>1:
            start = time.time()        
            visited_list = [False if x is False else True for x in tracker.cache]
            percent_visited = np.mean(np.asarray(visited_list))
            print(percent_visited)
            if percent_visited == 1:
                # save stuff and stop the process   
                tracker.cleanup()
                break
        try:
            idx, c_m = tracker.cache_queue.get(timeout=5)
        except QueueEmptyException:
            time.sleep(1)
            
            print('Nothing to do, waiting...')
            continue
        tracker.cache.update(idx, c_m)
        
     
        if tracker.cacher_run.value is False:
            tracker.recalculate()
        
    
    
    # Step 2.    
    # add a single surface
    print('Adding a surface')
    surface = Offline_Reference_Surface(tracker.g_pool)    
    
    
    # First define the markers that should be used for the surface
    # find a frame where there are 16 markers and all of them have high confidence
    ix = 0
    while True:
        if len(tracker.cache[ix]) == 16:
            usable_markers = [m for m in tracker.cache[ix] if m['id_confidence'] >= 0.8]
            if len(usable_markers) == 16:
                break
        ix +=1
        
    # Step 3
    # This dissables pupil-labs functionality. They ask for 90 frames with the markers. but because we know there will be 16 markers, we dont need it (toitoitoi)
    print('Defining & Finding Surface')
    surface.required_build_up = 1
    surface.build_correspondence(tracker.cache[ix],0.3,0.7)
    if not surface.defined:
        raise('Oh oh trouble ahead. The surface was not defined')
    surface.init_cache(tracker.cache,0.3,0.7)
    
    # Step 4
    tracker.surfaces = [surface];


    
    print('Saving Surface')
    tracker.save_surface_definitions_to_file()
    
    print('Changing Permissions to Group Read')    
    
    def file_permissions_groupreadwrite(path):
        try:
            os.chmod(path , 0o770)
            for root,dirs,_ in os.walk(path):
                for d in dirs :
                    try:
                        os.chmod(os.path.join(root,d) , 0o770)
                    except PermissionError:
                        print('permission in subfolder denied')
                        pass
                            
        except PermissionError:
            print('permission in surface folder denied')
            pass
        
    file_permissions_groupreadwrite(fake_gpool.rec_dir)
    
    return(tracker)