def sync_camera_gyro_manual(image_sequence, image_timestamps, gyro_data, gyro_timestamps, full_output=False):
    """Get time offset that aligns image timestamps with gyro timestamps.
    
    Given an image sequence, and gyroscope data, with their respective timestamps,
    calculate the offset that aligns the image data with the gyro data.
    The timestamps must only differ by an offset, not a scale factor.

    This function finds an approximation of the offset *d* that makes this transformation

        t_gyro = t_camera + d
        
    i.e. your new image timestamps should be
    
        image_timestamps_aligned = image_timestamps + d
        
    The offset is calculated using correlation. The parts of the signals to use are
    chosen by the user by picking points in a plot window.

    The offset is accurate up to about +/- 2 frames, so you should run
    *refine_time_offset* if you need better accuracy.
    
    Parameters
    ---------------
    image_sequence : sequence of image data
            This must be either a list or generator that provides a stream of 
            images that are used for optical flow calculations.
    image_timestamps : ndarray
            Timestamps of the images in image_sequence
    gyro_data : (3, N) ndarray
            Gyroscope measurements (angular velocity)
    gyro_timestamps : ndarray
            Timestamps of data in gyro_data
    full_output : bool
            If False, only return the offset, otherwise return extra data
            
    Returns
    --------------
    time_offset  :  float
            The time offset to add to image_timestamps to align the image data
            with the gyroscope data
    flow : ndarray
            (Only if full_output=True)
            The calculated optical flow magnitude
    frame_pair : (int, int)
            The frame pair that was picked for synchronization
    """
    
    flow = tracking.optical_flow_magnitude(image_sequence)
    flow_timestamps = image_timestamps[:-2]    
    
    # Let user select points in both pieces of data
    (frame_pair, gyro_idx) = manual_sync_pick(flow, gyro_timestamps, gyro_data)
    
    # Normalize data
    gyro_abs_max = np.max(np.abs(gyro_data), axis=0)
    gyro_normalized = (gyro_abs_max / np.max(gyro_abs_max)).flatten()
    flow_normalized = (flow / np.max(flow)).flatten()

    rate = lambda ts: len(ts) / (ts[-1] - ts[0])

    # Resample to match highest
    freq_gyro = rate(gyro_timestamps)
    freq_image = rate(flow_timestamps)
    logger.debug("Gyro sampling frequency: %.2f Hz, Image sampling frequency: %.2f Hz", freq_gyro, freq_image)
    
    gyro_part = gyro_normalized[gyro_idx[0]:gyro_idx[1]+1] # only largest
    flow_part = flow_normalized[frame_pair[0]:frame_pair[1]+1]
    
    N = flow_part.size * freq_gyro / freq_image
    flow_part_resampled = ssig.resample(flow_part, N).flatten()
    
    # ) Cross correlate the two signals and find time diff
    corr = ssig.correlate(gyro_part, flow_part_resampled, 'full') # Find the flow in gyro data
 
    i = np.argmax(corr)
    
    t_0_f = flow_timestamps[frame_pair[0]]
    t_1_f = flow_timestamps[frame_pair[1]]
    
    t_off_g = gyro_timestamps[gyro_idx[0] + i]
    t_off_f = t_1_f
    time_offset = t_off_g - t_off_f
    
    if full_output:
        return time_offset, flow, frame_pair
    else:
        return time_offset
Get time offset that aligns image timestamps with gyro timestamps.
    
    Given an image sequence, and gyroscope data, with their respective timestamps,
    calculate the offset that aligns the image data with the gyro data.
    The timestamps must only differ by an offset, not a scale factor.

    This function finds an approximation of the offset *d* that makes this transformation

        t_gyro = t_camera + d
        
    i.e. your new image timestamps should be
    
        image_timestamps_aligned = image_timestamps + d
        
    The offset is calculated using correlation. The parts of the signals to use are
    chosen by the user by picking points in a plot window.

    The offset is accurate up to about +/- 2 frames, so you should run
    *refine_time_offset* if you need better accuracy.
    
    Parameters
    ---------------
    image_sequence : sequence of image data
            This must be either a list or generator that provides a stream of 
            images that are used for optical flow calculations.
    image_timestamps : ndarray
            Timestamps of the images in image_sequence
    gyro_data : (3, N) ndarray
            Gyroscope measurements (angular velocity)
    gyro_timestamps : ndarray
            Timestamps of data in gyro_data
    full_output : bool
            If False, only return the offset, otherwise return extra data
            
    Returns
    --------------
    time_offset  :  float
            The time offset to add to image_timestamps to align the image data
            with the gyroscope data
    flow : ndarray
            (Only if full_output=True)
            The calculated optical flow magnitude
    frame_pair : (int, int)
            The frame pair that was picked for synchronization