Merged with upstream

This commit is contained in:
Michael Hansen
2013-11-20 14:01:42 -05:00
61 changed files with 513 additions and 320 deletions
+9
View File
@@ -0,0 +1,9 @@
# Configuration for coverage.py
[run]
branch = True
source = skimage
include = */skimage/*
omit =
*/setup.py
+64 -29
View File
@@ -1,42 +1,77 @@
# vim ft=yaml
# travis-ci.org definition for skimage build
#
# We pretend to be erlang because we can't use the python support in
# travis-ci; it uses virtualenvs, they do not have numpy, scipy, matplotlib,
# and it is impractical to build them
language: erlang
env:
- PYTHON=python PYSUF='' PYVER=2.7
- PYTHON=python3 PYSUF='3' PYVER=3.2
install:
- sudo apt-get update # needed for python3-numpy
- sudo apt-get install $PYTHON-dev
# After changing this file, check it on:
# http://lint.travis-ci.org/
language: python
python:
- 2.6
matrix:
include:
- python: 2.7
env:
- PYTHON=python
- PYVER=2.x
- python: 3.2
env:
- PYTHON=python3
- PYVER=3.x
exclude:
- python: 2.6
virtualenv:
system_site_packages: true
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- sudo apt-get update
- sudo apt-get install $PYTHON-numpy
- sudo apt-get install $PYTHON-scipy
- sudo apt-get install $PYTHON-setuptools
- sudo apt-get install $PYTHON-nose
- sudo easy_install$PYSUF pip
- sudo pip-$PYVER install cython
- sudo apt-get install libfreeimage3
- if [[ $PYVER == '2.7' ]]; then sudo apt-get install $PYTHON-matplotlib; fi
- if [[ $PYVER == '3.2' ]]; then sudo pip-$PYVER install git+git://github.com/matplotlib/matplotlib.git@v1.2.x; fi
- sudo pip-$PYVER install flake8
- $PYTHON setup.py build
- sudo $PYTHON setup.py install
- if [[ $PYVER == '2.x' ]]; then
- sudo apt-get install $PYTHON-qt4;
- sudo apt-get install $PYTHON-matplotlib;
- fi
- if [[ $PYVER == '3.x' ]]; then
- sudo apt-get install $PYTHON-pyqt4;
- pip install --use-mirrors matplotlib;
- fi
- pip install --use-mirrors cython
- pip install --use-mirrors flake8
- pip install --use-mirrors six
- pip install --use-mirrors nose-cov
- pip install --use-mirrors python-coveralls
- python check_bento_build.py
install:
- python setup.py build_ext --inplace
script:
# Check if setup.py's match bento.info
- $PYTHON check_bento_build.py
# Change into an innocuous directory and find tests from installation
# Matplotlib settings
- mkdir $HOME/.matplotlib
- touch $HOME/.matplotlib/matplotlibrc
- "echo 'backend : Agg' > $HOME/.matplotlib/matplotlibrc"
- "echo 'backend.qt4 : PyQt4' >> $HOME/.matplotlib/matplotlibrc"
- mkdir for_test
- cd for_test
- nosetests-$PYVER --exe -v --cover-package=skimage skimage
# Change back to repository root directory and run all doc examples
- cd ..
# Run all tests
- nosetests --exe -v --with-doctest --with-cov --cov skimage --cov-config .coveragerc skimage
# Run all doc examples
- export PYTHONPATH=$(pwd):$PYTHONPATH
- for f in doc/examples/*.py; do $PYTHON "$f"; if [ $? -ne 0 ]; then exit 1; fi done
- for f in doc/examples/applications/*.py; do $PYTHON "$f"; if [ $? -ne 0 ]; then exit 1; fi done
# Run pep8 and flake tests
- flake8 --exit-zero --exclude=test_*,six.py skimage doc/examples viewer_examples
after_success:
- coveralls
+4 -1
View File
@@ -7,7 +7,10 @@ clean:
find . -name "*.so" -o -name "*.pyc" -o -name "*.pyx.md5" | xargs rm -f
test:
nosetests skimage
python -c "import skimage, sys, io; sys.exit(skimage.test_verbose())"
doctest:
python -c "import skimage, sys, io; sys.exit(skimage.doctest_verbose())"
coverage:
nosetests skimage --with-coverage --cover-package=skimage
+2 -1
View File
@@ -4,6 +4,7 @@ Version 0.10
* Remove deprecated parameter `epsilon` of `skimage.viewer.LineProfile`
* Remove backwards-compatability of `skimage.measure.regionprops`
* Remove {`ratio`, `sigma`} deprecation warnings of `skimage.segmentation.slic`
and also remove explicit `sigma` parameter from doc-string example
* Change default mode of random_walker segmentation to 'cg_mg' > 'cg' > 'bf',
depending on which optional dependencies are available.
* Remove deprecated `out` parameter of `skimage.morphology.binary_*`
@@ -12,4 +13,4 @@ Version 0.10
* Remove deprecated function `filter.median_filter`
* Remove deprecated `skimage.color.is_gray` and `skimage.color.is_rgb`
functions
* Enable doctests of experimental `skimage.feature.brief`
+2 -2
View File
@@ -45,9 +45,9 @@ Library:
Extension: skimage.io._plugins._colormixer
Sources:
skimage/io/_plugins/_colormixer.pyx
Extension: skimage.measure._find_contours
Extension: skimage.measure._find_contours_cy
Sources:
skimage/measure/_find_contours.pyx
skimage/measure/_find_contours_cy.pyx
Extension: skimage.measure._moments
Sources:
skimage/measure/_moments.pyx
+1
View File
@@ -1,3 +1,4 @@
cython>=0.17
matplotlib>=1.0
numpy>=1.6
six>=1.3.0
+1
View File
@@ -22,6 +22,7 @@ PYTHON_VERSION = (2, 5)
DEPENDENCIES = {
'numpy': (1, 6),
'Cython': (0, 17),
'six': (1, 3),
}
+31 -7
View File
@@ -52,6 +52,7 @@ img_as_ubyte
import os.path as _osp
import imp as _imp
import functools as _functools
import warnings as _warnings
from skimage._shared.utils import deprecated as _deprecated
pkg_dir = _osp.abspath(_osp.dirname(__file__))
@@ -68,24 +69,48 @@ try:
_imp.find_module('nose')
except ImportError:
def _test(verbose=False):
"""This would invoke the skimage test suite, but nose couldn't be
"""This would run all unit tests, but nose couldn't be
imported so the test suite can not run.
"""
raise ImportError("Could not load nose. Unit tests not available.")
def _doctest(verbose=False):
"""This would run all doc tests, but nose couldn't be
imported so the test suite can not run.
"""
raise ImportError("Could not load nose. Doctests not available.")
else:
def _test(verbose=False):
"""Invoke the skimage test suite."""
def _test(doctest=False, verbose=False):
"""Run all unit tests."""
import nose
args = ['', pkg_dir, '--exe']
args = ['', pkg_dir, '--exe', '--ignore-files=^_test']
if verbose:
args.extend(['-v', '-s'])
nose.run('skimage', argv=args)
if doctest:
args.extend(['--with-doctest', '--ignore-files=^\.',
'--ignore-files=^setup\.py$$', '--ignore-files=test'])
# Make sure warnings do not break the doc tests
with _warnings.catch_warnings():
_warnings.simplefilter("ignore")
success = nose.run('skimage', argv=args)
else:
success = nose.run('skimage', argv=args)
# Return sys.exit code
if success:
return 0
else:
return 1
# do not use `test` as function name as this leads to a recursion problem with
# the nose test suite
test = _test
test_verbose = _functools.partial(test, verbose=True)
test_verbose.__doc__ = test.__doc__
doctest = _functools.partial(test, doctest=True)
doctest.__doc__ = doctest.__doc__
doctest_verbose = _functools.partial(test, doctest=True, verbose=True)
doctest_verbose.__doc__ = doctest.__doc__
class _Log(Warning):
@@ -105,10 +130,9 @@ class _FakeLog(object):
"""
self._name = name
import warnings
warnings.simplefilter("always", _Log)
self._warnings = warnings
self._warnings = _warnings
def _warn(self, msg, wtype):
self._warnings.warn('%s: %s' % (wtype, msg), _Log)
+1 -1
View File
@@ -2,7 +2,7 @@ import warnings
import functools
import sys
from . import six
import six
__all__ = ['deprecated', 'get_bound_method_class']
+4 -3
View File
@@ -4,11 +4,12 @@ import itertools
import numpy as np
from skimage import img_as_float
from skimage._shared import six
from skimage._shared.six.moves import zip
from .colorconv import rgb2gray, gray2rgb
from . import rgb_colors
import six
from six.moves import zip
__all__ = ['color_dict', 'label2rgb', 'DEFAULT_COLORS']
@@ -111,7 +112,7 @@ def label2rgb(label, image=None, colors=None, alpha=0.3,
label = label - offset # Make sure you don't modify the input array.
bg_label -= offset
new_type = np.min_scalar_type(label.max())
new_type = np.min_scalar_type(int(label.max()))
if new_type == np.bool:
new_type = np.uint8
label = label.astype(new_type)
+8 -7
View File
@@ -14,7 +14,6 @@ __all__ = ['histogram', 'cumulative_distribution', 'equalize',
def histogram(image, nbins=256):
"""Return histogram of image.
Unlike `numpy.histogram`, this function returns the centers of bins and
does not rebin integer arrays. For integer arrays, each integer value has
its own bin, which improves speed and intensity-resolution.
@@ -40,11 +39,12 @@ def histogram(image, nbins=256):
Examples
--------
>>> from skimage import data
>>> hist = histogram(data.camera())
>>> import matplotlib.pyplot as plt
>>> plt.plot(hist[1], hist[0]) # doctest: +ELLIPSIS
[...]
>>> from skimage import data, exposure, util
>>> image = util.img_as_float(data.camera())
>>> np.histogram(image, bins=2)
(array([107432, 154712]), array([ 0. , 0.5, 1. ]))
>>> exposure.histogram(image, nbins=2)
(array([107432, 154712]), array([ 0.25, 0.75]))
"""
sh = image.shape
if len(sh) == 3 and sh[-1] < 4:
@@ -339,7 +339,8 @@ def adjust_sigmoid(image, cutoff=0.5, gain=10, inv=False):
References
----------
.. [1] Gustav J. Braun, "Image Lightness Rescaling Using Sigmoidal Contrast
Enhancement Functions" http://www.cis.rit.edu/fairchild/PDFs/PAP07.pdf
Enhancement Functions",
http://www.cis.rit.edu/fairchild/PDFs/PAP07.pdf
"""
_assert_non_negative(image)
+20 -19
View File
@@ -57,12 +57,11 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
Examples
--------
>>> import numpy as np
>>> from skimage.feature.corner import corner_peaks, corner_harris
>>> from skimage.feature import pairwise_hamming_distance, brief, match_keypoints_brief
>>> square1 = np.zeros([8, 8], dtype=np.int32)
>>> square1[2:6, 2:6] = 1
>>> square1
>> from skimage.feature import corner_peaks, corner_harris, \\
.. pairwise_hamming_distance, brief, match_keypoints_brief
>> square1 = np.zeros([8, 8], dtype=np.int32)
>> square1[2:6, 2:6] = 1
>> square1
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
@@ -71,21 +70,21 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
>>> keypoints1 = corner_peaks(corner_harris(square1), min_distance=1)
>>> keypoints1
>> keypoints1 = corner_peaks(corner_harris(square1), min_distance=1)
>> keypoints1
array([[2, 2],
[2, 5],
[5, 2],
[5, 5]])
>>> descriptors1, keypoints1 = brief(square1, keypoints1, patch_size=5)
>>> keypoints1
>> descriptors1, keypoints1 = brief(square1, keypoints1, patch_size=5)
>> keypoints1
array([[2, 2],
[2, 5],
[5, 2],
[5, 5]])
>>> square2 = np.zeros([9, 9], dtype=np.int32)
>>> square2[2:7, 2:7] = 1
>>> square2
>> square2 = np.zeros([9, 9], dtype=np.int32)
>> square2[2:7, 2:7] = 1
>> square2
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0],
@@ -95,24 +94,25 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
[0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
>>> keypoints2 = corner_peaks(corner_harris(square2), min_distance=1)
>>> keypoints2
>> keypoints2 = corner_peaks(corner_harris(square2), min_distance=1)
>> keypoints2
array([[2, 2],
[2, 6],
[6, 2],
[6, 6]])
>>> descriptors2, keypoints2 = brief(square2, keypoints2, patch_size=5)
>>> keypoints2
>> descriptors2, keypoints2 = brief(square2, keypoints2, patch_size=5)
>> keypoints2
array([[2, 2],
[2, 6],
[6, 2],
[6, 6]])
>>> pairwise_hamming_distance(descriptors1, descriptors2)
>> pairwise_hamming_distance(descriptors1, descriptors2)
array([[ 0.03125 , 0.3203125, 0.3671875, 0.6171875],
[ 0.3203125, 0.03125 , 0.640625 , 0.375 ],
[ 0.375 , 0.6328125, 0.0390625, 0.328125 ],
[ 0.625 , 0.3671875, 0.34375 , 0.0234375]])
>>> match_keypoints_brief(keypoints1, descriptors1, keypoints2, descriptors2)
>> match_keypoints_brief(keypoints1, descriptors1,
.. keypoints2, descriptors2)
array([[[ 2, 2],
[ 2, 2]],
@@ -126,6 +126,7 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
[ 6, 6]]])
"""
np.random.seed(sample_seed)
image = np.squeeze(image)
+69 -39
View File
@@ -2,7 +2,7 @@ import numpy as np
from scipy import ndimage
from scipy import stats
from skimage.color import rgb2grey
from skimage.util import img_as_float
from skimage.util import img_as_float, pad
from skimage.feature import peak_local_max
@@ -70,10 +70,10 @@ def corner_kitchen_rosenfeld(image):
The corner measure is calculated as follows::
(imxx * imy**2 + imyy * imx**2 - 2 * imxy * imx * imy)
------------------------------------------------------
(imx**2 + imy**2)
/ (imx**2 + imy**2)
Where imx and imy are the first and imxx, imxy, imyy the second derivatives.
Where imx and imy are the first and imxx, imxy, imyy the second
derivatives.
Parameters
----------
@@ -147,19 +147,19 @@ def corner_harris(image, method='k', k=0.05, eps=1e-6, sigma=1):
Examples
--------
>>> from skimage.feature import corner_harris, corner_peaks
>>> square = np.zeros([10, 10])
>>> square = np.zeros([10, 10], dtype=int)
>>> square[2:8, 2:8] = 1
>>> square
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> corner_peaks(corner_harris(square), min_distance=1)
array([[2, 2],
[2, 7],
@@ -217,19 +217,19 @@ def corner_shi_tomasi(image, sigma=1):
Examples
--------
>>> from skimage.feature import corner_shi_tomasi, corner_peaks
>>> square = np.zeros([10, 10])
>>> square = np.zeros([10, 10], dtype=int)
>>> square[2:8, 2:8] = 1
>>> square
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> corner_peaks(corner_shi_tomasi(square), min_distance=1)
array([[2, 2],
[2, 7],
@@ -285,17 +285,17 @@ def corner_foerstner(image, sigma=1):
>>> from skimage.feature import corner_foerstner, corner_peaks
>>> square = np.zeros([10, 10])
>>> square[2:8, 2:8] = 1
>>> square
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> square.astype(int)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
>>> w, q = corner_foerstner(square)
>>> accuracy_thresh = 0.5
>>> roundness_thresh = 0.3
@@ -351,10 +351,37 @@ def corner_subpix(image, corners, window_size=11, alpha=0.99):
foerstner87.fast.pdf
.. [2] http://en.wikipedia.org/wiki/Corner_detection
Examples
--------
>>> from skimage.feature import corner_harris, corner_peaks, corner_subpix
>>> img = np.zeros((10, 10), dtype=int)
>>> img[:5, :5] = 1
>>> img[5:, 5:] = 1
>>> img
array([[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1]])
>>> coords = corner_peaks(corner_harris(img), min_distance=2)
>>> coords_subpix = corner_subpix(img, coords, window_size=7)
>>> coords_subpix
array([[ 4.5, 4.5]])
"""
# window extent in one direction
wext = (window_size - 1) / 2
wext = (window_size - 1) // 2
image = pad(image, pad_width=wext, mode='constant', constant_values=0)
# add pad width, make sure to not modify the input values in-place
corners = corners + wext
# normal equation arrays
N_dot = np.zeros((2, 2), dtype=np.double)
@@ -449,6 +476,9 @@ def corner_subpix(image, corners, window_size=11, alpha=0.99):
elif corner_class == 1:
corners_subpix[i, :] = y0 + est_edge[0], x0 + est_edge[1]
# subtract pad width
corners_subpix -= wext
return corners_subpix
@@ -470,7 +500,7 @@ def corner_peaks(image, min_distance=10, threshold_abs=0, threshold_rel=0.1,
Examples
--------
>>> from skimage.feature import peak_local_max, corner_peaks
>>> from skimage.feature import peak_local_max
>>> response = np.zeros((5, 5))
>>> response[2:4, 2:4] = 1
>>> response
+2 -2
View File
@@ -35,7 +35,7 @@ def corner_moravec(image, Py_ssize_t window_size=1):
Examples
--------
>>> from skimage.feature import moravec, peak_local_max
>>> from skimage.feature import corner_moravec, peak_local_max
>>> square = np.zeros([7, 7])
>>> square[3, 3] = 1
>>> square
@@ -46,7 +46,7 @@ def corner_moravec(image, Py_ssize_t window_size=1):
[ 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0.]])
>>> moravec(square)
>>> corner_moravec(square)
array([[ 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 1., 1., 0., 0.],
+17 -1
View File
@@ -1,5 +1,5 @@
import numpy as np
from numpy.testing import assert_array_equal
from numpy.testing import assert_array_equal, assert_almost_equal
from skimage import data
from skimage import img_as_float
@@ -101,6 +101,22 @@ def test_subpix():
assert_array_equal(subpix[0], (24.5, 24.5))
def test_subpix_border():
img = np.zeros((50, 50))
img[1:25,1:25] = 255
img[25:-1,25:-1] = 255
corner = corner_peaks(corner_harris(img), min_distance=1)
subpix = corner_subpix(img, corner, window_size=11)
ref = np.array([[ 0.52040816, 0.52040816],
[ 0.52040816, 24.47959184],
[24.47959184, 0.52040816],
[24.5 , 24.5 ],
[24.52040816, 48.47959184],
[48.47959184, 24.52040816],
[48.47959184, 48.47959184]])
assert_almost_equal(subpix, ref)
def test_num_peaks():
"""For a bunch of different values of num_peaks, check that
peak_local_max returns exactly the right amount of peaks. Test
+3 -2
View File
@@ -86,9 +86,10 @@ def test_daisy_normalization():
def test_daisy_visualization():
img = img_as_float(data.lena()[:128, :128].mean(axis=2))
img = img_as_float(data.lena()[:32, :32].mean(axis=2))
descs, descs_img = daisy(img, visualize=True)
assert(descs_img.shape == (128, 128, 3))
assert(descs_img.shape == (32, 32, 3))
if __name__ == '__main__':
from numpy import testing
+2 -17
View File
@@ -30,14 +30,6 @@ def _denoise_tv_chambolle_3d(im, weight=100, eps=2.e-4, n_iter_max=200):
-----
Rudin, Osher and Fatemi algorithm.
Examples
--------
>>> x, y, z = np.ogrid[0:40, 0:40, 0:40]
>>> mask = (x - 22)**2 + (y - 20)**2 + (z - 17)**2 < 8**2
>>> mask = mask.astype(np.float)
>>> mask += 0.2 * np.random.randn(*mask.shape)
>>> res = denoise_tv_chambolle(mask, weight=100)
"""
px = np.zeros_like(im)
@@ -121,13 +113,6 @@ def _denoise_tv_chambolle_2d(im, weight=50, eps=2.e-4, n_iter_max=200):
applications, Journal of Mathematical Imaging and Vision,
Springer, 2004, 20, 89-97.
Examples
--------
>>> from skimage import color, data
>>> lena = color.rgb2gray(data.lena())
>>> lena += 0.5 * lena.std() * np.random.randn(*lena.shape)
>>> denoised_lena = denoise_tv_chambolle(lena, weight=60)
"""
px = np.zeros_like(im)
@@ -224,13 +209,13 @@ def denoise_tv_chambolle(im, weight=50, eps=2.e-4, n_iter_max=200,
2D example on Lena image:
>>> from skimage import color, data
>>> lena = color.rgb2gray(data.lena())
>>> lena = color.rgb2gray(data.lena())[:50, :50]
>>> lena += 0.5 * lena.std() * np.random.randn(*lena.shape)
>>> denoised_lena = denoise_tv_chambolle(lena, weight=60)
3D example on synthetic data:
>>> x, y, z = np.ogrid[0:40, 0:40, 0:40]
>>> x, y, z = np.ogrid[0:20, 0:20, 0:20]
>>> mask = (x - 22)**2 + (y - 20)**2 + (z - 17)**2 < 8**2
>>> mask = mask.astype(np.float)
>>> mask += 0.2*np.random.randn(*mask.shape)
+4 -4
View File
@@ -36,12 +36,12 @@ def rank_order(image):
>>> a = np.array([[1, 4, 5], [4, 4, 1], [5, 1, 1]])
>>> a
array([[1, 4, 5],
[4, 4, 1],
[5, 1, 1]])
[4, 4, 1],
[5, 1, 1]])
>>> rank_order(a)
(array([[0, 1, 2],
[1, 1, 0],
[2, 0, 0]], dtype=uint32), array([1, 4, 5]))
[1, 1, 0],
[2, 0, 0]], dtype=uint32), array([1, 4, 5]))
>>> b = np.array([-1., 2.5, 3.1, 2.5])
>>> rank_order(b)
(array([0, 1, 2, 1], dtype=uint32), array([-1. , 2.5, 3.1]))
+3 -3
View File
@@ -62,12 +62,12 @@ class LPIFilter2D(object):
>>> filter_params = {'kw1': 1, 'kw2': 2, 'kw3': 3}
>>> impulse_response(r, c, **filter_params)
Examples
--------
Gaussian filter:
Use a 1-D gaussian in each direction without normalization
coefficients.
Gaussian filter: Use a 1-D gaussian in each direction without
normalization coefficients.
>>> def filt_func(r, c, sigma = 1):
... return np.exp(-np.hypot(r, c)/sigma)
>>> filter = LPIFilter2D(filt_func)
+4 -4
View File
@@ -1,10 +1,10 @@
from .generic import (autolevel, bottomhat, equalize, gradient, maximum, mean,
subtract_mean, median, minimum, modal, enhance_contrast,
pop, threshold, tophat, noise_filter, entropy, otsu)
from .percentile import (autolevel_percentile, gradient_percentile,
mean_percentile, subtract_mean_percentile,
enhance_contrast_percentile, percentile,
pop_percentile, threshold_percentile)
from ._percentile import (autolevel_percentile, gradient_percentile,
mean_percentile, subtract_mean_percentile,
enhance_contrast_percentile, percentile,
pop_percentile, threshold_percentile)
from .bilateral import mean_bilateral, pop_bilateral
from skimage._shared.utils import deprecated
+4 -4
View File
@@ -247,8 +247,8 @@ def maximum(image, selem, out=None, mask=None, shift_x=False, shift_y=False):
--------
skimage.morphology.dilation
Note
----
Notes
-----
* the lower algorithm complexity makes the rank.maximum() more efficient
for larger images and structuring elements
@@ -397,8 +397,8 @@ def minimum(image, selem, out=None, mask=None, shift_x=False, shift_y=False):
--------
skimage.morphology.erosion
Note
----
Notes
-----
* the lower algorithm complexity makes the rank.minimum() more efficient
for larger images and structuring elements
+1 -1
View File
@@ -437,7 +437,7 @@ def test_16bit():
image[10, 10] = value
assert rank.minimum(image, selem)[10, 10] == 0
assert rank.maximum(image, selem)[10, 10] == value
assert rank.mean(image, selem)[10, 10] == value / selem.size
assert rank.mean(image, selem)[10, 10] == int(value / selem.size)
def test_bilateral():
+1
View File
@@ -11,6 +11,7 @@ def configuration(parent_package='', top_path=None):
config = Configuration('filter', parent_package, top_path)
config.add_data_dir('tests')
config.add_data_dir('rank/tests')
cython(['_ctmf.pyx'], working_path=base_path)
cython(['_denoise_cy.pyx'], working_path=base_path)
+1 -1
View File
@@ -57,7 +57,7 @@ def threshold_adaptive(image, block_size, method='gaussian', offset=0,
Examples
--------
>>> from skimage.data import camera
>>> image = camera()
>>> image = camera()[:50, :50]
>>> binary_image1 = threshold_adaptive(image, 15, 'mean')
>>> func = lambda arr: arr.mean()
>>> binary_image2 = threshold_adaptive(image, 15, 'generic', param=func)
+3 -2
View File
@@ -12,10 +12,11 @@ import tempfile
from io import BytesIO
import numpy as np
import six
from skimage.io._plugins import call as call_plugin
from skimage.color import rgb2grey
from skimage._shared import six
# Shared image queue
@@ -247,7 +248,7 @@ def show():
>>> for i in range(4):
... io.imshow(np.random.random((50, 50)))
>>> io.show()
>>> io.show() # doctest: +SKIP
'''
return call_plugin('_app_show')
+2 -2
View File
@@ -11,7 +11,7 @@ except ImportError:
from skimage.util import img_as_ubyte
from skimage._shared import six
from six import string_types
def imread(fname, dtype=None):
@@ -106,7 +106,7 @@ def imsave(fname, arr, format_str=None):
arr = arr.astype(np.uint8)
# default to PNG if file-like object
if not isinstance(fname, six.string_types) and format_str is None:
if not isinstance(fname, string_types) and format_str is None:
format_str = "PNG"
img = Image.fromstring(mode, (arr.shape[1], arr.shape[0]), arr.tostring())
+6 -9
View File
@@ -10,7 +10,8 @@ from copy import copy
import numpy as np
from ._io import imread
from .._shared import six
import six
def concatenate_images(ic):
@@ -95,18 +96,14 @@ class MultiImage(object):
--------
>>> from skimage import data_dir
>>> img = MultiImage(data_dir + '/multipage.tif')
>>> len(img)
>>> img = MultiImage(data_dir + '/multipage.tif') # doctest: +SKIP
>>> len(img) # doctest: +SKIP
2
>>> for frame in img:
... print(frame.shape)
>>> for frame in img: # doctest: +SKIP
... print(frame.shape) # doctest: +SKIP
(15, 10)
(15, 10)
The two frames in this image can be shown with matplotlib:
.. plot:: show_collection.py
"""
def __init__(self, filename, conserve_memory=True, dtype=None):
"""Load a multi-img."""
+2 -1
View File
@@ -12,7 +12,8 @@ from skimage import data_dir
from skimage.io import ImageCollection, MultiImage
from skimage.io.collection import alphanumeric_key
from skimage.io import Image as ioImage
from skimage._shared import six
import six
try:
+6 -4
View File
@@ -53,9 +53,10 @@ def test_imread_uint16_big_endian():
assert img.dtype == np.uint16
assert_array_almost_equal(img, expected)
@skipif(not FI_available)
def test_write_multipage():
shape = (64,64,64)
shape = (64, 64, 64)
x = np.ones(shape, dtype=np.uint8) * np.random.random(shape) * 255
x = x.astype(np.uint8)
f = NamedTemporaryFile(suffix='.tif')
@@ -64,7 +65,8 @@ def test_write_multipage():
fi.write_multipage(x, fname)
y = fi.read_multipage(fname)
assert_array_equal(x, y)
class TestSave:
def roundtrip(self, dtype, x, suffix):
f = NamedTemporaryFile(suffix='.' + suffix)
@@ -94,13 +96,13 @@ class TestSave:
def test_metadata():
meta = fi.read_metadata(os.path.join(si.data_dir, 'multipage.tif'))
assert meta[('EXIF_MAIN', 'Orientation')] == 1
assert meta[('EXIF_MAIN', 'Software')].startswith('ImageMagick')
assert meta[('EXIF_MAIN', 'Software')].startswith('I')
meta = fi.read_multipage_metadata(os.path.join(si.data_dir,
'multipage.tif'))
assert len(meta) == 2
assert meta[0][('EXIF_MAIN', 'Orientation')] == 1
assert meta[1][('EXIF_MAIN', 'Software')].startswith('ImageMagick')
assert meta[1][('EXIF_MAIN', 'Software')].startswith('I')
if __name__ == "__main__":
+2 -1
View File
@@ -8,7 +8,8 @@ from tempfile import NamedTemporaryFile
from skimage import data_dir
from skimage.io import (imread, imsave, use_plugin, reset_plugins,
Image as ioImage)
from skimage._shared.six import BytesIO
from six import BytesIO
try:
+1 -2
View File
@@ -1,4 +1,4 @@
from .find_contours import find_contours
from ._find_contours import find_contours
from ._marching_cubes import marching_cubes, mesh_surface_area
from ._regionprops import regionprops, perimeter
from ._structural_similarity import structural_similarity
@@ -23,6 +23,5 @@ __all__ = ['find_contours',
'moments_central',
'moments_normalized',
'moments_hu',
'sum_blocks',
'marching_cubes',
'mesh_surface_area']
@@ -1,5 +1,5 @@
import numpy as np
from . import _find_contours
from . import _find_contours_cy
from collections import deque
@@ -115,8 +115,8 @@ def find_contours(array, level,
positive_orientation not in _param_options):
raise ValueError('Parameters "fully_connected" and'
' "positive_orientation" must be either "high" or "low".')
point_list = _find_contours.iterate_and_store(array, level,
fully_connected == 'high')
point_list = _find_contours_cy.iterate_and_store(array, level,
fully_connected == 'high')
contours = _assemble_contours(_take_2(point_list))
if positive_orientation == 'high':
contours = [c[::-1] for c in contours]
+4 -4
View File
@@ -74,13 +74,13 @@ def marching_cubes(volume, level, spacing=(1., 1., 1.)):
Regarding visualization of algorithm output, the ``mayavi`` package
is recommended. To contour a volume named `myvolume` about the level 0.0::
>>> from mayavi import mlab
>>> verts, tris = marching_cubes(myvolume, 0.0, (1., 1., 2.))
>>> from mayavi import mlab # doctest: +SKIP
>>> verts, tris = marching_cubes(myvolume, 0.0, (1., 1., 2.)) # doctest: +SKIP
>>> mlab.triangular_mesh([vert[0] for vert in verts],
... [vert[1] for vert in verts],
... [vert[2] for vert in verts],
... tris)
>>> mlab.show()
... tris) # doctest: +SKIP
>>> mlab.show() # doctest: +SKIP
References
----------
+6 -3
View File
@@ -479,13 +479,16 @@ def regionprops(label_image, properties=None,
Examples
--------
>>> from skimage.data import coins
>>> from skimage import data, util
>>> from skimage.morphology import label
>>> img = coins() > 110
>>> img = util.img_as_ubyte(data.coins()) > 110
>>> label_img = label(img)
>>> props = regionprops(label_img)
>>> props[0].centroid # centroid of first labelled object
(22.729879860483141, 81.912285234465827)
>>> props[0]['centroid'] # centroid of first labelled object
(22.729879860483141, 81.912285234465827)
"""
label_image = np.squeeze(label_image)
@@ -505,7 +508,7 @@ def regionprops(label_image, properties=None,
for i, sl in enumerate(objects):
if sl is None:
continue
label = i + 1
props = _RegionProperties(sl, label, label_image,
+5 -7
View File
@@ -28,27 +28,25 @@ def block_reduce(image, block_size, func=np.sum, cval=0):
--------
>>> from skimage.measure import block_reduce
>>> image = np.arange(3*3*4).reshape(3, 3, 4)
>>> image
>>> image # doctest: +NORMALIZE_WHITESPACE
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]],
[[24, 25, 26, 27],
[28, 29, 30, 31],
[32, 33, 34, 35]]])
>>> block_reduce(image, block_size=(3, 3, 1), func=np.mean)
array([[[ 16., 17., 18., 19.]]])
>>> block_reduce(image, block_size=(1, 3, 4), func=np.max)
>>> image_max1 = block_reduce(image, block_size=(1, 3, 4), func=np.max)
>>> image_max1 # doctest: +NORMALIZE_WHITESPACE
array([[[11]],
[[23]],
[[35]]])
>>> block_reduce(image, block_size=(3, 1, 4), func=np.max)
>>> image_max2 = block_reduce(image, block_size=(3, 1, 4), func=np.max)
>>> image_max2 # doctest: +NORMALIZE_WHITESPACE
array([[[27],
[31],
[35]]])
+19 -15
View File
@@ -550,21 +550,23 @@ def ransac(data, model_class, min_samples, residual_threshold,
>>> model = EllipseModel()
>>> model.estimate(data)
>>> model._params
array([ 4.85808595e+02, 4.51492793e+02, 1.15018491e+03,
5.52428289e+00, 7.32420126e-01])
>>> model._params # doctest: +SKIP
array([ -3.30354146e+03, -2.87791160e+03, 5.59062118e+03,
7.84365066e+00, 7.19203152e-01])
Estimate ellipse model using RANSAC:
>>> ransac_model, inliers = ransac(data, EllipseModel, 5, 3, max_trials=50)
>>> # ransac_model._params, inliers
Should give the correct result estimated without the faulty data::
[ 20.12762373, 29.73563061, 4.81499637, 10.4743584, 0.05217117]
[ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
>>> ransac_model._params
array([ 20.12762373, 29.73563063, 4.81499637, 10.4743584 , 0.05217117])
>>> inliers
array([False, False, False, False, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True], dtype=bool)
Robustly estimate geometric transformation:
@@ -578,10 +580,12 @@ def ransac(data, model_class, min_samples, residual_threshold,
>>> dst[2] = (50, 50)
>>> model, inliers = ransac((src, dst), SimilarityTransform, 2, 10)
>>> inliers
array([ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49])
array([False, False, False, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True], dtype=bool)
"""
+2 -2
View File
@@ -12,11 +12,11 @@ def configuration(parent_package='', top_path=None):
config = Configuration('measure', parent_package, top_path)
config.add_data_dir('tests')
cython(['_find_contours.pyx'], working_path=base_path)
cython(['_find_contours_cy.pyx'], working_path=base_path)
cython(['_moments.pyx'], working_path=base_path)
cython(['_marching_cubes_cy.pyx'], working_path=base_path)
config.add_extension('_find_contours', sources=['_find_contours.c'],
config.add_extension('_find_contours_cy', sources=['_find_contours_cy.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_moments', sources=['_moments.c'],
include_dirs=[get_numpy_include_dirs()])
+2 -3
View File
@@ -69,7 +69,7 @@ def skeletonize(image):
[0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0]], dtype=uint8)
>>> skel = skeletonize(ellipse)
>>> skel
>>> skel.astype(np.uint8)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -212,7 +212,6 @@ def medial_axis(image, mask=None, return_distance=False):
Examples
--------
>>> from skimage import morphology
>>> square = np.zeros((7, 7), dtype=np.uint8)
>>> square[1:-1, 2:-2] = 1
>>> square
@@ -223,7 +222,7 @@ def medial_axis(image, mask=None, return_distance=False):
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
>>> morphology.medial_axis(square).astype(np.uint8)
>>> medial_axis(square).astype(np.uint8)
array([[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
+2 -2
View File
@@ -88,8 +88,8 @@ def convex_hull_object(image, neighbors=8):
hull : ndarray of bool
Binary image with pixels in convex hull set to True.
Note
----
Notes
-----
This function uses skimage.morphology.label to define unique objects,
finds the convex hull of each using convex_hull_image, and combines
these regions with logical OR. Be aware the convex hulls of unconnected
+3 -3
View File
@@ -37,17 +37,17 @@ def remove_small_objects(ar, min_size=64, connectivity=1, in_place=False):
>>> a = np.array([[0, 0, 0, 1, 0],
... [1, 1, 1, 0, 0],
... [1, 1, 1, 0, 1]], bool)
>>> b = morphology.remove_small_connected_components(a, 6)
>>> b = morphology.remove_small_objects(a, 6)
>>> b
array([[False, False, False, False, False],
[ True, True, True, False, False],
[ True, True, True, False, False]], dtype=bool)
>>> c = morphology.remove_small_connected_components(a, 7, connectivity=2)
>>> c = morphology.remove_small_objects(a, 7, connectivity=2)
>>> c
array([[False, False, False, True, False],
[ True, True, True, False, False],
[ True, True, True, False, False]], dtype=bool)
>>> d = morphology.remove_small_connected_components(a, 6, in_place=True)
>>> d = morphology.remove_small_objects(a, 6, in_place=True)
>>> d is a
True
"""
+2 -1
View File
@@ -118,7 +118,8 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None):
>>> distance = ndimage.distance_transform_edt(image)
>>> from skimage.feature import peak_local_max
>>> local_maxi = peak_local_max(distance, labels=image,
... footprint=np.ones((3, 3)))
... footprint=np.ones((3, 3)),
... indices=False)
>>> markers = ndimage.label(local_maxi)[0]
>>> labels = watershed(-distance, markers, mask=image)
+11 -11
View File
@@ -28,17 +28,17 @@ We can create a Picture object open opening an image file
>>> picture = novice.open(data.data_dir + '/chelsea.png')
Pictures know their format
>>> print picture.format
png
>>> picture.format
'png'
... and where they came from
>>> print picture.path.endswith('chelsea.png')
>>> picture.path.endswith('chelsea.png')
True
... and their size
>>> print picture.size
>>> picture.size
(451, 300)
>>> print picture.width
>>> picture.width
451
Changing `size` resizes the picture.
@@ -51,9 +51,9 @@ and know their location in the picture.
... pixel.red /= 2
Pictures know if they've been modified from the original file
>>> print picture.modified
>>> picture.modified
True
>>> print picture.path
>>> print(picture.path)
None
Pictures can be indexed like arrays
@@ -61,11 +61,11 @@ Pictures can be indexed like arrays
Saving the picture updates the path attribute, format, and modified state.
>>> picture.save('save-demo.jpg')
>>> print picture.path.endswith('save-demo.jpg')
>>> picture.path.endswith('save-demo.jpg')
True
>>> print picture.format
jpeg
>>> print picture.modified
>>> picture.format
'jpeg'
>>> picture.modified
False
"""
+1 -2
View File
@@ -8,13 +8,12 @@ from skimage import io
from skimage import img_as_ubyte
from skimage.transform import resize
from skimage.color import color_dict
from skimage._shared import six
import six
from six.moves.urllib_parse import urlparse
from six.moves.urllib import request
urlopen = request.urlopen
# Convert colors from `skimage.color` to uint8 and allow access through
# dict or a named tuple.
color_dict = dict((name, tuple(int(255 * c + 0.5) for c in rgb))
+4 -1
View File
@@ -114,9 +114,12 @@ def relabel_sequential(label_field, offset=1):
>>> relab
array([5, 5, 6, 6, 7, 9, 8])
"""
m = label_field.max()
if not np.issubdtype(label_field.dtype, np.int):
new_type = np.min_scalar_type(int(m))
label_field = label_field.astype(new_type)
labels = np.unique(label_field)
labels0 = labels[labels != 0]
m = labels.max()
if m == len(labels0): # nothing to do, already 1...n labels
return label_field, labels, labels
forward_map = np.zeros(m+1, int)
+6 -3
View File
@@ -87,9 +87,12 @@ def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=None,
>>> from skimage.segmentation import slic
>>> from skimage.data import lena
>>> img = lena()
>>> segments = slic(img, n_segments=100, compactness=10)
>>> # Increasing the compactness parameter yields more square regions
>>> segments = slic(img, n_segments=100, compactness=20)
>>> segments = slic(img, n_segments=100, compactness=10, sigma=0)
Increasing the compactness parameter yields more square regions:
>>> segments = slic(img, n_segments=100, compactness=20, sigma=0)
"""
if sigma is None:
+12
View File
@@ -61,5 +61,17 @@ def test_relabel_sequential_offset5_with0():
assert_array_equal(inv, inv_ref)
def test_relabel_sequential_dtype():
ar = np.array([1, 1, 5, 5, 8, 99, 42, 0], dtype=float)
ar_relab, fw, inv = relabel_sequential(ar, offset=5)
ar_relab_ref = np.array([5, 5, 6, 6, 7, 9, 8, 0])
assert_array_equal(ar_relab, ar_relab_ref)
fw_ref = np.zeros(100, int)
fw_ref[1] = 5; fw_ref[5] = 6; fw_ref[8] = 7; fw_ref[42] = 8; fw_ref[99] = 9
assert_array_equal(fw, fw_ref)
inv_ref = np.array([0, 0, 0, 0, 0, 1, 5, 8, 42, 99])
assert_array_equal(inv, inv_ref)
if __name__ == "__main__":
np.testing.run_module_suite()
+13 -11
View File
@@ -1,11 +1,11 @@
import six
import math
import numpy as np
from scipy import ndimage, spatial
from skimage.util import img_as_float
from ._warps_cy import _warp_fast
from skimage._shared.utils import get_bound_method_class
from skimage._shared import six
from skimage.util import img_as_float
from ._warps_cy import _warp_fast
class GeometricTransform(object):
@@ -797,13 +797,14 @@ def estimate_transform(ttype, src, dst, **kwargs):
>>> tform = tf.estimate_transform('similarity', src, dst)
>>> tform.inverse(tform(src)) # == src
>>> np.allclose(tform.inverse(tform(src)), src)
True
>>> # warp image using the estimated transformation
>>> from skimage import data
>>> image = data.camera()
>>> warp(image, inverse_map=tform.inverse)
>>> warp(image, inverse_map=tform.inverse) # doctest: +SKIP
>>> # create transformation with explicit parameters
>>> tform2 = tf.SimilarityTransform(scale=1.1, rotation=1,
@@ -811,7 +812,8 @@ def estimate_transform(ttype, src, dst, **kwargs):
>>> # unite transformations, applied in order from left to right
>>> tform3 = tform + tform2
>>> tform3(src) # == tform2(tform(src))
>>> np.allclose(tform3(src), tform2(tform(src)))
True
"""
ttype = ttype.lower()
@@ -996,25 +998,25 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1,
>>> from skimage.transform import SimilarityTransform
>>> tform = SimilarityTransform(translation=(0, -10))
>>> warp(image, tform)
>>> warp(image, tform) # doctest: +SKIP
Shift an image to the right with a callable (slow):
>>> def shift(xy):
... xy[:, 1] -= 10
... return xy
>>> warp(image, shift_right)
>>> warp(image, shift_right) # doctest: +SKIP
Use a transformation matrix to warp an image (fast):
>>> matrix = np.array([[1, 0, 0], [0, 1, -10], [0, 0, 1]])
>>> warp(image, matrix)
>>> warp(image, matrix) # doctest: +SKIP
>>> from skimage.transform import ProjectiveTransform
>>> warp(image, ProjectiveTransform(matrix=matrix))
>>> warp(image, ProjectiveTransform(matrix=matrix)) # doctest: +SKIP
You can also use the inverse of a geometric transformation (fast):
>>> warp(image, tform.inverse)
>>> warp(image, tform.inverse) # doctest: +SKIP
"""
# Backward API compatibility
+4 -4
View File
@@ -252,16 +252,16 @@ def downscale_local_mean(image, factors, cval=0):
image : ndarray
Down-sampled image with same number of dimensions as input image.
Example
-------
Examples
--------
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> downscale_local_mean(a, (2, 3))
array([[3.5, 4.],
[5.5, 4.5]])
array([[ 3.5, 4. ],
[ 5.5, 4.5]])
"""
return block_reduce(image, factors, np.mean, cval)
+4 -7
View File
@@ -40,8 +40,7 @@ def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10,
Examples
--------
>>> import numpy as np
>>> from skimage.transform import hough_line, hough_peaks
>>> from skimage.transform import hough_line, hough_line_peaks
>>> from skimage.draw import line
>>> img = np.zeros((15, 15), dtype=np.bool_)
>>> rr, cc = line(0, 0, 14, 14)
@@ -49,11 +48,9 @@ def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10,
>>> rr, cc = line(0, 14, 14, 0)
>>> img[cc, rr] = 1
>>> hspace, angles, dists = hough_line(img)
>>> hspace, angles, dists = hough_peaks(hspace, angles, dists)
>>> angles
array([ 0.74590887, -0.79856126])
>>> dists
array([ 10.74418605, 0.51162791])
>>> hspace, angles, dists = hough_line_peaks(hspace, angles, dists)
>>> len(angles)
2
"""
+14 -21
View File
@@ -5,17 +5,14 @@ from numpy.testing import assert_raises
import itertools
import os.path
from skimage.transform import radon, iradon
from skimage.transform import radon, iradon, iradon_sart, rescale
from skimage.io import imread
from skimage import data_dir
__PHANTOM = imread(os.path.join(data_dir, "phantom.png"),
PHANTOM = imread(os.path.join(data_dir, "phantom.png"),
as_grey=True)[::2, ::2]
def _get_phantom():
return __PHANTOM
PHANTOM = rescale(PHANTOM, 0.5, order=1)
def _debug_plot(original, result, sinogram=None):
@@ -39,7 +36,7 @@ def _debug_plot(original, result, sinogram=None):
plt.show()
def rescale(x):
def _rescale_intensity(x):
x = x.astype(float)
x -= x.min()
x /= x.max()
@@ -117,7 +114,7 @@ def test_iradon_center():
def check_radon_iradon(interpolation_type, filter_type):
debug = False
image = _get_phantom()
image = PHANTOM
reconstructed = iradon(radon(image), filter=filter_type,
interpolation=interpolation_type)
delta = np.mean(np.abs(image - reconstructed))
@@ -128,7 +125,7 @@ def check_radon_iradon(interpolation_type, filter_type):
if interpolation_type == 'nearest':
allowed_delta = 0.03
else:
allowed_delta = 0.02
allowed_delta = 0.025
else:
allowed_delta = 0.05
assert delta < allowed_delta
@@ -156,7 +153,7 @@ def test_iradon_angles():
radon_image_200 = radon(image, theta=np.linspace(0, 180, nb_angles,
endpoint=False))
reconstructed = iradon(radon_image_200)
delta_200 = np.mean(abs(rescale(image) - rescale(reconstructed)))
delta_200 = np.mean(abs(_rescale_intensity(image) - _rescale_intensity(reconstructed)))
assert delta_200 < 0.03
# Lower number of projections
nb_angles = 80
@@ -225,7 +222,7 @@ def test_radon_circle():
r = np.sqrt((c0 - shape[0] // 2)**2 + (c1 - shape[1] // 2)**2)
radius = min(shape) // 2
image = np.clip(radius - r, 0, np.inf)
image = rescale(image)
image = _rescale_intensity(image)
angles = np.linspace(0, 180, min(shape), endpoint=False)
sinogram = radon(image, theta=angles, circle=True)
assert np.all(sinogram.std(axis=1) < 1e-2)
@@ -314,14 +311,9 @@ def test_order_angles_golden_ratio():
def test_iradon_sart():
from skimage.io import imread
from skimage import data_dir
from skimage.transform import rescale, radon, iradon_sart
debug = False
shepp_logan = imread(os.path.join(data_dir, "phantom.png"), as_grey=True)
image = rescale(shepp_logan, scale=0.4)
image = rescale(PHANTOM, 0.8)
theta_ordered = np.linspace(0., 180., image.shape[0], endpoint=False)
theta_missing_wedge = np.linspace(0., 150., image.shape[0], endpoint=True)
for theta, error_factor in ((theta_ordered, 1.),
@@ -344,15 +336,15 @@ def test_iradon_sart():
delta = np.mean(np.abs(reconstructed - image))
print('delta (1 iteration) =', delta)
assert delta < 0.016 * error_factor
assert delta < 0.02 * error_factor
reconstructed = iradon_sart(sinogram, theta, reconstructed)
delta = np.mean(np.abs(reconstructed - image))
print('delta (2 iterations) =', delta)
assert delta < 0.013 * error_factor
assert delta < 0.014 * error_factor
reconstructed = iradon_sart(sinogram, theta, clip=(0, 1))
delta = np.mean(np.abs(reconstructed - image))
print('delta (1 iteration, clip) =', delta)
assert delta < 0.015 * error_factor
assert delta < 0.018 * error_factor
np.random.seed(1239867)
shifts = np.random.uniform(-3, 3, sinogram.shape[1])
@@ -377,7 +369,8 @@ def test_iradon_sart():
delta = np.mean(np.abs(reconstructed - image))
print('delta (1 iteration, shifted sinogram) =', delta)
assert delta < 0.018 * error_factor
assert delta < 0.022 * error_factor
if __name__ == "__main__":
from numpy.testing import run_module_suite
+14 -14
View File
@@ -4,8 +4,8 @@ of an n-dimensional array.
"""
from __future__ import division, absolute_import, print_function
from skimage._shared.six import integer_types
from six import integer_types
import numpy as np
try:
@@ -1220,26 +1220,26 @@ def pad(array, pad_width, mode=None, **kwargs):
Examples
--------
>>> a = [1, 2, 3, 4, 5]
>>> np.lib.pad(a, (2,3), 'constant', constant_values=(4,6))
>>> pad(a, (2,3), 'constant', constant_values=(4,6))
array([4, 4, 1, 2, 3, 4, 5, 6, 6, 6])
>>> np.lib.pad(a, (2,3), 'edge')
>>> pad(a, (2,3), 'edge')
array([1, 1, 1, 2, 3, 4, 5, 5, 5, 5])
>>> np.lib.pad(a, (2,3), 'linear_ramp', end_values=(5,-4))
>>> pad(a, (2,3), 'linear_ramp', end_values=(5,-4))
array([ 5, 3, 1, 2, 3, 4, 5, 2, -1, -4])
>>> np.lib.pad(a, (2,), 'maximum')
>>> pad(a, (2,), 'maximum')
array([5, 5, 1, 2, 3, 4, 5, 5, 5])
>>> np.lib.pad(a, (2,), 'mean')
>>> pad(a, (2,), 'mean')
array([3, 3, 1, 2, 3, 4, 5, 3, 3])
>>> np.lib.pad(a, (2,), 'median')
>>> pad(a, (2,), 'median')
array([3, 3, 1, 2, 3, 4, 5, 3, 3])
>>> a = [[1,2], [3,4]]
>>> np.lib.pad(a, ((3, 2), (2, 3)), 'minimum')
>>> pad(a, ((3, 2), (2, 3)), 'minimum')
array([[1, 1, 1, 2, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1],
[1, 1, 1, 2, 1, 1, 1],
@@ -1249,19 +1249,19 @@ def pad(array, pad_width, mode=None, **kwargs):
[1, 1, 1, 2, 1, 1, 1]])
>>> a = [1, 2, 3, 4, 5]
>>> np.lib.pad(a, (2,3), 'reflect')
>>> pad(a, (2,3), 'reflect')
array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2])
>>> np.lib.pad(a, (2,3), 'reflect', reflect_type='odd')
>>> pad(a, (2,3), 'reflect', reflect_type='odd')
array([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.lib.pad(a, (2,3), 'symmetric')
>>> pad(a, (2,3), 'symmetric')
array([2, 1, 1, 2, 3, 4, 5, 5, 4, 3])
>>> np.lib.pad(a, (2,3), 'symmetric', reflect_type='odd')
>>> pad(a, (2,3), 'symmetric', reflect_type='odd')
array([0, 1, 1, 2, 3, 4, 5, 5, 6, 7])
>>> np.lib.pad(a, (2,3), 'wrap')
>>> pad(a, (2,3), 'wrap')
array([4, 5, 1, 2, 3, 4, 5, 1, 2, 3])
>>> def padwithtens(vector, pad_width, iaxis, kwargs):
@@ -1272,7 +1272,7 @@ def pad(array, pad_width, mode=None, **kwargs):
>>> a = np.arange(6)
>>> a = a.reshape((2,3))
>>> np.lib.pad(a, 2, padwithtens)
>>> pad(a, 2, padwithtens)
array([[10, 10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 10, 10],
[10, 10, 0, 1, 2, 10, 10],
+22 -21
View File
@@ -51,31 +51,32 @@ def montage2d(arr_in, fill='mean', rescale_intensity=False, grid_shape=None):
>>> import numpy as np
>>> from skimage.util.montage import montage2d
>>> arr_in = np.arange(3 * 2 * 2).reshape(3, 2, 2)
>>> print(arr_in) # doctest: +NORMALIZE_WHITESPACE
[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]]]
>>> arr_in # doctest: +NORMALIZE_WHITESPACE
array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])
>>> arr_out = montage2d(arr_in)
>>> print(arr_out.shape)
>>> arr_out.shape
(4, 4)
>>> print(arr_out)
[[ 0. 1. 4. 5. ]
[ 2. 3. 6. 7. ]
[ 8. 9. 5.5 5.5]
[ 10. 11. 5.5 5.5]]
>>> print(arr_in.mean())
>>> arr_out
array([[ 0. , 1. , 4. , 5. ],
[ 2. , 3. , 6. , 7. ],
[ 8. , 9. , 5.5, 5.5],
[ 10. , 11. , 5.5, 5.5]])
>>> arr_in.mean()
5.5
>>> arr_out_nonsquare = montage2d(arr_in, grid_shape=(3, 4))
>>> print(arr_out_nonsquare)
[[ 0. 1. 4. 5. ]
[ 2. 3. 6. 7. ]
[ 8. 9. 10. 11. ]]
>>> print(arr_out_nonsquare.shape)
(3, 4)
>>> arr_out_nonsquare = montage2d(arr_in, grid_shape=(1, 3))
>>> arr_out_nonsquare
array([[ 0., 1., 4., 5., 8., 9.],
[ 2., 3., 6., 7., 10., 11.]])
>>> arr_out_nonsquare.shape
(2, 6)
"""
assert arr_in.ndim == 3
n_images, height, width = arr_in.shape
+2 -2
View File
@@ -158,8 +158,8 @@ class PaintTool(CanvasToolBase):
class CenteredWindow(object):
"""Window that create slices numpy arrays over 2D windows.
Example
-------
Examples
--------
>>> a = np.arange(16).reshape(4, 4)
>>> w = CenteredWindow(1, a.shape)
>>> a[w.at(1, 1)]
+25
View File
@@ -182,8 +182,13 @@ class Plugin(QtGui.QDialog):
This method is called by the viewer when the original image is updated.
"""
self.arguments[0] = image
self._on_new_image(image)
self.filter_image()
def _on_new_image(self, image):
"""Override this method to update your plugin for new images."""
pass
@property
def filtered_image(self):
"""Return filtered image."""
@@ -235,3 +240,23 @@ class Plugin(QtGui.QDialog):
"""Remove artists that are connected to the image viewer."""
for a in self.artists:
a.remove()
def output(self):
"""Return the plugin's representation and data.
Returns
-------
image : array, same shape as ``self.image_viewer.image``, or None
The filtered image.
data : None
Any data associated with the plugin.
Notes
-----
Derived classes should override this method to return a tuple
containing an *overlay* of the same shape of the image, and a
*data* object. Either of these is optional: return ``None`` if
you don't want to return a value.
"""
return (self.image_viewer.image, None)
+32 -8
View File
@@ -20,16 +20,21 @@ class ColorHistogram(PlotPlugin):
super(ColorHistogram, self).attach(image_viewer)
self.rect_tool = RectangleTool(self.ax, on_release=self.ab_selected)
self.lab_image = color.rgb2lab(image_viewer.image)
self._on_new_image(image_viewer.image)
def _on_new_image(self, image):
self.lab_image = color.rgb2lab(image)
# Calculate color histogram in the Lab colorspace:
L, a, b = self.lab_image.T
left, right = -100, 100
ab_extents = [left, right, right, left]
self.mask = np.ones(L.shape, bool)
bins = np.arange(left, right)
hist, x_edges, y_edges = np.histogram2d(a.flatten(), b.flatten(), bins,
normed=True)
hist, x_edges, y_edges = np.histogram2d(a.flatten(), b.flatten(),
bins, normed=True)
self.data = {'bins': bins, 'hist': hist, 'edges': (x_edges, y_edges),
'extents': (left, right, left, right)}
# Clip bin heights that dominate a-b histogram
max_val = pct_total_area(hist, percentile=self.max_pct)
hist = exposure.rescale_intensity(hist, in_range=(0, max_val))
@@ -46,15 +51,36 @@ class ColorHistogram(PlotPlugin):
def ab_selected(self, extents):
x0, x1, y0, y1 = extents
self.data['extents'] = extents
lab_masked = self.lab_image.copy()
L, a, b = lab_masked.T
mask = ((a > y0) & (a < y1)) & ((b > x0) & (b < x1))
lab_masked[..., 1:][~mask.T] = 0
self.mask = ((a > y0) & (a < y1)) & ((b > x0) & (b < x1))
lab_masked[..., 1:][~self.mask.T] = 0
self.image_viewer.image = color.lab2rgb(lab_masked)
def output(self):
"""Return the image mask and the histogram data.
Returns
-------
mask : array of bool, same shape as image
The selected pixels.
data : dict
The data describing the histogram and the selected region.
Keys:
- 'bins' : array of float, the bin boundaries for both
`a` and `b` channels.
- 'hist' : 2D array of float, the normalized histogram.
- 'edges' : tuple of array of float, the bin edges
along each dimension
- 'extents' : tuple of float, the left and right and
top and bottom of the selected region.
"""
return (self.mask, self.data)
def pct_total_area(image, percentile=0.80):
"""Return threshold value based on percentage of total area.
@@ -65,5 +91,3 @@ def pct_total_area(image, percentile=0.80):
sorted_pixels = np.sort(image.flat)
return sorted_pixels[idx]
+1 -1
View File
@@ -47,4 +47,4 @@ class Measure(Plugin):
dx = np.diff(x)[0]
dy = np.diff(y)[0]
self._length.text = '%.1f' % np.hypot(dx, dy)
self._angle.text = u'%.1f°' % (180 - np.arctan2(dy, dx) * rad2deg)
self._angle.text = '%.1f°' % (180 - np.arctan2(dy, dx) * rad2deg)
+14 -1
View File
@@ -3,7 +3,8 @@ from warnings import warn
from skimage.util.dtype import dtype_range
from .base import Plugin
from ..utils import ClearColormap, update_axes_image
from skimage._shared import six
import six
__all__ = ['OverlayPlugin']
@@ -107,3 +108,15 @@ class OverlayPlugin(Plugin):
# clear overlay from ImageViewer on close
self.overlay = None
super(OverlayPlugin, self).closeEvent(event)
def output(self):
"""Return the overlaid image.
Returns
-------
overlay : array, same shape as image
The overlay currently displayed.
data : None
"""
return (self.overlay, None)
+4
View File
@@ -47,3 +47,7 @@ class PlotPlugin(Plugin):
bgcolor = str(bgcolor / 255.)
self.fig.patch.set_facecolor(bgcolor)
self.layout.addWidget(self.canvas, self.row, 0)
def _update_original_image(self, image):
super(PlotPlugin, self)._update_original_image(image)
self.redraw()
+2 -1
View File
@@ -73,7 +73,7 @@ class ImageViewer(QtGui.QMainWindow):
>>> from skimage import data
>>> image = data.coins()
>>> viewer = ImageViewer(image)
>>> # viewer.show()
>>> viewer.show() # doctest: +SKIP
"""
@@ -228,6 +228,7 @@ class ImageViewer(QtGui.QMainWindow):
self._show()
if main_window:
utils.start_qtapp()
return [p.output() for p in self.plugins]
def redraw(self):
self.canvas.draw_idle()