mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-15 12:54:54 +08:00
Merged with upstream
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
# Configuration for coverage.py
|
||||
|
||||
[run]
|
||||
branch = True
|
||||
source = skimage
|
||||
include = */skimage/*
|
||||
omit =
|
||||
*/setup.py
|
||||
|
||||
+64
-29
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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,3 +1,4 @@
|
||||
cython>=0.17
|
||||
matplotlib>=1.0
|
||||
numpy>=1.6
|
||||
six>=1.3.0
|
||||
|
||||
@@ -22,6 +22,7 @@ PYTHON_VERSION = (2, 5)
|
||||
DEPENDENCIES = {
|
||||
'numpy': (1, 6),
|
||||
'Cython': (0, 17),
|
||||
'six': (1, 3),
|
||||
}
|
||||
|
||||
|
||||
|
||||
+31
-7
@@ -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)
|
||||
|
||||
@@ -2,7 +2,7 @@ import warnings
|
||||
import functools
|
||||
import sys
|
||||
|
||||
from . import six
|
||||
import six
|
||||
|
||||
|
||||
__all__ = ['deprecated', 'get_bound_method_class']
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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.],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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')
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__":
|
||||
|
||||
@@ -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,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]
|
||||
@@ -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
|
||||
----------
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -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()])
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
"""
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user