예제 #1
0
def find_object(img, thresholds, sizerange, dist_thresh, erode=False, check_centers=True):
    
            body = nim.threshold(img, thresholds[0], thresholds[1])
            
            if erode is not False:
                for i in range(erode):
                    body = binary_erosion(body)
                    
            if check_centers is False:
                blobs = nim.find_blobs(body, sizerange=sizerange, aslist=False)
            else:
                blobs = nim.find_blobs(body, sizerange=sizerange, aslist=True)
            body = blobs
            
            if check_centers:
                centers = nim.center_of_blob(blobs)
                dist = []
                for center in centers:
                    diff = np.linalg.norm( center - np.array(img.shape)/2. )
                    dist.append(diff)
                body = np.zeros_like(img)
                for j, d in enumerate(dist):
                    if d < dist_thresh:
                        body += blobs[j]
                                                
            if body.max() > 1:
                body /= body.max()
            
            if body is None:
                body = np.zeros_like(img)
            
            body = np.array(body*255, dtype=np.uint8)
            
            
            return body
def calc_saccades(trajec, threshold_lo=300, threshold_hi=100000000, min_angle=10, plot=False):
    # thresholds in deg/sec
    # min_angle = minimum angle necessary to count as a saccade, deg
    

    fps = 100.
        
    possible_saccade_array = (np.abs(trajec.heading_smooth_diff)*180/np.pi > threshold_lo)*(np.abs(trajec.heading_smooth_diff)*180/np.pi < threshold_hi)
    possible_saccades = nim.find_blobs(possible_saccade_array, [3,100])
    
    if len(possible_saccades) == 1:
        if np.sum(possible_saccades[0]) == 0:
            possible_saccades = []
    
    trajec.all_saccades = []
    trajec.saccades = []
    trajec.sac_ranges = []
    
    
    if len(possible_saccades) > 0:
        for sac in possible_saccades:
            indices = np.where(sac==1)[0].tolist()
            if len(indices) > 0:
                # expand saccade range to make sure we get full turn
                #lo = np.max([indices[0]-5, 0])
                #hi = np.min([indices[-1]+5, len(trajec.speed)-2])
                #new_indices = np.arange(lo, hi).tolist()
                #tmp = np.where( np.abs(trajec.heading_diff_window[new_indices])*180/np.pi > 350 )[0].tolist()
                #indices = np.array(new_indices)[ tmp ].tolist()
                angle_of_saccade = np.abs(get_angle_of_saccade(trajec, indices)*180./np.pi)
                mean_speed = np.mean(trajec.speed[indices])
                if len(indices) > 3 and angle_of_saccade > 10: # and mean_speed > 0.005:
                    trajec.sac_ranges.append(indices)
                    s_rel = np.argmax( np.abs(trajec.heading_smooth_diff[indices]) )
                    s = indices[s_rel]
                    trajec.all_saccades.append(s)
            
    if plot:
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.set_aspect('equal')
        
        ax.plot(trajec.positions[:,0], trajec.positions[:,1], '-', color='black', alpha=1, linewidth=1, zorder=1)
            
        for sac in trajec.sac_ranges:        
            ax.plot(trajec.positions[sac,0], trajec.positions[sac,1], '-', color='red', alpha=1, linewidth=1, zorder=1+1)
        for s in trajec.all_saccades:
            x = trajec.positions[s, 0]
            y = trajec.positions[s, 1]
            saccade = patches.Circle( (x, y), radius=0.001, facecolor='blue', edgecolor='none', alpha=1, zorder=3)
            ax.add_artist(saccade)
                        
        post = patches.Circle( (0, 0), radius=0.009565, facecolor='black', edgecolor='none', alpha=1)
        ax.add_artist(post)
                        
        fig.savefig('saccade_trajectory.pdf', format='pdf')
예제 #3
0
def get_bouts_of_constant_speed(movieinfo,
                                accel_threshold=.005,
                                duration_threshold=0.2):
    duration_threshold_frames = duration_threshold * float(movieinfo.framerate)

    #speed_diff = np.diff( np.hstack( (movieinfo.scaled.speed[0], movieinfo.scaled.speed) ) )
    #speed_diff_bool_tmp = np.abs(speed_diff) < accel_threshold

    nt, alt_speed = interpolate_to_new_framerate(
        movieinfo, 5000., movieinfo.trajec.epoch_time,
        movieinfo.trajec.velocities[:, 2])
    nt, speed = interpolate_to_new_framerate(movieinfo, 5000.,
                                             movieinfo.timestamps,
                                             movieinfo.scaled.speed)

    speed_diff = np.diff(np.hstack((speed[0], speed)))
    speed_diff_bool_tmp = np.abs(speed_diff) < accel_threshold

    alt_speed_diff = np.diff(np.hstack((alt_speed[0], alt_speed)))
    alt_speed_diff_bool_tmp = np.abs(alt_speed_diff) < .005

    bool_tmp = alt_speed_diff_bool_tmp * speed_diff_bool_tmp

    continuous_sequences = nim.find_blobs(
        bool_tmp, sizerange=[duration_threshold_frames, np.inf], dilate=1)

    calc_pitch_estimate(movieinfo)

    pitch = []
    speed = []
    for i, sequence in enumerate(continuous_sequences):
        indices = np.where(sequence == 1)[0].tolist()

        if np.sum(sequence) > 0:
            print movieinfo.id, len(sequence)

        r1 = np.median(movieinfo.scaled.speed[indices])
        r2 = np.median(movieinfo.scaled.pitchangle[indices])

        if not np.isnan(r1) and not np.isnan(r2):
            pitch.append(r2)
            speed.append(r1)

    return pitch, speed
예제 #4
0
def get_flydra_speed_during_fixation_means(trajec,
                                           fixation_threshold_degrees=5,
                                           fixation_duration_threshold=0.1):
    fixation_indices = get_flydra_indices_during_fixation(
        trajec, fixation_threshold_degrees, fixation_duration_threshold)

    if len(fixation_indices) > 0:
        diffarr = np.diff(np.hstack((fixation_indices[0], fixation_indices)))
        continuous_sequences = nim.find_blobs(diffarr)

        mean = []
        std = []
        for sequence in continuous_sequences:
            indices = np.where(sequence == 1)[0].tolist()
            mean.append(np.mean(trajec.speed[indices]))
            std.append(np.std(trajec.speed[indices]))

        return mean, std
    else:
        return [], []
예제 #5
0
 def get_continuous_data(fixation):
     fixation_angle_bool_tmp = np.abs(fixation) < fixation_threshold_radians
     dist_bool = trajec.dist_to_stim_r > 0.01
     altitude_bool_high = trajec.positions[:, 2] < -.01
     altitude_bool_low = trajec.positions[:, 2] > -.1
     fixation_bool_tmp = fixation_angle_bool_tmp * altitude_bool_high * altitude_bool_low * dist_bool
     #fixation_diff = np.diff( np.hstack( (fixation[0], fixation) ) )
     #fixation_diff_bool_tmp = fixation_diff < 0.0005
     #fixation_bool_tmp = fixation_angle_bool_tmp#*diff_bool_tmp
     #fixation_indices_tmp = np.where( fixation_angle_bool_tmp == True )[0].tolist()
     #fixation_indices_tmp = np.where( np.abs(fixation) < fixation_threshold_radians )[0].tolist()
     continuous_sequences = nim.find_blobs(
         fixation_bool_tmp,
         sizerange=[fixation_duration_threshold_frames, np.inf],
         dilate=False)
     fixation_indices = []
     for sequence in continuous_sequences:
         indices = np.where(sequence == 1)[0].tolist()
         fixation_indices = np.hstack((fixation_indices, indices))
     return fixation_indices.tolist()
예제 #6
0
    def get_continuous_data(fixation_lower):

        lower_fixation_angle_bool_tmp = np.abs(
            fixation_lower) < fixation_threshold_radians
        fixation_lower_diff = np.diff(
            np.hstack((fixation_lower[0], fixation_lower)))
        lower_fixation_diff_bool_tmp = np.abs(fixation_lower_diff) < 0.01745
        lower_fixation_bool_tmp = lower_fixation_angle_bool_tmp  #lower_fixation_diff_bool_tmp #
        lower_fixation_indices_tmp = np.where(
            lower_fixation_bool_tmp == True)[0].tolist()
        #lower_fixation_indices_tmp = np.where( np.abs(fixation_lower) < fixation_threshold_radians )[0].tolist()
        continuous_sequences = nim.find_blobs(
            lower_fixation_indices_tmp,
            sizerange=[fixation_duration_threshold_frames, np.inf],
            dilate=1)
        lower_fixation_indices = []
        for sequence in continuous_sequences:
            indices = np.where(sequence == 1)[0].tolist()
            lower_fixation_indices = np.hstack(
                (lower_fixation_indices,
                 np.array(lower_fixation_indices_tmp)[indices]))
        return lower_fixation_indices.tolist()
예제 #7
0
 def background_subtraction(self, raw, save_raw=False):
 
     mask_center_0 = int(self.mask_center[0])
     mask_center_1 = int(self.mask_center[1])
     mask_0_lo = max(0, mask_center_0 - self.mask_radius)
     mask_0_hi = min(self.width, mask_center_0 + self.mask_radius)
     mask_1_lo = max(0, mask_center_1 - self.mask_radius)
     mask_1_hi = min(self.width, mask_center_1 + self.mask_radius)
     if self.tracking_mask is not None:
         tracking_mask = copy.copy(self.tracking_mask)
         tracking_mask[mask_0_lo:mask_0_hi, mask_1_lo:mask_1_hi] = 1
     
     if self.dynamic_tracking_mask is True:
         # TODO: currently dynamic tracking and such only works for square format cameras 
         #print 'dynamic tracking'
         masked_img = raw[mask_0_lo:mask_0_hi, mask_1_lo:mask_1_hi]
         masked_background = self.background[mask_0_lo:mask_0_hi, mask_1_lo:mask_1_hi]
     else:
         masked_img = raw
         masked_background = self.background
     '''
     if masked_img.shape[0] < 100 or masked_img.shape[1] < 100:
         #print 'no uframe'
         self.dynamic_tracking_mask = False
         uframe = uFrame()
         return uframe, None        
     '''
         
     absdiff = nim.absdiff(masked_img, masked_background)
     if self.dynamic_tracking_mask is False and self.tracking_mask is not None:
         absdiff *= tracking_mask
         
     #absdiff = nim.auto_adjust_levels(absdiff)
     #print 'shape: ', np.shape(absdiff)
     #threshold = max( 10, absdiff.max() - THRESHRANGE )
     #print 'dynamic threshold: ', threshold 
     
     #diffthresh = nim.threshold(absdiff, threshold)
     #print 'max absdiff: ', absdiff.max()
     diffthresh = nim.threshold(absdiff, 15, threshold_hi=255)
     
     # abort early if there is no info:
     s = np.sum(diffthresh)
     if s < 10:  
         uframe = uFrame()
         #print 'no uframe, early abort, sum: ', s 
         self.dynamic_tracking_mask = False
         return uframe, None
     blobs = nim.find_blobs(diffthresh, self.blob_size_range)
     
     if blobs is None:
         self.dynamic_tracking_mask = False
         masked_img = raw
         masked_background = self.background
         
         absdiff = nim.absdiff(masked_img, masked_background)
         diffthresh = nim.threshold(absdiff, threshold)
         if self.dynamic_tracking_mask is False and self.tracking_mask is not None:
             diffthresh *= tracking_mask
         blobs = nim.find_blobs(diffthresh, self.blob_size_range)
     
     
     if blobs is None:
         uframe = uFrame()
         if save_raw is False:
             #print 'no uframe'
             self.dynamic_tracking_mask = False
             return uframe, None
         else:
             frame = Frame(raw, absdiff, diffthresh)
             return uframe, frame
         
     nblobs = blobs.max()
     #print 'n blobs: ', nblobs
     if nblobs > 1:
         blobs = nim.find_biggest_blob(blobs)
     
         
     center = nim.center_of_blob(blobs)
     #print 'center: ', center
     
     if np.isnan(center)[0] or np.isnan(center)[1]:
         uframe = uFrame()
         #print 'no uframe, NaN center!'
         self.dynamic_tracking_mask = False
         return uframe, None
     if center[0] < 1 or center[1] < 1:
         uframe = uFrame()
         #print 'no uframe, NaN center!'
         self.dynamic_tracking_mask = False
         return uframe, None
     
     #print 'center found'
     if 1:
         limlo_x = max( int(center[0])-ROI_RADIUS, 0 )
         limlo_y = max( int(center[1])-ROI_RADIUS, 0 )
         
         limhi_x = min( int(center[0])+ROI_RADIUS, masked_img.shape[0] )
         limhi_y = min( int(center[1])+ROI_RADIUS, masked_img.shape[1] )
         
         # TODO: right now object entering or leaving frame doesnt work perfectly
         uimg = masked_img[limlo_x:limhi_x, limlo_y:limhi_y]
         uimg = copy.copy(uimg)
         uimg_absdiff = absdiff[limlo_x:limhi_x, limlo_y:limhi_y]
         uimg_absdiff = copy.copy(uimg_absdiff)
         uimg_diffthresh = blobs[limlo_x:limhi_x, limlo_y:limhi_y]
         uimg_diffthresh = copy.copy(uimg_diffthresh)
         
         if self.dynamic_tracking_mask is True:
             tmp = np.array([masked_img.shape[0]/2., masked_img.shape[1]/2.])
             center = np.array(self.mask_center) + np.array(center) - tmp
             uimg_indices = [mask_0_lo+limlo_x, mask_0_lo+limhi_x, mask_1_lo+limlo_y, mask_1_lo+limhi_y]
         else:
             uimg_indices = [limlo_x, limhi_x, limlo_y, limhi_y]
         self.dynamic_tracking_mask = True
         self.mask_center = center
         
         uframe = uFrame(center, uimg, uimg_absdiff, uimg_diffthresh) 
         uframe.blobsize = blobs.sum()
         
         uframe.indices = uimg_indices
             
         if save_raw is False:
             del(raw)
             del(absdiff)
             del(diffthresh)
             del(blobs)
             return uframe, None
             
         frame = Frame(masked_img, absdiff, diffthresh)
     return uframe, frame    
def calc_saccades_z(trajec, threshold_lo=200, threshold_hi=100000000, min_angle=10, plot=False):
    # thresholds in deg/sec
    # min_angle = minimum angle necessary to count as a saccade, deg

    fps = 100.
    
    heading_norollover_for_axes = floris_math.remove_angular_rollover(np.arctan2(trajec.speed_xy[:], trajec.velocities[:,2]), 3)
    ## kalman
    
    data = heading_norollover_for_axes.reshape([len(heading_norollover_for_axes),1])
    ss = 3 # state size
    os = 1 # observation size
    F = np.array([   [1,1,0], # process update
                     [0,1,1],
                     [0,0,1]],
                    dtype=np.float)
    H = np.array([   [1,0,0]], # observation matrix
                    dtype=np.float)
    Q = np.eye(ss) # process noise
    Q[0,0] = .01
    Q[1,1] = .01
    Q[2,2] = .01
    R = 1*np.eye(os) # observation noise
    
    initx = np.array([data[0,0], data[1,0]-data[0,0], 0], dtype=np.float)
    initv = 0*np.eye(ss)
    xsmooth,Vsmooth = kalman_math.kalman_smoother(data, F, H, Q, R, initx, initv, plot=False)

    heading_norollover_smooth_for_axes = xsmooth[:,0]
    heading_smooth_diff_for_axes = xsmooth[:,1]*trajec.fps
    heading_for_axes = floris_math.fix_angular_rollover(heading_norollover_for_axes)
    heading_smooth_for_axes = floris_math.fix_angular_rollover(heading_norollover_smooth_for_axes)
    
    trajec.heading_altitude_smooth = heading_smooth_for_axes
    trajec.heading_altitude_smooth_diff = heading_smooth_diff_for_axes
    
    ## saccades
    
    possible_saccade_array = (np.abs(trajec.heading_altitude_smooth_diff)*180/np.pi > threshold_lo)*(np.abs(trajec.heading_altitude_smooth_diff)*180/np.pi < threshold_hi)
    possible_saccades = nim.find_blobs(possible_saccade_array, [3,100])
    
    if len(possible_saccades) == 1:
        if np.sum(possible_saccades[0]) == 0:
            possible_saccades = []
    
    trajec.saccades_z = []
    
    
    if len(possible_saccades) > 0:
        for sac in possible_saccades:
            indices = np.where(sac==1)[0].tolist()
            if len(indices) > 0:
                # expand saccade range to make sure we get full turn
                #lo = np.max([indices[0]-5, 0])
                #hi = np.min([indices[-1]+5, len(trajec.speed)-2])
                #new_indices = np.arange(lo, hi).tolist()
                #tmp = np.where( np.abs(trajec.heading_diff_window[new_indices])*180/np.pi > 350 )[0].tolist()
                #indices = np.array(new_indices)[ tmp ].tolist()
                angle_of_saccade = np.abs(get_angle_of_saccade_z(trajec, indices)*180./np.pi)
                mean_speed = np.mean(trajec.speed[indices])
                if len(indices) > 3 and angle_of_saccade > 10: # and mean_speed > 0.005:
                    trajec.saccades_z.append(indices)

    if plot:
        
        fig = plt.figure()
        ax = fig.add_subplot(111)
        
        ax.plot(trajec.positions[:,0], trajec.positions[:,2], color='black')
        for sac in trajec.saccades_z:
            ax.plot(trajec.positions[sac,0], trajec.positions[sac,2], color='red')