Example #1
0
def dct_cut_downsampled(data, cutoff, spacing=0.4):
    '''
    like dctCut but also lowers the sampling rate, creating a compact
    representation from which the whole downsampled data could be
    recovered
    '''
    h, w = np.shape(data)[:2]
    f1 = fft.fftfreq(h * 2, spacing)
    f2 = fft.fftfreq(w * 2, spacing)
    wl = 1. / np.abs(reshape(f1, (2 * h, 1)) + 1j * f2.reshape(1, 2 * w))
    mask = np.int32(wl >= cutoff)
    mirror = reflect2D(data)
    ff = fft.fft2(mirror, axes=(0, 1))
    cut = (ff.T * mask.T).T  # weird shape broadcasting constraints
    empty_cols = find(np.all(mask == 0, 0))
    empty_rows = find(np.all(mask == 0, 1))
    delete_col = len(empty_cols) / 2  #idiv important here
    delete_row = len(empty_rows) / 2  #idiv important here
    keep_cols = w - delete_col
    keep_rows = h - delete_row
    col_mask = np.zeros(w * 2)
    col_mask[:keep_cols] = 1
    col_mask[-keep_cols:] = 1
    col_mask = col_mask == 1
    row_mask = np.zeros(h * 2)
    row_mask[:keep_rows] = 1
    row_mask[-keep_rows:] = 1
    row_mask = row_mask == 1
    cut = cut[row_mask, ...][:, col_mask, ...]
    w, h = keep_cols, keep_rows
    result = fft.ifft2(cut, axes=(0, 1))[:h, :w, ...]
    return result
Example #2
0
def dct_upsample_notrim(data, factor=2):
    '''
    Uses the DCT to supsample array data. Nice for visualization. Uses a
    discrete cosine transform to smoothly supsample image data. Boundary
    conditions are handeled as reflected.

    Data is made symmetric, fourier transformed, then inserted into the
    low-frequency components of a larger array, which is then inverse
    transformed.

    Parameters:
        data (ndarray): frist two dimensions should be height and width.
            data may contain aribtrary number of additional dimensions
        factor (int): supsampling factor.
    '''
    print('ALIGNMENT BUG DO NOT USE YET')
    assert 0
    h, w = np.shape(data)[:2]
    mirrored = reflect2D_1(data)
    ff = fft.fft2(mirrored, axes=(0, 1))
    h2, w2 = np.shape(mirrored)[:2]
    newshape = (h2 * factor, w2 * factor) + np.shape(data)[2:]
    result = np.zeros(newshape, dtype=ff.dtype)
    H = h + 1  #have to add one more on the left to grab the nyqist term
    W = w + 1
    result[:H, :W, ...] = ff[:H, :W, ...]
    result[-h:, :W, ...] = ff[-h:, :W, ...]
    result[:H, -w:, ...] = ff[:H, -w:, ...]
    result[-h:, -w:, ...] = ff[-h:, -w:, ...]
    result = fft.ifft2(result, axes=(0, 1))
    result = result[0:h * factor + factor, 0:w * factor + factor, ...]
    return result * (factor * factor)
Example #3
0
def dct_cut_antialias(data, cutoff, spacing=0.4):
    '''
    Uses brute-force supsampling to anti-alias the frequency space sinc
    function, skirting numerical issues that derives either from
    attempting to evaulate the radial sinc function on a small 2D domain,
    or select a constant frequency cutoff in the frequency space.
    '''
    h, w = np.shape(data)[:2]
    mask = get_mask_antialiased((h, w), 7, spacing, cutoff)
    mirror = reflect2D(data)
    ff2 = fft.fft2(mirror, axes=(0, 1))
    cut = (ff2.T * mask.T).T  # weird shape broadcasting constraints
    result = fft.ifft2(cut, axes=(0, 1))[:h, :w, ...]
    return result
Example #4
0
def dct_cut(data, cutoff, spacing=0.4):
    '''
    Low-pass filters image data by discarding high frequency Fourier
    components.
    Image data is reflected before being processes (i.e.) mirrored boundary
    conditions.
    TODO: I think there is some way to compute the mirrored conditions
    directly without copying the image data.

    This function has been superseded by dct_cut_antialias, which is more
    accurate.
    '''
    print('WARNING DEPRICATED USE dct_cut_antialias')
    h, w = np.shape(data)[:2]
    mask = get_mask((h, w), spacing, cutoff)
    mirror = reflect2D(data)
    ff2 = fft.fft2(mirror, axes=(0, 1))
    cut = (ff2.T * mask.T).T  # weird shape broadcasting constraints
    result = fft.ifft2(cut, axes=(0, 1))[:h, :w, ...]
    return result