예제 #1
0
def HighPassFilter(t, px, py, moco_kernel, central_fix):
    '''
    Slow drift correction by robust high-pass filtering

    Effectively forces long-term average pupil fixation to be centrally
    fixated in video space.

    Arguments
    ----
    t : 1D float array
        Video soft timestamps in seconds
    px : 1D float array
        Video space pupil center x
    py : 1D float array
        Video space pupil center y
    moco_kernel : integer
        Temporal kernel width in samples [31]
    central_fix : float tuple
        (x,y) coordinate in video space of central fixation

    Returns
    ----
    px_filt : 1D float array
        Drift corrected video space pupil center x
    py_filt : 1D float array
        Drift corrected video space pupil center y
    '''

    # Force odd-valued kernel width
    moco_kernel = utils._forceodd(moco_kernel)

    print('  Highpass filtering with %d sample kernel' % moco_kernel)

    # Infill NaN regions
    # Replace NaNs with unreasonable but finite value for median filtering
    nan_idx = np.isnan(px)
    px[nan_idx] = -1e9
    py[nan_idx] = -1e9

    # Moving median filter to estimate baseline
    px_bline = medfilt(px, moco_kernel)
    py_bline = medfilt(py, moco_kernel)

    # Restore NaNs to vectors
    px_bline[nan_idx] = np.nan
    py_bline[nan_idx] = np.nan

    # Subtract baseline and add central fixation offset
    px_filt = px - px_bline + central_fix[0]
    py_filt = py - py_bline + central_fix[1]

    return px_filt, py_filt, px_bline, py_bline
예제 #2
0
파일: moco.py 프로젝트: danweflen/mrgaze
def HighPassFilter(t, px, py, moco_kernel, central_fix):
    """
    Slow drift correction by robust high-pass filtering

    Effectively forces long-term average pupil fixation to be centrally
    fixated in video space.

    Arguments
    ----
    t : 1D float array
        Video soft timestamps in seconds
    px : 1D float array
        Video space pupil center x
    py : 1D float array
        Video space pupil center y
    moco_kernel : integer
        Temporal kernel width in samples [31]
    central_fix : float tuple
        (x,y) coordinate in video space of central fixation

    Returns
    ----
    px_filt : 1D float array
        Drift corrected video space pupil center x
    py_filt : 1D float array
        Drift corrected video space pupil center y
    """

    # Force odd-valued kernel width
    moco_kernel = utils._forceodd(moco_kernel)

    print("  Highpass filtering with %d sample kernel" % moco_kernel)

    # Infill NaN regions
    # Replace NaNs with unreasonable but finite value for median filtering
    nan_idx = np.isnan(px)
    px[nan_idx] = -1e9
    py[nan_idx] = -1e9

    # Moving median filter to estimate baseline
    px_bline = medfilt(px, moco_kernel)
    py_bline = medfilt(py, moco_kernel)

    # Restore NaNs to vectors
    px_bline[nan_idx] = np.nan
    py_bline[nan_idx] = np.nan

    # Subtract baseline and add central fixation offset
    px_filt = px - px_bline + central_fix[0]
    py_filt = py - py_bline + central_fix[1]

    return px_filt, py_filt, px_bline, py_bline
예제 #3
0
파일: engine.py 프로젝트: danweflen/mrgaze
def FilterPupilometry(pupils_csv, pupils_filt_csv):
    '''
    DEPRECATED: Temporally filter all pupilometry timeseries
    '''

    if not os.path.isfile(pupils_csv):
        print('* Raw pupilometry CSV file missing - returning')
        return False

    # Read raw pupilometry data
    p = ReadPupilometry(pupils_csv)

    # Sampling time (s)
    dt = p[1,0] - p[0,0]

    # Kernel widths for each metric
    k_area  = utils._forceodd(0.25 / dt)
    k_pupil = 3
    k_blink = utils._forceodd(0.25 / dt)
    k_art   = utils._forceodd(1.0 / dt)

    # Moving median filter
    pf = p.copy()
    pf[:,1] = utils._nanmedfilt(p[:,1], k_area)
    pf[:,2] = utils._nanmedfilt(p[:,2], k_pupil) # Pupil x
    pf[:,3] = utils._nanmedfilt(p[:,3], k_pupil) # Pupil y

    # Blink filter
    pf[:,4] = utils._nanmedfilt(p[:,8], k_blink)

    # Artifact power
    pf[:,5] = utils._nanmedfilt(pf[:,9], k_art)

    # Write filtered timeseries to new CSV file in results directory
    np.savetxt(pupils_filt_csv, pf, fmt='%.6f', delimiter=',')

    # Clean return
    return True
예제 #4
0
def FilterPupilometry(pupils_csv, pupils_filt_csv):
    '''
    DEPRECATED: Temporally filter all pupilometry timeseries
    '''

    if not os.path.isfile(pupils_csv):
        print('* Raw pupilometry CSV file missing - returning')
        return False

    # Read raw pupilometry data
    p = ReadPupilometry(pupils_csv)

    # Sampling time (s)
    dt = p[1, 0] - p[0, 0]

    # Kernel widths for each metric
    k_area = utils._forceodd(0.25 / dt)
    k_pupil = 3
    k_blink = utils._forceodd(0.25 / dt)
    k_art = utils._forceodd(1.0 / dt)

    # Moving median filter
    pf = p.copy()
    pf[:, 1] = utils._nanmedfilt(p[:, 1], k_area)
    pf[:, 2] = utils._nanmedfilt(p[:, 2], k_pupil)  # Pupil x
    pf[:, 3] = utils._nanmedfilt(p[:, 3], k_pupil)  # Pupil y

    # Blink filter
    pf[:, 4] = utils._nanmedfilt(p[:, 8], k_blink)

    # Artifact power
    pf[:, 5] = utils._nanmedfilt(pf[:, 9], k_art)

    # Write filtered timeseries to new CSV file in results directory
    np.savetxt(pupils_filt_csv, pf, fmt='%.6f', delimiter=',')

    # Clean return
    return True
예제 #5
0
파일: preproc.py 프로젝트: wmpauli/pupil
def EstimateBias(fr):
    '''
    Estimate illumination bias field
    
    Arguments
    ----
    fr : 2D numpy uint8 array
        Uncorrected image with biased illumination
    
    Returns
    ----
    bias_field : 2D numpy float array
        Estimated bias multiplier field
    '''

    # Target downsampled matrix size
    nd = 32;

    # Get image dimensions
    ny, nx, nz = fr.shape
    
    # Target maximum dimension is 32
    # Apect ratio preserved approximately
    if nx > ny:
        nxd = nd
        nyd = int(nx/32.0 * ny)
    else:
        nxd = int(ny/32.0 * nx)
        nyd = nd
        
    # Downsample frame
    fr_d = cv2.resize(fr, (nxd, nyd))
    
    # 2D baseline estimation
    # Use large kernel relative to image size
    k = utils._forceodd(nd/2)
    bias_field_d = cv2.medianBlur(fr_d, k)
    
    # Bias correction
    bias_corr_d = 1 - (bias_field_d - np.mean(fr_d)) / fr_d
    
    # Upsample biasfield to same size as original frame
    bias_corr = cv2.resize(bias_corr_d, (nx, ny))
    
    # DEBUG: Flat bias correction
    bias_corr = np.ones_like(fr)
    
    return bias_corr
예제 #6
0
def EstimateBias(fr):
    '''
    Estimate illumination bias field
    
    Arguments
    ----
    fr : 2D numpy uint8 array
        Uncorrected image with biased illumination
    
    Returns
    ----
    bias_field : 2D numpy float array
        Estimated bias multiplier field
    '''

    # Target downsampled matrix size
    nd = 32

    # Get image dimensions
    ny, nx, nz = fr.shape

    # Target maximum dimension is 32
    # Apect ratio preserved approximately
    if nx > ny:
        nxd = nd
        nyd = int(nx / 32.0 * ny)
    else:
        nxd = int(ny / 32.0 * nx)
        nyd = nd

    # Downsample frame
    fr_d = cv2.resize(fr, (nxd, nyd))

    # 2D baseline estimation
    # Use large kernel relative to image size
    k = utils._forceodd(nd / 2)
    bias_field_d = cv2.medianBlur(fr_d, k)

    # Bias correction
    bias_corr_d = 1 - (bias_field_d - np.mean(fr_d)) / fr_d

    # Upsample biasfield to same size as original frame
    bias_corr = cv2.resize(bias_corr_d, (nx, ny))

    # DEBUG: Flat bias correction
    bias_corr = np.ones_like(fr)

    return bias_corr