Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

Commit

Permalink
Merge pull request #28 from hoechenberger/image-utils
Browse files Browse the repository at this point in the history
Add some image processing
  • Loading branch information
hoechenberger committed Jan 6, 2015
2 parents 32d8a53 + 780caa0 commit 9b43eb3
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 10 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Changelog
=========
****************
v0.4, 2014-11-24
v0.5, 2014-XX-XX
****************
- ``compare_*`` functions renamed to ``gen_*``.
- ``get_cdf*`` functions renamed to ``get_percentiles*``.
Expand All @@ -11,6 +11,7 @@ v0.4, 2014-11-24
- Add sum_cdfs() to calculate the sum of an arbitrary number of CDFs.
- Remove plotting functionality.
- gen_cdf() completely reworked to be more readable and faster (>2x).
- Add ``image`` module

******************
v0.3.1, 2014-09-01
Expand Down
4 changes: 2 additions & 2 deletions pphelper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"""

from .version import __version__
from . import racemodel, hardware
from . import racemodel, hardware, utils, image

__all__ = ['racemodel', 'hardware', 'utils']
__all__ = ['racemodel', 'hardware', 'utils', 'image']
94 changes: 94 additions & 0 deletions pphelper/image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-

"""
pphelper.image
==================
Provides
--------
- ``fft_image`` : Perform an FFT on the supplied image array.
- ``lowpass_filter_image`` : Load an image from a file, and low-pass
filter via a Gaussian kernel.
"""

from __future__ import unicode_literals

from collections import namedtuple
import numpy as np
from scipy.misc import imread
from scipy import ndimage
import pyfftw
from pyfftw.interfaces.scipy_fftpack import fft2

# Enable cache for FFTW to speed up calculations
pyfftw.interfaces.cache.enable()
pyfftw.interfaces.cache.set_keepalive_time(60)


def fft_image(image):
"""
Perform an FFT on the supplied image array.
Parameters
----------
image : ndarray
An array of the image
Returns
-------
namedtuple
A namedtuple containing the the fast-fourier transform, the
amplitude and phase.
"""
image_fft = fft2(image)
image_amplitude = np.abs(image_fft)
image_phase = np.angle(image_fft)

result = namedtuple('Image', 'FFT Amplitude Phase')
return result(image_fft, image_amplitude, image_phase)


def lowpass_filter_image(image=None, filename=None, flatten=False,
sigma=3):
"""
Load an image from a file, and low-pass filter via a Gaussian kernel.
Parameters
----------
image : ndarray, optional
The image to be processed. This will usually have been created
using `scipy.misc.imread` or a similar function.
If this argument is present, `filename` will be ignored.
filename : string, optional
The name of the image file to load and process.
Will be ignored is `image_array` is not `None`.
flatten : bool, optional
Whether to "flatten" the image before filtering,
i.e. convert it to grayscale.
sigma : scalar, optional
The standard deviation for Gaussian kernel.
See `scipy.ndimage.filters.gaussian_filter`.
Returns
-------
ndarray
The lowpass-filtered image.
See Also
--------
scipy.ndimage.gaussian_filter
"""
if (image is None) and (filename is None):
raise AttributeError('Please supply either an image array or an'
'image filename in lowpass_filter_image().')

if image is None:
image = imread(filename, flatten=flatten)

return ndimage.gaussian_filter(image, sigma)
8 changes: 8 additions & 0 deletions pphelper/tests/data/fftw3-wisdom.pickle
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(S'(fftw-3.3.3 fftw_wisdom #x3c273403 #x192df114 #x4d08727c #xe98e9b9d\n)\n'
p0
S'(fftw-3.3.3 fftwf_wisdom #x706526c0 #x2f8b6c85 #x8cd1bb1a #x7c96e03d\n (fftwf_dft_vrank_geq1_register 0 #x10bdd #x10bdd #x0 #x944f503b #xf8534f89 #x76809261 #x52b8aecd)\n (fftwf_codelet_t1fuv_2_sse2 0 #x10bdd #x10bdd #x0 #x2cee21a0 #xfbab248b #x058f86de #xf548f89a)\n (fftwf_codelet_t1fuv_5_sse2 0 #x11bdd #x11bdd #x0 #x1b82f8d3 #x717fb11c #xb27d7e69 #x03ff8807)\n (fftwf_dft_buffered_register 1 #x11bdd #x11bdd #x0 #xd712df88 #x3ee16826 #x2b7042c8 #x46362a36)\n (fftwf_dft_vrank_geq1_register 0 #x10bdd #x10bdd #x0 #xa6e0da61 #xa6dac649 #x375a536c #xb237dc8b)\n (fftwf_dft_r2hc_register 0 #x10bdd #x10bdd #x0 #x2cbe16c0 #x7ddb4319 #x7340c78f #x68f0b812)\n (fftwf_dft_vrank_geq1_register 0 #x11bdd #x11bdd #x0 #x427ecc38 #xcf08e4d1 #xc19d2ad5 #xc87a901e)\n (fftwf_rdft_rank0_register 0 #x10bdd #x10bdd #x0 #xf07fa2f8 #x81ccc2cf #xbe2f3774 #xebc07fdb)\n (fftwf_dft_rank_geq2_register 0 #x11bdd #x11bdd #x0 #xe306c0d6 #x621e38d2 #xc1e339ec #xf4f6cc20)\n (fftwf_dft_nop_register 0 #x10bdd #x10bdd #x0 #xc527c2c6 #xfab4fd30 #x0f5d6b2c #x572ae1aa)\n (fftwf_codelet_t2fv_20_avx 0 #x10bdd #x10bdd #x0 #xc708f2d3 #x9659f94f #xbd8aa7aa #x0b892dea)\n (fftwf_dft_bluestein_register 0 #x10bdd #x10bdd #x0 #x21770fdf #x88d8bede #xedd6d3f8 #xf034ac28)\n (fftwf_dft_r2hc_register 0 #x11bdd #x11bdd #x0 #xcf6484a3 #xeb96624d #x9fb138be #x2d1418ef)\n (fftwf_rdft_rank0_register 3 #x11bdd #x11bdd #x0 #xce01f425 #xb25c5e42 #x6ff25e8b #x576556a2)\n (fftwf_dft_buffered_register 0 #x10bdd #x10bdd #x0 #xe696c6ec #xf1746f89 #x5302f428 #xb1105975)\n (fftwf_dft_generic_register 0 #x11bdd #x11bdd #x0 #x0fe532d1 #x1b0fe2a6 #xe1036c71 #x37ec6e6e)\n (fftwf_dft_vrank_geq1_register 0 #x11bdd #x11bdd #x0 #xa2f7c7a3 #x11bb3f58 #x8e2bfc2d #x35e8fbd1)\n (fftwf_dft_nop_register 0 #x11bdd #x11bdd #x0 #xf018e799 #x52a9f6b1 #x88e103d1 #xbc1674aa)\n (fftwf_codelet_n2fv_16_avx 0 #x10bdd #x10bdd #x0 #xec796509 #xda616af9 #x241273f9 #x4ce72e8f)\n)\n'
p1
S'(fftw-3.3.3 fftwl_wisdom #x2fa95cff #x06d4b84e #x4020c7e8 #xcc9b0a2b\n)\n'
p2
tp3
.
Binary file added pphelper/tests/data/tux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pphelper/tests/data/tux_flattened.npy
Binary file not shown.
Binary file added pphelper/tests/data/tux_flattened_amplitude.npy
Binary file not shown.
Binary file added pphelper/tests/data/tux_flattened_fft.npy
Binary file not shown.
Binary file not shown.
Binary file added pphelper/tests/data/tux_flattened_phase.npy
Binary file not shown.
35 changes: 35 additions & 0 deletions pphelper/tests/test_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-

from pphelper.image import lowpass_filter_image, fft_image
import numpy as np
import pyfftw
import pickle

data_directory = 'pphelper/tests/data/'


# def test_lowpass_filter_image():
# result = lowpass_filter_image(filename=data_directory + 'tux.png',
# flatten=True)
# result_expected = np.load(
# data_directory + 'tux_flattened_lowpass_filtered_sigma_3.npy'
# )
# assert np.array_equal(result, result_expected)
#
#
# def test_fft_image():
# image = np.load(data_directory + 'tux_flattened.npy')
#
# with open(data_directory + 'fftw3-wisdom.pickle', 'rb') as f:
# pyfftw.import_wisdom(pickle.load(f))
# fft, amplitude, phase = fft_image(image)
#
# fft_expected = np.load(data_directory + 'tux_flattened_fft.npy')
# amplitude_expected = np.load(
# data_directory + 'tux_flattened_amplitude.npy'
# )
# phase_expected = np.load(data_directory + 'tux_flattened_phase.npy')
#
# assert np.allclose(fft, fft_expected)
# assert np.allclose(amplitude, amplitude_expected)
# assert np.allclose(phase, phase_expected)
4 changes: 0 additions & 4 deletions pphelper/tests/test_racemodel.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# -*- coding: utf-8 -*-

"""
Unit and (sort-of) integration tests for ``pphelper``.
"""

from __future__ import division
import numpy as np
import pandas as pd
Expand Down
2 changes: 1 addition & 1 deletion pphelper/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.4'
__version__ = '0.5'
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
'experiments.',
long_description=open('README.rst').read(),
install_requires=['sphinxcontrib-napoleon', 'psychopy >= 1.81.03',
'pandas >= 0.14.1', 'matplotlib', 'scipy',
'numpy >= 1.7.2'],
'pyfftw', 'pandas >= 0.14.1', 'matplotlib',
'scipy', 'pillow', 'numpy >= 1.7.2'],
classifiers=['Intended Audience :: Science/Research',
'Programming Language :: Python',
'Topic :: Scientific/Engineering :: Bio-Informatics',
Expand Down

0 comments on commit 9b43eb3

Please sign in to comment.