def get_DFT(shape): """ Get the DFT fast operation dictionary for the given image shape. Parameters ---------- shape : list or tuple The shape of the image which the dictionary is the DFT dictionary. Returns ------- matrix : magni.utils.matrices.Matrix The specified DFT dictionary. See Also -------- magni.utils.matrices.Matrix : The matrix emulator class. Examples -------- Create a dummy image: >>> import numpy as np, magni >>> img = np.random.randn(64, 64) >>> vec = magni.imaging.mat2vec(img) Perform DFT in the ordinary way: >>> dft_normal = magni.imaging._fastops.dft2(vec, img.shape) Perform DFT using the present function: >>> from magni.imaging.dictionaries import get_DFT >>> matrix = get_DFT(img.shape) >>> dft_matrix = matrix.T.dot(vec) Check that the two ways produce the same result: >>> np.allclose(dft_matrix, dft_normal) True """ @_decorate_validation def validate_input(): _levels('shape', (_generic(None, 'explicit collection', len_=2), _numeric(None, 'integer', range_='[1;inf)'))) validate_input() entries = shape[0] * shape[1] return _Matrix(_fastops.idft2, _fastops.dft2, (shape,), (entries, entries))
def get_DCT(shape): """ Get the DCT fast operation dictionary for the given image shape. Parameters ---------- shape : list or tuple The shape of the image which the dictionary is the DCT dictionary. Returns ------- matrix : magni.utils.matrices.Matrix The specified DCT dictionary. See Also -------- magni.utils.matrices.Matrix : The matrix emulator class. Examples -------- Create a dummy image: >>> img = np.random.randn(64, 64) >>> vec = magni.imaging.mat2vec(img) Perform DCT in the ordinary way: >>> dct_normal = magni.imaging._fastops.dct2(vec, *img.shape) Perform DCT using the present function: >>> from magni.imaging.dictionaries import get_DCT >>> matrix = get_DCT(img.shape) >>> dct_matrix = matrix.T.dot(vec) Check that the two ways produce the same result: >>> np.allclose(dct_matrix, dct_normal) True """ _validate_get_DCT(shape) entries = shape[0] * shape[1] return _Matrix(_fastops.idct2, _fastops.dct2, shape, (entries, entries))
def get_DCT(shape, overcomplete_shape=None): """ Get the DCT fast operation dictionary for the given image shape. Parameters ---------- shape : list or tuple The shape of the image for which the dictionary is the DCT dictionary. overcomplete_shape : list or tuple, optional The shape of the (overcomplete) frequency domain for the DCT dictionary. The entries must be greater than or equal to the corresponding entries in `shape`. Returns ------- matrix : magni.utils.matrices.Matrix The specified DCT dictionary. See Also -------- magni.utils.matrices.Matrix : The matrix emulator class. Examples -------- Create a dummy image: >>> import numpy as np, magni >>> img = np.random.randn(64, 64) >>> vec = magni.imaging.mat2vec(img) Perform DCT in the ordinary way: >>> dct_normal = magni.imaging.dictionaries._fastops.dct2(vec, img.shape) Perform DCT using the present function: >>> from magni.imaging.dictionaries import get_DCT >>> matrix = get_DCT(img.shape) >>> dct_matrix = matrix.T.dot(vec) Check that the two ways produce the same result: >>> np.allclose(dct_matrix, dct_normal) True Compute the overcomplete transform (and back again) and check that the resulting image is identical to the original. Notice how this example first ensures that the necessary version of SciPy is available: >>> from pkg_resources import parse_version >>> from scipy import __version__ as _scipy_version >>> if parse_version(_scipy_version) >= parse_version('0.16.0'): ... matrix = get_DCT(img.shape, img.shape) ... dct_matrix = matrix.T.dot(vec) ... vec_roundtrip = matrix.dot(dct_matrix) ... np.allclose(vec, vec_roundtrip) ... else: ... True True """ @_decorate_validation def validate_input(): _levels('shape', (_generic(None, 'explicit collection', len_=2), _numeric(None, 'integer', range_='[1;inf)'))) if overcomplete_shape is not None: _generic('overcomplete_shape', 'explicit collection', len_=2), _numeric(('overcomplete_shape', 0), 'integer', range_='[{};inf)'.format(shape[0])) _numeric(('overcomplete_shape', 1), 'integer', range_='[{};inf)'.format(shape[1])) validate_input() entries = shape[0] * shape[1] if overcomplete_shape is None: args = (shape, ) shape = (entries, entries) else: if _parse_version(_scipy_version) < _parse_version('0.16.0'): raise NotImplementedError( 'Over-complete DCT requires SciPy >= 0.16.0') args = (shape, overcomplete_shape) shape = (entries, overcomplete_shape[0] * overcomplete_shape[1]) return _Matrix(_fastops.idct2, _fastops.dct2, args, shape)
def get_DFT(shape, overcomplete_shape=None): """ Get the DFT fast operation dictionary for the given image shape. Parameters ---------- shape : list or tuple The shape of the image for which the dictionary is the DFT dictionary. overcomplete_shape : list or tuple, optional The shape of the (overcomplete) frequency domain for the DFT dictionary. The entries must be greater than or equal to the corresponding entries in `shape`. Returns ------- matrix : magni.utils.matrices.Matrix The specified DFT dictionary. See Also -------- magni.utils.matrices.Matrix : The matrix emulator class. Examples -------- Create a dummy image: >>> import numpy as np, magni >>> img = np.random.randn(64, 64) >>> vec = magni.imaging.mat2vec(img) Perform DFT in the ordinary way: >>> dft_normal = magni.imaging.dictionaries._fastops.dft2(vec, img.shape) Perform DFT using the present function: >>> from magni.imaging.dictionaries import get_DFT >>> matrix = get_DFT(img.shape) >>> dft_matrix = matrix.conj().T.dot(vec) Check that the two ways produce the same result: >>> np.allclose(dft_matrix, dft_normal) True Compute the overcomplete transform (and back again): >>> matrix = get_DFT(img.shape, img.shape) >>> dft_matrix = matrix.conj().T.dot(vec) >>> vec_roundtrip = matrix.dot(dft_matrix) Check that the twice transformed image is identical to the original: >>> np.allclose(vec, vec_roundtrip) True """ @_decorate_validation def validate_input(): _levels('shape', (_generic(None, 'explicit collection', len_=2), _numeric(None, 'integer', range_='[1;inf)'))) if overcomplete_shape is not None: _generic('overcomplete_shape', 'explicit collection', len_=2), _numeric(('overcomplete_shape', 0), 'integer', range_='[{};inf)'.format(shape[0])) _numeric(('overcomplete_shape', 1), 'integer', range_='[{};inf)'.format(shape[1])) validate_input() entries = shape[0] * shape[1] if overcomplete_shape is None: args = (shape, ) shape = (entries, entries) else: args = (shape, overcomplete_shape) shape = (entries, overcomplete_shape[0] * overcomplete_shape[1]) return _Matrix(_fastops.idft2, _fastops.dft2, args, shape, is_complex=True)
def construct_measurement_matrix(coords, h, w): """ Construct a measurement matrix extracting the specified measurements. Parameters ---------- coords : ndarray The `k` floating point coordinates arranged into a 2D array where each row is a coordinate pair (x, y), such that `coords` has size `k` x 2. h : int The height of the image measured in pixels. w : int The width of the image measured in pixels. Returns ------- Phi : magni.utils.matrices.Matrix The constructed measurement matrix. See Also -------- magni.utils.matrices.Matrix : The matrix emulator class. Notes ----- The function constructs two functions: one for extracting pixels at the coordinates specified and one for the transposed operation. These functions are then wrapped by a matrix emulator which is returned. Examples -------- Create a dummy 5 by 5 pixel image and an example sampling pattern: >>> import numpy as np, magni >>> img = np.arange(25, dtype=np.float).reshape(5, 5) >>> vec = magni.imaging.mat2vec(img) >>> coords = magni.imaging.measurements.uniform_line_sample_image( ... 5, 5, 16., 17) Sample the image in the ordinary way: >>> unique = magni.imaging.measurements.unique_pixels(coords) >>> samples_normal = img[unique[:, 1], unique[:, 0]] >>> samples_normal = samples_normal.reshape((len(unique), 1)) Sample the image using the present function: >>> from magni.imaging.measurements import construct_measurement_matrix >>> matrix = construct_measurement_matrix(coords, *img.shape) >>> samples_matrix = matrix.dot(vec) Check that the two ways produce the same result: >>> np.allclose(samples_matrix, samples_normal) True """ @_decorate_validation def validate_input(): _numeric('coords', ('integer', 'floating'), shape=(-1, 2)) _numeric('h', 'integer', range_='[1;inf)') _numeric('w', 'integer', range_='[1;inf)') _numeric('coords[:, 0]', ('integer', 'floating'), range_='[0;{}]'.format(w), shape=(-1, ), var=coords[:, 0]) _numeric('coords[:, 1]', ('integer', 'floating'), range_='[0;{}]'.format(h), shape=(-1, ), var=coords[:, 1]) validate_input() coords = _unique_pixels(coords) mask = coords[:, 0] * w + coords[:, 1] def measure(vec): return vec[mask] def measure_T(vec): output = np.zeros((h * w, 1), dtype=vec.dtype) output[mask] = vec return output return _Matrix(measure, measure_T, [], (len(mask), h * w))
def construct_measurement_matrix(coords, h, w): """ Construct a measurement matrix extracting the specified measurements. Parameters ---------- coords : ndarray The `k` floating point coordinates arranged into a 2D array where each row is a coordinate pair (x, y), such that `coords` has size `k` x 2. Returns ------- Phi : magni.utils.matrices.Matrix The constructed measurement matrix. See Also -------- magni.utils.matrices.Matrix : The matrix emulator class. Notes ----- The function construct two functions: one for extracting pixels at the coordinates specified and one for the transposed operation. These functions are then wrapped by a matrix emulator which is returned. Examples -------- Create a dummy 5 by 5 pixel image and an example sampling pattern: >>> img = np.arange(25, dtype=np.float).reshape(5, 5) >>> vec = magni.imaging.mat2vec(img) >>> coords = magni.imaging.measurements.uniform_line_sample_image( ... 5, 5, 16., 17) Sample the image in the ordinary way: >>> unique = magni.imaging.measurements.unique_pixels(coords) >>> samples_normal = img[unique[:, 1], unique[:, 0]] >>> samples_normal = samples_normal.reshape((len(unique), 1)) Sample the image using the present function: >>> from magni.imaging.measurements import construct_measurement_matrix >>> matrix = construct_measurement_matrix(coords, *img.shape) >>> samples_matrix = matrix.dot(vec) Check that the two ways produce the same result: >>> np.allclose(samples_matrix, samples_normal) True """ _validate_construct_measurement_matrix(coords, h, w) coords = unique_pixels(coords) mask = coords[:, 0] * w + coords[:, 1] def measure(vec): return vec[mask] def measure_T(vec): output = np.zeros((h * w, 1)) output[mask] = vec return output return _Matrix(measure, measure_T, [], (len(mask), h * w))