mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-04 22:12:52 +08:00
Merge branch 'releases' into debian
* releases: (978 commits) Update release instructions for building docs Change to http git protocol Add 0.10 to docs Set version 0.10 Move removal of deprated functionality by one version Correctly apply catch_warnings() Avoid circular imports Mention which parameters to label are optional. Simplify label deprecation. Fix broken and circular imports Update bento build Fix imports and suppress deprecation warnings Move implementation of label to measure submodule Move label to measure module (with deprecation). Warn that background parameter will default to 0 in v0.12. Fix copy/paste error in docstring. Change EPD link to Enthought Canopy Improve description of subpixel corner localization Comment special case when local patch around is constant Test invalid input for unwrap_phase Fix docstring of skimage.filter.rank.threshold_percentile Test 90deg rotation for similarity transform ...
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
# Configuration for coverage.py
|
||||
|
||||
[run]
|
||||
branch = True
|
||||
source = skimage
|
||||
include = */skimage/*
|
||||
omit =
|
||||
*/setup.py
|
||||
|
||||
[report]
|
||||
exclude_lines =
|
||||
def __repr__
|
||||
if __name__ == .__main__.:
|
||||
+84
-32
@@ -1,42 +1,94 @@
|
||||
# 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
|
||||
- PYTHONWARNINGS=all
|
||||
- PYTHONX=python
|
||||
- PYVER=2.x
|
||||
- python: 3.2
|
||||
env:
|
||||
- PYTHON=python3
|
||||
- PYTHONWARNINGS=all
|
||||
- PYTHONX=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
|
||||
- wget https://raw.githubusercontent.com/numpy/numpy/master/numpy/_import_tools.py -O /home/travis/virtualenv/python3.2_with_system_site_packages/lib/python3.2/site-packages/numpy/_import_tools.py
|
||||
|
||||
- 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 pillow
|
||||
- pip install cython
|
||||
- pip install flake8
|
||||
- pip install six
|
||||
|
||||
- pip install nose-cov
|
||||
- pip install coveralls
|
||||
|
||||
- python check_bento_build.py
|
||||
|
||||
install:
|
||||
- tools/header.py "Dependency versions"
|
||||
- tools/build_versions.py
|
||||
|
||||
- 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
|
||||
- mkdir $HOME/.matplotlib
|
||||
# Matplotlib settings
|
||||
- mkdir -p $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 ..
|
||||
- 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 all tests
|
||||
- if [[ $PYVER == '3.x' ]]; then
|
||||
- nosetests --exe -v --with-doctest --with-cov --cov skimage --cov-config=.coveragerc skimage
|
||||
- fi
|
||||
- if [[ $PYVER == '2.x' ]]; then
|
||||
- nosetests --exe -v --with-doctest skimage
|
||||
- fi
|
||||
# Run all doc examples
|
||||
- export PYTHONPATH=$(pwd):$PYTHONPATH
|
||||
- for f in doc/examples/*.py; do $PYTHONX "$f"; if [ $? -ne 0 ]; then exit 1; fi done
|
||||
- for f in doc/examples/applications/*.py; do $PYTHONX "$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:
|
||||
- if [[ $PYVER == '3.x' ]]; then
|
||||
- coveralls
|
||||
- fi
|
||||
|
||||
+35
-7
@@ -13,7 +13,7 @@ Here's the long and short of it:
|
||||
|
||||
git clone git@github.com:your-username/scikit-image.git
|
||||
|
||||
* Add upstream repository::
|
||||
* Add the upstream repository::
|
||||
|
||||
git remote add upstream git@github.com:scikit-image/scikit-image.git
|
||||
|
||||
@@ -43,8 +43,8 @@ Here's the long and short of it:
|
||||
|
||||
git push origin transform-speedups
|
||||
|
||||
* Go to GitHub. The new branch will show up with a Pull Request button -
|
||||
click it.
|
||||
* Go to GitHub. The new branch will show up with a green Pull Request
|
||||
button - click it.
|
||||
|
||||
* If you want, post on the `mailing list
|
||||
<http://groups.google.com/group/scikit-image>`_ to explain your changes or
|
||||
@@ -54,11 +54,34 @@ For a more detailed discussion, read these :doc:`detailed documents
|
||||
<gitwash/index>` on how to use Git with ``scikit-image``
|
||||
(`<http://scikit-image.org/docs/dev/gitwash/index.html>`_).
|
||||
|
||||
4. Review process:
|
||||
|
||||
* Reviewers (the other developers and interested community members) will
|
||||
write inline and/or general comments on your Pull Request (PR) to help
|
||||
you improve its implementation, documentation and style. Every single
|
||||
developer working on the project has their code reviewed, and we've come
|
||||
to see it as friendly conversation from which we all learn and the
|
||||
overall code quality benefits. Therefore, please don't let the review
|
||||
discourage you from contributing: its only aim is to improve the quality
|
||||
of project, not to criticize (we are, after all, very grateful for the
|
||||
time you're donating!).
|
||||
|
||||
* To update your pull request, make your changes on your local repository
|
||||
and commit. As soon as those changes are pushed up (to the same branch as
|
||||
before) the pull request will update automatically.
|
||||
|
||||
* `Travis-CI <http://travis-ci.org/>`__, a continuous integration service,
|
||||
is triggered after each Pull Request update to build the code, run unit
|
||||
tests, measure code coverage and check coding style (PEP8) of your
|
||||
branch. The Travis tests must pass before your PR can be merged. If
|
||||
Travis fails, you can find out why by clicking on the "failed" icon (red
|
||||
cross) and inspecting the build and test log.
|
||||
|
||||
.. note::
|
||||
|
||||
To reviewers: add a short explanation of what a branch did to the merge
|
||||
message and, if closing a bug, also add "Closes gh-123" where 123 is the
|
||||
bug number.
|
||||
To reviewers: if it is not obvious, add a short explanation of what a branch
|
||||
did to the merge message and, if closing a bug, also add "Closes #123"
|
||||
where 123 is the issue number.
|
||||
|
||||
|
||||
Divergence between ``upstream master`` and your feature branch
|
||||
@@ -98,7 +121,7 @@ Guidelines
|
||||
as NumPy and SciPy.
|
||||
* For new functionality, always add an example to the
|
||||
gallery.
|
||||
* No changes should be committed without review. Ask on the
|
||||
* No changes are ever committed without review. Ask on the
|
||||
`mailing list <http://groups.google.com/group/scikit-image>`_ if
|
||||
you get no response to your pull request.
|
||||
**Never merge your own pull request.**
|
||||
@@ -154,6 +177,7 @@ detailing the test coverage::
|
||||
skimage/filter/__init__ 1 1 100%
|
||||
...
|
||||
|
||||
|
||||
Activate Travis-CI for your fork (optional)
|
||||
-------------------------------------------
|
||||
|
||||
@@ -174,6 +198,10 @@ It corresponds to steps one and two in
|
||||
Thus, as soon as you push your code to your fork, it will trigger Travis-CI,
|
||||
and you will receive an email notification when the process is done.
|
||||
|
||||
Every time Travis is triggered, it also calls on `Coveralls
|
||||
<http://coveralls.io>`_ to inspect the current test overage.
|
||||
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
|
||||
+27
-3
@@ -144,17 +144,41 @@
|
||||
Color separation (color deconvolution) for several stainings.
|
||||
|
||||
- Jostein Bø Fløystad
|
||||
Reconstruction circle mode for Radon transform
|
||||
Simultaneous Algebraic Reconstruction Technique for inverse Radon transform
|
||||
Tomography: radon/iradon improvements and SART implementation
|
||||
Phase unwrapping integration
|
||||
|
||||
- Matt Terry
|
||||
Color difference functions
|
||||
|
||||
- Eugene Dvoretsky
|
||||
Yen threshold implementation.
|
||||
Yen, Ridler-Calvard (ISODATA) threshold implementations.
|
||||
|
||||
- Riaan van den Dool
|
||||
skimage.io plugin: GDAL
|
||||
|
||||
- Fedor Morozov
|
||||
Drawing: Wu's anti-aliased circle
|
||||
|
||||
- Michael Hansen
|
||||
novice submodule
|
||||
|
||||
- Munther Gdeisat
|
||||
Phase unwrapping implementation
|
||||
|
||||
- Miguel Arevallilo Herraez
|
||||
Phase unwrapping implementation
|
||||
|
||||
- Hussein Abdul-Rahman
|
||||
Phase unwrapping implementation
|
||||
|
||||
- Gregor Thalhammer
|
||||
Phase unwrapping integration
|
||||
|
||||
- François Orieux
|
||||
Image deconvolution http://research.orieux.fr
|
||||
|
||||
- Vighnesh Birodkar
|
||||
Blob Detection
|
||||
|
||||
- Axel Donath
|
||||
Blob Detection
|
||||
|
||||
@@ -46,6 +46,12 @@ functionality is only available with the following installed:
|
||||
The ``pyamg`` module is used for the fast `cg_mg` mode of random
|
||||
walker segmentation.
|
||||
|
||||
* `Pillow <https://pypi.python.org/pypi/Pillow>`__
|
||||
(or <`PIL http://www.pythonware.com/products/pil/>`__)
|
||||
The ``Pillow`` library (or equivalently ``PIL``) is used for Input/Output.
|
||||
|
||||
* `Astropy <http://www.astropy.org>`__ is required to use the FITS io plug-in.
|
||||
|
||||
Testing requirements
|
||||
--------------------
|
||||
* `Nose <https://nose.readthedocs.org/en/latest/>`__
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ include setup*.py
|
||||
include MANIFEST.in
|
||||
include *.txt
|
||||
include Makefile
|
||||
recursive-include skimage *.pyx *.pxd *.pxi *.py *.c *.h *.ini *.md5 *.rst *.txt
|
||||
recursive-include skimage *.pyx *.pxd *.pxi *.py *.c *.h *.ini *.md5
|
||||
recursive-include skimage/data *
|
||||
|
||||
include doc/Makefile
|
||||
|
||||
@@ -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
|
||||
|
||||
+3
-3
@@ -13,8 +13,8 @@ How to make a new release of ``skimage``
|
||||
- Update the docs:
|
||||
|
||||
- Edit ``doc/source/_static/docversions.js`` and commit
|
||||
- Build a clean version of the docs. Run ``make`` in the root dir, then
|
||||
``rm -rf build; make html`` in the docs.
|
||||
- Build a clean version of the docs. Run ``python setup.py install`` in the
|
||||
root dir, then ``rm -rf build; make html`` in the docs.
|
||||
- Run ``make html`` again to copy the newly generated ``random.js`` into
|
||||
place. Double check ``random.js``, otherwise the skimage.org front
|
||||
page gets broken!
|
||||
@@ -51,7 +51,7 @@ How to make a new release of ``skimage``
|
||||
- Add previous stable version documentation path to disallowed paths
|
||||
in `robots.txt`
|
||||
- Build using ``make gh-pages``.
|
||||
- Push upstream: ``git push`` in ``gh-pages``.
|
||||
- Push upstream: ``git push origin master`` in ``gh-pages``.
|
||||
|
||||
- Update the development docs for the new version ``0.Xdev`` just like above
|
||||
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
Version 0.10
|
||||
------------
|
||||
* Remove deprecated functions in `skimage.filter.rank.*`
|
||||
* Remove deprecated parameter `epsilon` of `skimage.viewer.LineProfile`
|
||||
* Remove backwards-compatability of `skimage.measure.regionprops`
|
||||
* Remove {`ratio`, `sigma`} deprecation warnings of `skimage.segmentation.slic`
|
||||
* 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_*`
|
||||
* Remove deprecated parameter `depth` in `skimage.segmentation.random_walker`
|
||||
* Remove deprecated logger function in `skimage/__init__.py`
|
||||
* Remove deprecated function `filter.median_filter`
|
||||
* Remove deprecated `skimage.color.is_gray` and `skimage.color.is_rgb`
|
||||
functions
|
||||
Remember to list any API changes below in `doc/source/api_changes.txt`.
|
||||
|
||||
Version 0.12
|
||||
------------
|
||||
* Change `label` to mark background as 0, not -1, which is consistent with
|
||||
SciPy's labelling.
|
||||
* Remove `skimage.morphology.label` from `skimage.morphology.__init__`--it now
|
||||
lives in `skimage.measure.label`.
|
||||
* Remove deprecated `reverse_map` parameter of `skimage.transform.warp`
|
||||
* Change depecrated `enforce_connectivity=False` on skimage.segmentation.slic
|
||||
and set it to True as default
|
||||
* Remove deprecated `skimage.measure.fit.BaseModel._params` attribute
|
||||
* Remove deprecated `skimage.measure.fit.BaseModel._params`,
|
||||
`skimage.transform.ProjectiveTransform._matrix`,
|
||||
`skimage.transform.PolynomialTransform._params`,
|
||||
`skimage.transform.PiecewiseAffineTransform.affines_*` attributes
|
||||
* Remove deprecated functions `skimage.filter.denoise_*`
|
||||
|
||||
+27
-17
@@ -1,5 +1,5 @@
|
||||
Name: scikit-image
|
||||
Version: 0.9.3
|
||||
Version: 0.10.0
|
||||
Summary: Image processing routines for SciPy
|
||||
Url: http://scikit-image.org
|
||||
DownloadUrl: http://github.com/scikit-image/scikit-image
|
||||
@@ -35,19 +35,17 @@ Library:
|
||||
skimage, skimage.color, skimage.data, skimage.draw, skimage.exposure,
|
||||
skimage.feature, skimage.filter, skimage.graph, skimage.io,
|
||||
skimage.io._plugins, skimage.measure, skimage.morphology,
|
||||
skimage.scripts, skimage.segmentation, skimage.transform, skimage.util
|
||||
skimage.scripts, skimage.restoration, skimage.segmentation,
|
||||
skimage.transform, skimage.util
|
||||
Extension: skimage.morphology._pnpoly
|
||||
Sources:
|
||||
skimage/morphology/_pnpoly.pyx
|
||||
Extension: skimage.feature._template
|
||||
Sources:
|
||||
skimage/feature/_template.pyx
|
||||
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
|
||||
@@ -66,12 +64,9 @@ Library:
|
||||
Extension: skimage.filter._ctmf
|
||||
Sources:
|
||||
skimage/filter/_ctmf.pyx
|
||||
Extension: skimage.filter._denoise_cy
|
||||
Extension: skimage.measure._ccomp
|
||||
Sources:
|
||||
skimage/filter/_denoise_cy.pyx
|
||||
Extension: skimage.morphology.ccomp
|
||||
Sources:
|
||||
skimage/morphology/ccomp.pyx
|
||||
skimage/measure/_ccomp.pyx
|
||||
Extension: skimage.morphology._watershed
|
||||
Sources:
|
||||
skimage/morphology/_watershed.pyx
|
||||
@@ -96,9 +91,12 @@ Library:
|
||||
Extension: skimage.feature.censure_cy
|
||||
Sources:
|
||||
skimage/feature/censure_cy.pyx
|
||||
Extension: skimage.feature._brief_cy
|
||||
Extension: skimage.feature.orb_cy
|
||||
Sources:
|
||||
skimage/feature/_brief_cy.pyx
|
||||
skimage/feature/orb_cy.pyx
|
||||
Extension: skimage.feature.brief_cy
|
||||
Sources:
|
||||
skimage/feature/brief_cy.pyx
|
||||
Extension: skimage.feature.corner_cy
|
||||
Sources:
|
||||
skimage/feature/corner_cy.pyx
|
||||
@@ -123,9 +121,6 @@ Library:
|
||||
Extension: skimage.transform._warps_cy
|
||||
Sources:
|
||||
skimage/transform/_warps_cy.pyx
|
||||
Extension: skimage._shared.interpolation
|
||||
Sources:
|
||||
skimage/_shared/interpolation.pyx
|
||||
Extension: skimage.segmentation._felzenszwalb_cy
|
||||
Sources:
|
||||
skimage/segmentation/_felzenszwalb_cy.pyx
|
||||
@@ -144,6 +139,21 @@ Library:
|
||||
Extension: skimage.filter.rank.bilateral_cy
|
||||
Sources:
|
||||
skimage/filter/rank/bilateral_cy.pyx
|
||||
Extension: skimage.restoration._unwrap_1d
|
||||
Sources:
|
||||
skimage/restoration/_unwrap_1d.pyx
|
||||
Extension: skimage.restoration._unwrap_2d
|
||||
Sources:
|
||||
skimage/restoration/_unwrap_2d.pyx skimage/exposure/unwrap_2d_ljmu.c
|
||||
Extension: skimage.restoration._unwrap_3d
|
||||
Sources:
|
||||
skimage/restoration/_unwrap_3d.pyx skimage/exposure/unwrap_3d_ljmu.c
|
||||
Extension: skimage.restoration._denoise_cy
|
||||
Sources:
|
||||
skimage/restoration/_denoise_cy.pyx
|
||||
Extension: skimage.feature._hessian_det_appx
|
||||
Sources:
|
||||
skimage/exposure/_hessian_det_appx.pyx
|
||||
|
||||
Executable: skivi
|
||||
Module: skimage.scripts.skivi
|
||||
|
||||
@@ -16,13 +16,11 @@ from skimage import data
|
||||
coins = data.coins()
|
||||
hist = np.histogram(coins, bins=np.arange(0, 256))
|
||||
|
||||
plt.figure(figsize=(8, 3))
|
||||
plt.subplot(121)
|
||||
plt.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.subplot(122)
|
||||
plt.plot(hist[1][:-1], hist[0], lw=2)
|
||||
plt.title('histogram of grey values')
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3))
|
||||
ax1.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax1.axis('off')
|
||||
ax2.plot(hist[1][:-1], hist[0], lw=2)
|
||||
ax2.set_title('histogram of grey values')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -37,17 +35,15 @@ background with the coins:
|
||||
|
||||
"""
|
||||
|
||||
plt.figure(figsize=(6, 3))
|
||||
plt.subplot(121)
|
||||
plt.imshow(coins > 100, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.title('coins > 100')
|
||||
plt.axis('off')
|
||||
plt.subplot(122)
|
||||
plt.imshow(coins > 150, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.title('coins > 150')
|
||||
plt.axis('off')
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3))
|
||||
ax1.imshow(coins > 100, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax1.set_title('coins > 100')
|
||||
ax1.axis('off')
|
||||
ax2.imshow(coins > 150, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax2.set_title('coins > 150')
|
||||
ax2.axis('off')
|
||||
margins = dict(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
plt.subplots_adjust(**margins)
|
||||
fig.subplots_adjust(**margins)
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -64,10 +60,10 @@ edge-detector.
|
||||
from skimage.filter import canny
|
||||
edges = canny(coins/255.)
|
||||
|
||||
plt.figure(figsize=(4, 3))
|
||||
plt.imshow(edges, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('Canny detector')
|
||||
fig, ax = plt.subplots(figsize=(4, 3))
|
||||
ax.imshow(edges, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax.axis('off')
|
||||
ax.set_title('Canny detector')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -79,10 +75,10 @@ from scipy import ndimage
|
||||
|
||||
fill_coins = ndimage.binary_fill_holes(edges)
|
||||
|
||||
plt.figure(figsize=(4, 3))
|
||||
plt.imshow(fill_coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('Filling the holes')
|
||||
fig, ax = plt.subplots(figsize=(4, 3))
|
||||
ax.imshow(fill_coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax.axis('off')
|
||||
ax.set_title('Filling the holes')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -93,10 +89,10 @@ objects.
|
||||
from skimage import morphology
|
||||
coins_cleaned = morphology.remove_small_objects(fill_coins, 21)
|
||||
|
||||
plt.figure(figsize=(4, 3))
|
||||
plt.imshow(coins_cleaned, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('Removing small objects')
|
||||
fig, ax = plt.subplots(figsize=(4, 3))
|
||||
ax.imshow(coins_cleaned, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax.axis('off')
|
||||
ax.set_title('Removing small objects')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -117,10 +113,10 @@ from skimage.filter import sobel
|
||||
|
||||
elevation_map = sobel(coins)
|
||||
|
||||
plt.figure(figsize=(4, 3))
|
||||
plt.imshow(elevation_map, cmap=plt.cm.jet, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('elevation_map')
|
||||
fig, ax = plt.subplots(figsize=(4, 3))
|
||||
ax.imshow(elevation_map, cmap=plt.cm.jet, interpolation='nearest')
|
||||
ax.axis('off')
|
||||
ax.set_title('elevation_map')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -133,10 +129,10 @@ markers = np.zeros_like(coins)
|
||||
markers[coins < 30] = 1
|
||||
markers[coins > 150] = 2
|
||||
|
||||
plt.figure(figsize=(4, 3))
|
||||
plt.imshow(markers, cmap=plt.cm.spectral, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('markers')
|
||||
fig, ax = plt.subplots(figsize=(4, 3))
|
||||
ax.imshow(markers, cmap=plt.cm.spectral, interpolation='nearest')
|
||||
ax.axis('off')
|
||||
ax.set_title('markers')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -147,10 +143,10 @@ starting from the markers determined above:
|
||||
"""
|
||||
segmentation = morphology.watershed(elevation_map, markers)
|
||||
|
||||
plt.figure(figsize=(4, 3))
|
||||
plt.imshow(segmentation, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('segmentation')
|
||||
fig, ax = plt.subplots(figsize=(4, 3))
|
||||
ax.imshow(segmentation, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax.axis('off')
|
||||
ax.set_title('segmentation')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -166,16 +162,14 @@ segmentation = ndimage.binary_fill_holes(segmentation - 1)
|
||||
labeled_coins, _ = ndimage.label(segmentation)
|
||||
image_label_overlay = label2rgb(labeled_coins, image=coins)
|
||||
|
||||
plt.figure(figsize=(6, 3))
|
||||
plt.subplot(121)
|
||||
plt.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.contour(segmentation, [0.5], linewidths=1.2, colors='y')
|
||||
plt.axis('off')
|
||||
plt.subplot(122)
|
||||
plt.imshow(image_label_overlay, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3))
|
||||
ax1.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax1.contour(segmentation, [0.5], linewidths=1.2, colors='y')
|
||||
ax1.axis('off')
|
||||
ax2.imshow(image_label_overlay, interpolation='nearest')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplots_adjust(**margins)
|
||||
fig.subplots_adjust(**margins)
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
@@ -33,14 +33,14 @@ First we create a transformation using explicit parameters:
|
||||
|
||||
tform = tf.SimilarityTransform(scale=1, rotation=math.pi / 2,
|
||||
translation=(0, 1))
|
||||
print(tform._matrix)
|
||||
print(tform.params)
|
||||
|
||||
"""
|
||||
Alternatively you can define a transformation by the transformation matrix
|
||||
itself:
|
||||
"""
|
||||
|
||||
matrix = tform._matrix.copy()
|
||||
matrix = tform.params.copy()
|
||||
matrix[1, 2] = 2
|
||||
tform2 = tf.SimilarityTransform(matrix)
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ from skimage.data import data_dir
|
||||
from skimage.util import img_as_ubyte
|
||||
from skimage import io
|
||||
|
||||
plt.gray()
|
||||
phantom = img_as_ubyte(io.imread(data_dir+'/phantom.png', as_grey=True))
|
||||
plt.imshow(phantom)
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(phantom, cmap=plt.cm.gray)
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -43,10 +43,10 @@ Let's also define a convenience function for plotting comparisons:
|
||||
def plot_comparison(original, filtered, filter_name):
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
|
||||
ax1.imshow(original)
|
||||
ax1.imshow(original, cmap=plt.cm.gray)
|
||||
ax1.set_title('original')
|
||||
ax1.axis('off')
|
||||
ax2.imshow(filtered)
|
||||
ax2.imshow(filtered, cmap=plt.cm.gray)
|
||||
ax2.set_title(filter_name)
|
||||
ax2.axis('off')
|
||||
|
||||
|
||||
@@ -44,13 +44,11 @@ from skimage import data
|
||||
noisy_image = img_as_ubyte(data.camera())
|
||||
hist = np.histogram(noisy_image, bins=np.arange(0, 256))
|
||||
|
||||
plt.figure(figsize=(8, 3))
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.imshow(noisy_image, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.plot(hist[1][:-1], hist[0], lw=2)
|
||||
plt.title('Histogram of grey values')
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3))
|
||||
ax1.imshow(noisy_image, interpolation='nearest', cmap=plt.cm.gray)
|
||||
ax1.axis('off')
|
||||
ax2.plot(hist[1][:-1], hist[0], lw=2)
|
||||
ax2.set_title('Histogram of grey values')
|
||||
|
||||
"""
|
||||
|
||||
@@ -62,11 +60,6 @@ Noise removal
|
||||
Some noise is added to the image, 1% of pixels are randomly set to 255, 1% are
|
||||
randomly set to 0. The **median** filter is applied to remove the noise.
|
||||
|
||||
.. note::
|
||||
|
||||
There are different implementations of median filter:
|
||||
`skimage.filter.median_filter` and `skimage.filter.rank.median`
|
||||
|
||||
"""
|
||||
|
||||
from skimage.filter.rank import median
|
||||
@@ -77,27 +70,24 @@ noisy_image = img_as_ubyte(data.camera())
|
||||
noisy_image[noise > 0.99] = 255
|
||||
noisy_image[noise < 0.01] = 0
|
||||
|
||||
fig = plt.figure(figsize=(10, 7))
|
||||
fig, ax = plt.subplots(2, 2, figsize=(10, 7))
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(noisy_image, vmin=0, vmax=255)
|
||||
plt.title('Noisy image')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, vmin=0, vmax=255, cmap=plt.cm.gray)
|
||||
ax1.set_title('Noisy image')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(median(noisy_image, disk(1)), vmin=0, vmax=255)
|
||||
plt.title('Median $r=1$')
|
||||
plt.axis('off')
|
||||
ax2.imshow(median(noisy_image, disk(1)), vmin=0, vmax=255, cmap=plt.cm.gray)
|
||||
ax2.set_title('Median $r=1$')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(median(noisy_image, disk(5)), vmin=0, vmax=255)
|
||||
plt.title('Median $r=5$')
|
||||
plt.axis('off')
|
||||
ax3.imshow(median(noisy_image, disk(5)), vmin=0, vmax=255, cmap=plt.cm.gray)
|
||||
ax3.set_title('Median $r=5$')
|
||||
ax3.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(median(noisy_image, disk(20)), vmin=0, vmax=255)
|
||||
plt.title('Median $r=20$')
|
||||
plt.axis('off')
|
||||
ax4.imshow(median(noisy_image, disk(20)), vmin=0, vmax=255, cmap=plt.cm.gray)
|
||||
ax4.set_title('Median $r=20$')
|
||||
ax4.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -119,19 +109,17 @@ image.
|
||||
|
||||
from skimage.filter.rank import mean
|
||||
|
||||
fig = plt.figure(figsize=[10, 7])
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[10, 7])
|
||||
|
||||
loc_mean = mean(noisy_image, disk(10))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.imshow(noisy_image, vmin=0, vmax=255)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, vmin=0, vmax=255, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.imshow(loc_mean, vmin=0, vmax=255)
|
||||
plt.title('Local mean $r=10$')
|
||||
plt.axis('off')
|
||||
ax2.imshow(loc_mean, vmin=0, vmax=255, cmap=plt.cm.gray)
|
||||
ax2.set_title('Local mean $r=10$')
|
||||
ax2.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -149,31 +137,28 @@ the central one.
|
||||
|
||||
"""
|
||||
|
||||
from skimage.filter.rank import bilateral_mean
|
||||
from skimage.filter.rank import mean_bilateral
|
||||
|
||||
noisy_image = img_as_ubyte(data.camera())
|
||||
|
||||
bilat = bilateral_mean(noisy_image.astype(np.uint16), disk(20), s0=10, s1=10)
|
||||
bilat = mean_bilateral(noisy_image.astype(np.uint16), disk(20), s0=10, s1=10)
|
||||
|
||||
fig = plt.figure(figsize=[10, 7])
|
||||
fig, ax = plt.subplots(2, 2, figsize=(10, 7))
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(bilat, cmap=plt.cm.gray)
|
||||
plt.title('Bilateral mean')
|
||||
plt.axis('off')
|
||||
ax2.imshow(bilat, cmap=plt.cm.gray)
|
||||
ax2.set_title('Bilateral mean')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
ax3.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)
|
||||
ax3.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(bilat[200:350, 350:450], cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
ax4.imshow(bilat[200:350, 350:450], cmap=plt.cm.gray)
|
||||
ax4.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -203,7 +188,7 @@ from skimage.filter import rank
|
||||
noisy_image = img_as_ubyte(data.camera())
|
||||
|
||||
# equalize globally and locally
|
||||
glob = exposure.equalize(noisy_image) * 255
|
||||
glob = exposure.equalize_hist(noisy_image) * 255
|
||||
loc = rank.equalize(noisy_image, disk(20))
|
||||
|
||||
# extract histogram for each image
|
||||
@@ -211,31 +196,26 @@ hist = np.histogram(noisy_image, bins=np.arange(0, 256))
|
||||
glob_hist = np.histogram(glob, bins=np.arange(0, 256))
|
||||
loc_hist = np.histogram(loc, bins=np.arange(0, 256))
|
||||
|
||||
plt.figure(figsize=(10, 10))
|
||||
fig, ax = plt.subplots(3, 2, figsize=(10, 10))
|
||||
ax1, ax2, ax3, ax4, ax5, ax6 = ax.ravel()
|
||||
|
||||
plt.subplot(321)
|
||||
plt.imshow(noisy_image, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, interpolation='nearest', cmap=plt.cm.gray)
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(322)
|
||||
plt.plot(hist[1][:-1], hist[0], lw=2)
|
||||
plt.title('Histogram of gray values')
|
||||
ax2.plot(hist[1][:-1], hist[0], lw=2)
|
||||
ax2.set_title('Histogram of gray values')
|
||||
|
||||
plt.subplot(323)
|
||||
plt.imshow(glob, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
ax3.imshow(glob, interpolation='nearest', cmap=plt.cm.gray)
|
||||
ax3.axis('off')
|
||||
|
||||
plt.subplot(324)
|
||||
plt.plot(glob_hist[1][:-1], glob_hist[0], lw=2)
|
||||
plt.title('Histogram of gray values')
|
||||
ax4.plot(glob_hist[1][:-1], glob_hist[0], lw=2)
|
||||
ax4.set_title('Histogram of gray values')
|
||||
|
||||
plt.subplot(325)
|
||||
plt.imshow(loc, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
ax5.imshow(loc, interpolation='nearest', cmap=plt.cm.gray)
|
||||
ax5.axis('off')
|
||||
|
||||
plt.subplot(326)
|
||||
plt.plot(loc_hist[1][:-1], loc_hist[0], lw=2)
|
||||
plt.title('Histogram of gray values')
|
||||
ax6.plot(loc_hist[1][:-1], loc_hist[0], lw=2)
|
||||
ax6.set_title('Histogram of gray values')
|
||||
|
||||
"""
|
||||
|
||||
@@ -256,17 +236,15 @@ noisy_image = img_as_ubyte(data.camera())
|
||||
|
||||
auto = autolevel(noisy_image.astype(np.uint16), disk(20))
|
||||
|
||||
fig = plt.figure(figsize=[10, 7])
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[10, 7])
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.imshow(auto, cmap=plt.cm.gray)
|
||||
plt.title('Local autolevel')
|
||||
plt.axis('off')
|
||||
ax2.imshow(auto, cmap=plt.cm.gray)
|
||||
ax2.set_title('Local autolevel')
|
||||
ax2.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -297,7 +275,7 @@ fig, axes = plt.subplots(nrows=3, figsize=(7, 8))
|
||||
ax0, ax1, ax2 = axes
|
||||
plt.gray()
|
||||
|
||||
ax0.imshow(np.hstack((image, loc_autolevel)))
|
||||
ax0.imshow(np.hstack((image, loc_autolevel)), cmap=plt.cm.gray)
|
||||
ax0.set_title('Original / auto-level')
|
||||
|
||||
ax1.imshow(
|
||||
@@ -326,24 +304,22 @@ noisy_image = img_as_ubyte(data.camera())
|
||||
|
||||
enh = enhance_contrast(noisy_image, disk(5))
|
||||
|
||||
fig = plt.figure(figsize=[10, 7])
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
fig, ax = plt.subplots(2, 2, figsize=[10, 7])
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(enh, cmap=plt.cm.gray)
|
||||
plt.title('Local morphological contrast enhancement')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
ax2.imshow(enh, cmap=plt.cm.gray)
|
||||
ax2.set_title('Local morphological contrast enhancement')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(enh[200:350, 350:450], cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
ax3.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)
|
||||
ax3.axis('off')
|
||||
|
||||
ax4.imshow(enh[200:350, 350:450], cmap=plt.cm.gray)
|
||||
ax4.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -360,24 +336,22 @@ noisy_image = img_as_ubyte(data.camera())
|
||||
|
||||
penh = enhance_contrast_percentile(noisy_image, disk(5), p0=.1, p1=.9)
|
||||
|
||||
fig = plt.figure(figsize=[10, 7])
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
fig, ax = plt.subplots(2, 2, figsize=[10, 7])
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(penh, cmap=plt.cm.gray)
|
||||
plt.title('Local percentile morphological\n contrast enhancement')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
ax2.imshow(penh, cmap=plt.cm.gray)
|
||||
ax2.set_title('Local percentile morphological\n contrast enhancement')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(penh[200:350, 350:450], cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
ax3.imshow(noisy_image[200:350, 350:450], cmap=plt.cm.gray)
|
||||
ax3.axis('off')
|
||||
|
||||
ax4.imshow(penh[200:350, 350:450], cmap=plt.cm.gray)
|
||||
ax4.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -419,29 +393,24 @@ loc_otsu = p8 >= t_loc_otsu
|
||||
t_glob_otsu = threshold_otsu(p8)
|
||||
glob_otsu = p8 >= t_glob_otsu
|
||||
|
||||
plt.figure()
|
||||
fig, ax = plt.subplots(2, 2)
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(p8, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.colorbar()
|
||||
plt.axis('off')
|
||||
fig.colorbar(ax1.imshow(p8, cmap=plt.cm.gray), ax=ax1)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(t_loc_otsu, cmap=plt.cm.gray)
|
||||
plt.title('Local Otsu ($r=%d$)' % radius)
|
||||
plt.colorbar()
|
||||
plt.axis('off')
|
||||
fig.colorbar(ax2.imshow(t_loc_otsu, cmap=plt.cm.gray), ax=ax2)
|
||||
ax2.set_title('Local Otsu ($r=%d$)' % radius)
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(p8 >= t_loc_otsu, cmap=plt.cm.gray)
|
||||
plt.title('Original >= local Otsu' % t_glob_otsu)
|
||||
plt.axis('off')
|
||||
ax3.imshow(p8 >= t_loc_otsu, cmap=plt.cm.gray)
|
||||
ax3.set_title('Original >= local Otsu' % t_glob_otsu)
|
||||
ax3.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(glob_otsu, cmap=plt.cm.gray)
|
||||
plt.title('Global Otsu ($t=%d$)' % t_glob_otsu)
|
||||
plt.axis('off')
|
||||
ax4.imshow(glob_otsu, cmap=plt.cm.gray)
|
||||
ax4.set_title('Global Otsu ($t=%d$)' % t_glob_otsu)
|
||||
ax4.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -460,17 +429,15 @@ m = (np.tile(x, (n, 1)) * np.linspace(0.1, 1, n) * 128 + 128).astype(np.uint8)
|
||||
radius = 10
|
||||
t = rank.otsu(m, disk(radius))
|
||||
|
||||
plt.figure()
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2)
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.imshow(m)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
ax1.imshow(m)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.imshow(m >= t, interpolation='nearest')
|
||||
plt.title('Local Otsu ($r=%d$)' % radius)
|
||||
plt.axis('off')
|
||||
ax2.imshow(m >= t, interpolation='nearest')
|
||||
ax2.set_title('Local Otsu ($r=%d$)' % radius)
|
||||
ax2.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -501,27 +468,24 @@ opening = minimum(maximum(noisy_image, disk(5)), disk(5))
|
||||
grad = gradient(noisy_image, disk(5))
|
||||
|
||||
# display results
|
||||
fig = plt.figure(figsize=[10, 7])
|
||||
fig, ax = plt.subplots(2, 2, figsize=[10, 7])
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
ax1.imshow(noisy_image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(closing, cmap=plt.cm.gray)
|
||||
plt.title('Gray-level closing')
|
||||
plt.axis('off')
|
||||
ax2.imshow(closing, cmap=plt.cm.gray)
|
||||
ax2.set_title('Gray-level closing')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(opening, cmap=plt.cm.gray)
|
||||
plt.title('Gray-level opening')
|
||||
plt.axis('off')
|
||||
ax3.imshow(opening, cmap=plt.cm.gray)
|
||||
ax3.set_title('Gray-level opening')
|
||||
ax3.axis('off')
|
||||
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(grad, cmap=plt.cm.gray)
|
||||
plt.title('Morphological gradient')
|
||||
plt.axis('off')
|
||||
ax4.imshow(grad, cmap=plt.cm.gray)
|
||||
ax4.set_title('Morphological gradient')
|
||||
ax4.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -554,19 +518,15 @@ import matplotlib.pyplot as plt
|
||||
|
||||
image = data.camera()
|
||||
|
||||
plt.figure(figsize=(10, 4))
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
|
||||
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
plt.title('Image')
|
||||
plt.colorbar()
|
||||
plt.axis('off')
|
||||
fig.colorbar(ax1.imshow(image, cmap=plt.cm.gray), ax=ax1)
|
||||
ax1.set_title('Image')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.imshow(entropy(image, disk(5)), cmap=plt.cm.jet)
|
||||
plt.title('Entropy')
|
||||
plt.colorbar()
|
||||
plt.axis('off')
|
||||
fig.colorbar(ax2.imshow(entropy(image, disk(5)), cmap=plt.cm.jet), ax=ax2)
|
||||
ax2.set_title('Entropy')
|
||||
ax2.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
@@ -589,7 +549,6 @@ from time import time
|
||||
|
||||
from scipy.ndimage.filters import percentile_filter
|
||||
from skimage.morphology import dilation
|
||||
from skimage.filter import median_filter
|
||||
from skimage.filter.rank import median, maximum
|
||||
|
||||
|
||||
@@ -619,11 +578,6 @@ def cm_dil(image, selem):
|
||||
return dilation(image=image, selem=selem)
|
||||
|
||||
|
||||
@exec_and_timeit
|
||||
def ctmf_med(image, radius):
|
||||
return median_filter(image=image, radius=radius)
|
||||
|
||||
|
||||
@exec_and_timeit
|
||||
def ndi_med(image, n):
|
||||
return percentile_filter(image, 50, size=n * 2 - 1)
|
||||
@@ -651,12 +605,12 @@ for r in e_range:
|
||||
|
||||
rec = np.asarray(rec)
|
||||
|
||||
plt.figure()
|
||||
plt.title('Performance with respect to element size')
|
||||
plt.ylabel('Time (ms)')
|
||||
plt.title('Element radius')
|
||||
plt.plot(e_range, rec)
|
||||
plt.legend(['filter.rank.maximum', 'morphology.dilate'])
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_title('Performance with respect to element size')
|
||||
ax.set_ylabel('Time (ms)')
|
||||
ax.set_xlabel('Element radius')
|
||||
ax.plot(e_range, rec)
|
||||
ax.legend(['filter.rank.maximum', 'morphology.dilate'])
|
||||
|
||||
"""
|
||||
|
||||
@@ -679,12 +633,12 @@ for s in s_range:
|
||||
|
||||
rec = np.asarray(rec)
|
||||
|
||||
plt.figure()
|
||||
plt.title('Performance with respect to image size')
|
||||
plt.ylabel('Time (ms)')
|
||||
plt.title('Image size')
|
||||
plt.plot(s_range, rec)
|
||||
plt.legend(['filter.rank.maximum', 'morphology.dilate'])
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_title('Performance with respect to image size')
|
||||
ax.set_ylabel('Time (ms)')
|
||||
ax.set_xlabel('Image size')
|
||||
ax.plot(s_range, rec)
|
||||
ax.legend(['filter.rank.maximum', 'morphology.dilate'])
|
||||
|
||||
|
||||
"""
|
||||
@@ -694,7 +648,6 @@ plt.legend(['filter.rank.maximum', 'morphology.dilate'])
|
||||
Comparison between:
|
||||
|
||||
* `filter.rank.median`
|
||||
* `filter.median_filter`
|
||||
* `scipy.ndimage.percentile`
|
||||
|
||||
on increasing structuring element size:
|
||||
@@ -708,19 +661,17 @@ e_range = range(2, 30, 4)
|
||||
for r in e_range:
|
||||
elem = disk(r + 1)
|
||||
rc, ms_rc = cr_med(a, elem)
|
||||
rctmf, ms_rctmf = ctmf_med(a, r)
|
||||
rndi, ms_ndi = ndi_med(a, r)
|
||||
rec.append((ms_rc, ms_rctmf, ms_ndi))
|
||||
rec.append((ms_rc, ms_ndi))
|
||||
|
||||
rec = np.asarray(rec)
|
||||
|
||||
plt.figure()
|
||||
plt.title('Performance with respect to element size')
|
||||
plt.plot(e_range, rec)
|
||||
plt.legend(['filter.rank.median', 'filter.median_filter',
|
||||
'scipy.ndimage.percentile'])
|
||||
plt.ylabel('Time (ms)')
|
||||
plt.title('Element radius')
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_title('Performance with respect to element size')
|
||||
ax.plot(e_range, rec)
|
||||
ax.legend(['filter.rank.median', 'scipy.ndimage.percentile'])
|
||||
ax.set_ylabel('Time (ms)')
|
||||
ax.set_xlabel('Element radius')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -729,10 +680,10 @@ Comparison of outcome of the three methods:
|
||||
|
||||
"""
|
||||
|
||||
plt.figure()
|
||||
plt.imshow(np.hstack((rc, rctmf, rndi)))
|
||||
plt.title('filter.rank.median vs filtermedian_filter vs scipy.ndimage.percentile')
|
||||
plt.axis('off')
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(np.hstack((rc, rndi)))
|
||||
ax.set_title('filter.rank.median vs. scipy.ndimage.percentile')
|
||||
ax.axis('off')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -749,19 +700,17 @@ s_range = [100, 200, 500, 1000]
|
||||
for s in s_range:
|
||||
a = (np.random.random((s, s)) * 256).astype(np.uint8)
|
||||
(rc, ms_rc) = cr_med(a, elem)
|
||||
rctmf, ms_rctmf = ctmf_med(a, r)
|
||||
rndi, ms_ndi = ndi_med(a, r)
|
||||
rec.append((ms_rc, ms_rctmf, ms_ndi))
|
||||
rec.append((ms_rc, ms_ndi))
|
||||
|
||||
rec = np.asarray(rec)
|
||||
|
||||
plt.figure()
|
||||
plt.title('Performance with respect to image size')
|
||||
plt.plot(s_range, rec)
|
||||
plt.legend(['filter.rank.median', 'filter.median_filter',
|
||||
'scipy.ndimage.percentile'])
|
||||
plt.ylabel('Time (ms)')
|
||||
plt.title('Image size')
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_title('Performance with respect to image size')
|
||||
ax.plot(s_range, rec)
|
||||
ax.legend(['filter.rank.median', 'scipy.ndimage.percentile'])
|
||||
ax.set_ylabel('Time (ms)')
|
||||
ax.set_xlabel('Image size')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
==============
|
||||
Blob Detection
|
||||
==============
|
||||
|
||||
Blobs are bright on dark or dark on bright regions in an image. In
|
||||
this example, blobs are detected using 3 algorithms. The image used
|
||||
in this case is the Hubble eXtreme Deep Field. Each bright dot in the
|
||||
image is a star or a galaxy.
|
||||
|
||||
Laplacian of Gaussian (LoG)
|
||||
-----------------------------
|
||||
This is the most accurate and slowest approach. It computes the Laplacian
|
||||
of Gaussian images with successively increasing standard deviation and
|
||||
stacks them up in a cube. Blobs are local maximas in this cube. Detecting
|
||||
larger blobs is especially slower because of larger kernel sizes during
|
||||
convolution. Only bright blobs on dark backgrounds are detected. See
|
||||
:py:meth:`skimage.feature.blob_log` for usage.
|
||||
|
||||
Difference of Gaussian (DoG)
|
||||
----------------------------
|
||||
This is a faster approximation of LoG approach. In this case the image is
|
||||
blurred with increasing standard deviations and the difference between
|
||||
two successively blurred images are stacked up in a cube. This method
|
||||
suffers from the same disadvantage as LoG approach for detecting larger
|
||||
blobs. Blobs are again assumed to be bright on dark. See
|
||||
:py:meth:`skimage.feature.blob_dog` for usage.
|
||||
|
||||
Determinant of Hessian (DoH)
|
||||
----------------------------
|
||||
This is the fastest approach. It detects blobs by finding maximas in the
|
||||
matrix of the Determinant of Hessian of the image. The detection speed is
|
||||
independent of the size of blobs as internally the implementation uses
|
||||
box filters instead of convolutions. Bright on dark as well as dark on
|
||||
bright blobs are detected. The downside is that small blobs (<3px) are not
|
||||
detected accurately. See :py:meth:`skimage.feature.blob_doh` for usage.
|
||||
|
||||
"""
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
from skimage import data
|
||||
from skimage.feature import blob_dog, blob_log, blob_doh
|
||||
from math import sqrt
|
||||
from skimage.color import rgb2gray
|
||||
|
||||
image = data.hubble_deep_field()[0:500, 0:500]
|
||||
image_gray = rgb2gray(image)
|
||||
|
||||
blobs_log = blob_log(image_gray, max_sigma=30, num_sigma=10, threshold=.1)
|
||||
# Compute radii in the 3rd column.
|
||||
blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)
|
||||
|
||||
blobs_dog = blob_dog(image_gray, max_sigma=30, threshold=.1)
|
||||
blobs_dog[:, 2] = blobs_dog[:, 2] * sqrt(2)
|
||||
|
||||
blobs_doh = blob_doh(image_gray, max_sigma=30, threshold=.01)
|
||||
|
||||
blobs_list = [blobs_log, blobs_dog, blobs_doh]
|
||||
colors = ['yellow', 'lime', 'red']
|
||||
titles = ['Laplacian of Gaussian', 'Difference of Gaussian',
|
||||
'Determinant of Hessian']
|
||||
sequence = zip(blobs_list, colors, titles)
|
||||
|
||||
for blobs, color, title in sequence:
|
||||
fig, ax = plt.subplots(1, 1)
|
||||
ax.set_title(title)
|
||||
ax.imshow(image, interpolation='nearest')
|
||||
for blob in blobs:
|
||||
y, x, r = blob
|
||||
c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)
|
||||
ax.add_patch(c)
|
||||
|
||||
plt.show()
|
||||
@@ -0,0 +1,61 @@
|
||||
"""
|
||||
=======================
|
||||
BRIEF binary descriptor
|
||||
=======================
|
||||
|
||||
This example demonstrates the BRIEF binary description algorithm.
|
||||
|
||||
The descriptor consists of relatively few bits and can be computed using
|
||||
a set of intensity difference tests. The short binary descriptor results
|
||||
in low memory footprint and very efficient matching based on the Hamming
|
||||
distance metric.
|
||||
|
||||
BRIEF does not provide rotation-invariance. Scale-invariance can be achieved by
|
||||
detecting and extracting features at different scales.
|
||||
|
||||
"""
|
||||
from skimage import data
|
||||
from skimage import transform as tf
|
||||
from skimage.feature import (match_descriptors, corner_peaks, corner_harris,
|
||||
plot_matches, BRIEF)
|
||||
from skimage.color import rgb2gray
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
img1 = rgb2gray(data.lena())
|
||||
tform = tf.AffineTransform(scale=(1.2, 1.2), translation=(0, -100))
|
||||
img2 = tf.warp(img1, tform)
|
||||
img3 = tf.rotate(img1, 25)
|
||||
|
||||
keypoints1 = corner_peaks(corner_harris(img1), min_distance=5)
|
||||
keypoints2 = corner_peaks(corner_harris(img2), min_distance=5)
|
||||
keypoints3 = corner_peaks(corner_harris(img3), min_distance=5)
|
||||
|
||||
extractor = BRIEF()
|
||||
|
||||
extractor.extract(img1, keypoints1)
|
||||
keypoints1 = keypoints1[extractor.mask]
|
||||
descriptors1 = extractor.descriptors
|
||||
|
||||
extractor.extract(img2, keypoints2)
|
||||
keypoints2 = keypoints2[extractor.mask]
|
||||
descriptors2 = extractor.descriptors
|
||||
|
||||
extractor.extract(img3, keypoints3)
|
||||
keypoints3 = keypoints3[extractor.mask]
|
||||
descriptors3 = extractor.descriptors
|
||||
|
||||
matches12 = match_descriptors(descriptors1, descriptors2, cross_check=True)
|
||||
matches13 = match_descriptors(descriptors1, descriptors3, cross_check=True)
|
||||
|
||||
fig, ax = plt.subplots(nrows=2, ncols=1)
|
||||
|
||||
plt.gray()
|
||||
|
||||
plot_matches(ax[0], img1, img2, keypoints1, keypoints2, matches12)
|
||||
ax[0].axis('off')
|
||||
|
||||
plot_matches(ax[1], img1, img3, keypoints1, keypoints3, matches13)
|
||||
ax[1].axis('off')
|
||||
|
||||
plt.show()
|
||||
+11
-14
@@ -35,24 +35,21 @@ edges1 = filter.canny(im)
|
||||
edges2 = filter.canny(im, sigma=3)
|
||||
|
||||
# display results
|
||||
plt.figure(figsize=(8, 3))
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 3))
|
||||
|
||||
plt.subplot(131)
|
||||
plt.imshow(im, cmap=plt.cm.jet)
|
||||
plt.axis('off')
|
||||
plt.title('noisy image', fontsize=20)
|
||||
ax1.imshow(im, cmap=plt.cm.jet)
|
||||
ax1.axis('off')
|
||||
ax1.set_title('noisy image', fontsize=20)
|
||||
|
||||
plt.subplot(132)
|
||||
plt.imshow(edges1, cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
plt.title('Canny filter, $\sigma=1$', fontsize=20)
|
||||
ax2.imshow(edges1, cmap=plt.cm.gray)
|
||||
ax2.axis('off')
|
||||
ax2.set_title('Canny filter, $\sigma=1$', fontsize=20)
|
||||
|
||||
plt.subplot(133)
|
||||
plt.imshow(edges2, cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
plt.title('Canny filter, $\sigma=3$', fontsize=20)
|
||||
ax3.imshow(edges2, cmap=plt.cm.gray)
|
||||
ax3.axis('off')
|
||||
ax3.set_title('Canny filter, $\sigma=3$', fontsize=20)
|
||||
|
||||
plt.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9,
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9,
|
||||
bottom=0.02, left=0.02, right=0.98)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
========================
|
||||
CENSURE feature detector
|
||||
========================
|
||||
|
||||
The CENSURE feature detector is a scale-invariant center-surround detector
|
||||
(CENSURE) that claims to outperform other detectors and is capable of real-time
|
||||
implementation.
|
||||
|
||||
"""
|
||||
from skimage import data
|
||||
from skimage import transform as tf
|
||||
from skimage.feature import CENSURE
|
||||
from skimage.color import rgb2gray
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
img1 = rgb2gray(data.lena())
|
||||
tform = tf.AffineTransform(scale=(1.5, 1.5), rotation=0.5,
|
||||
translation=(150, -200))
|
||||
img2 = tf.warp(img1, tform)
|
||||
|
||||
detector = CENSURE()
|
||||
|
||||
fig, ax = plt.subplots(nrows=1, ncols=2)
|
||||
|
||||
plt.gray()
|
||||
|
||||
detector.detect(img1)
|
||||
|
||||
ax[0].imshow(img1)
|
||||
ax[0].axis('off')
|
||||
ax[0].scatter(detector.keypoints[:, 1], detector.keypoints[:, 0],
|
||||
2 ** detector.scales, facecolors='none', edgecolors='r')
|
||||
|
||||
detector.detect(img2)
|
||||
|
||||
ax[1].imshow(img2)
|
||||
ax[1].axis('off')
|
||||
ax[1].scatter(detector.keypoints[:, 1], detector.keypoints[:, 0],
|
||||
2 ** detector.scales, facecolors='none', edgecolors='r')
|
||||
|
||||
plt.show()
|
||||
@@ -48,7 +48,7 @@ from skimage.util import img_as_ubyte
|
||||
image = img_as_ubyte(data.coins()[0:95, 70:370])
|
||||
edges = filter.canny(image, sigma=3, low_threshold=10, high_threshold=50)
|
||||
|
||||
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
|
||||
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(5, 2))
|
||||
|
||||
# Detect two radii
|
||||
hough_radii = np.arange(15, 30, 2)
|
||||
@@ -77,6 +77,8 @@ ax.imshow(image, cmap=plt.cm.gray)
|
||||
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
Ellipse detection
|
||||
=================
|
||||
|
||||
@@ -137,7 +139,7 @@ image_rgb[cy, cx] = (0, 0, 255)
|
||||
edges = color.gray2rgb(edges)
|
||||
edges[cy, cx] = (250, 0, 0)
|
||||
|
||||
fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(10, 6))
|
||||
fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4))
|
||||
|
||||
ax1.set_title('Original picture')
|
||||
ax1.imshow(image_rgb)
|
||||
@@ -146,3 +148,8 @@ ax2.set_title('Edge (white) and result (red)')
|
||||
ax2.imshow(edges)
|
||||
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
"""
|
||||
|
||||
@@ -29,12 +29,13 @@ r = np.sin(np.exp((np.sin(x)**3 + np.cos(y)**2)))
|
||||
contours = measure.find_contours(r, 0.8)
|
||||
|
||||
# Display the image and plot all contours found
|
||||
plt.imshow(r, interpolation='nearest')
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(r, interpolation='nearest', cmap=plt.cm.gray)
|
||||
|
||||
for n, contour in enumerate(contours):
|
||||
plt.plot(contour[:, 1], contour[:, 0], linewidth=2)
|
||||
ax.plot(contour[:, 1], contour[:, 0], linewidth=2)
|
||||
|
||||
plt.axis('image')
|
||||
plt.xticks([])
|
||||
plt.yticks([])
|
||||
ax.axis('image')
|
||||
ax.set_xticks([])
|
||||
ax.set_yticks([])
|
||||
plt.show()
|
||||
|
||||
@@ -40,11 +40,9 @@ image[chull] += 1
|
||||
# [ 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
|
||||
|
||||
|
||||
fig = plt.subplots(figsize=(10, 6))
|
||||
plt.subplot(1, 2, 1)
|
||||
plt.title('Original picture')
|
||||
plt.imshow(original_image, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.subplot(1, 2, 2)
|
||||
plt.title('Transformed picture')
|
||||
plt.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 6))
|
||||
ax1.set_title('Original picture')
|
||||
ax1.imshow(original_image, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax2.set_title('Transformed picture')
|
||||
ax2.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.show()
|
||||
|
||||
@@ -29,9 +29,9 @@ image[230:280, 60:110] = 1
|
||||
coords = corner_peaks(corner_harris(image), min_distance=5)
|
||||
coords_subpix = corner_subpix(image, coords, window_size=13)
|
||||
|
||||
plt.gray()
|
||||
plt.imshow(image, interpolation='nearest')
|
||||
plt.plot(coords[:, 1], coords[:, 0], '.b', markersize=3)
|
||||
plt.plot(coords_subpix[:, 1], coords_subpix[:, 0], '+r', markersize=15)
|
||||
plt.axis((0, 350, 350, 0))
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(image, interpolation='nearest', cmap=plt.cm.gray)
|
||||
ax.plot(coords[:, 1], coords[:, 0], '.b', markersize=3)
|
||||
ax.plot(coords_subpix[:, 1], coords_subpix[:, 0], '+r', markersize=15)
|
||||
ax.axis((0, 350, 350, 0))
|
||||
plt.show()
|
||||
|
||||
@@ -20,8 +20,9 @@ img = data.camera()
|
||||
descs, descs_img = daisy(img, step=180, radius=58, rings=2, histograms=6,
|
||||
orientations=8, visualize=True)
|
||||
|
||||
plt.axis('off')
|
||||
plt.imshow(descs_img)
|
||||
fig, ax = plt.subplots()
|
||||
ax.axis('off')
|
||||
ax.imshow(descs_img)
|
||||
descs_num = descs.shape[0] * descs.shape[1]
|
||||
plt.title('%i DAISY descriptors extracted:' % descs_num)
|
||||
ax.set_title('%i DAISY descriptors extracted:' % descs_num)
|
||||
plt.show()
|
||||
|
||||
@@ -29,7 +29,7 @@ import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import data, img_as_float
|
||||
from skimage.filter import denoise_tv_chambolle, denoise_bilateral
|
||||
from skimage.restoration import denoise_tv_chambolle, denoise_bilateral
|
||||
|
||||
|
||||
lena = img_as_float(data.lena())
|
||||
|
||||
@@ -22,11 +22,11 @@ fig, (ax0, ax1) = plt.subplots(ncols=2, figsize=(10, 4))
|
||||
img0 = ax0.imshow(image, cmap=plt.cm.gray)
|
||||
ax0.set_title('Image')
|
||||
ax0.axis('off')
|
||||
plt.colorbar(img0, ax=ax0)
|
||||
fig.colorbar(img0, ax=ax0)
|
||||
|
||||
img1 = ax1.imshow(entropy(image, disk(5)), cmap=plt.cm.jet)
|
||||
ax1.set_title('Entropy')
|
||||
ax1.axis('off')
|
||||
plt.colorbar(img1, ax=ax1)
|
||||
fig.colorbar(img1, ax=ax1)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -17,6 +17,8 @@ that fall within the 2nd and 98th percentiles [2]_.
|
||||
.. [2] http://homepages.inf.ed.ac.uk/rbf/HIPR2/stretch.htm
|
||||
|
||||
"""
|
||||
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
@@ -24,6 +26,9 @@ from skimage import data, img_as_float
|
||||
from skimage import exposure
|
||||
|
||||
|
||||
matplotlib.rcParams['font.size'] = 8
|
||||
|
||||
|
||||
def plot_img_and_hist(img, axes, bins=256):
|
||||
"""Plot an image along with its histogram and cumulative histogram.
|
||||
|
||||
@@ -55,8 +60,7 @@ def plot_img_and_hist(img, axes, bins=256):
|
||||
img = data.moon()
|
||||
|
||||
# Contrast stretching
|
||||
p2 = np.percentile(img, 2)
|
||||
p98 = np.percentile(img, 98)
|
||||
p2, p98 = np.percentile(img, (2, 98))
|
||||
img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))
|
||||
|
||||
# Equalization
|
||||
@@ -66,7 +70,7 @@ img_eq = exposure.equalize_hist(img)
|
||||
img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03)
|
||||
|
||||
# Display results
|
||||
f, axes = plt.subplots(2, 4, figsize=(8, 4))
|
||||
fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(8, 5))
|
||||
|
||||
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
|
||||
ax_img.set_title('Low contrast image')
|
||||
@@ -88,5 +92,5 @@ ax_cdf.set_ylabel('Fraction of total intensity')
|
||||
ax_cdf.set_yticks(np.linspace(0, 1, 5))
|
||||
|
||||
# prevent overlap of y-axis labels
|
||||
plt.subplots_adjust(wspace=0.4)
|
||||
fig.subplots_adjust(wspace=0.4)
|
||||
plt.show()
|
||||
|
||||
@@ -24,9 +24,6 @@ from skimage.util import img_as_float
|
||||
from skimage.filter import gabor_kernel
|
||||
|
||||
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
|
||||
def compute_feats(image, kernels):
|
||||
feats = np.zeros((len(kernels), 2), dtype=np.double)
|
||||
for k, kernel in enumerate(kernels):
|
||||
@@ -104,24 +101,24 @@ for theta in (0, 1):
|
||||
# Save kernel and the power image for each image
|
||||
results.append((kernel, [power(img, kernel) for img in images]))
|
||||
|
||||
fig, axes = plt.subplots(nrows=5, ncols=4, figsize=(9, 6))
|
||||
fig, axes = plt.subplots(nrows=5, ncols=4, figsize=(5, 6))
|
||||
plt.gray()
|
||||
|
||||
fig.suptitle('Image responses for Gabor filter kernels', fontsize=15)
|
||||
fig.suptitle('Image responses for Gabor filter kernels', fontsize=12)
|
||||
|
||||
axes[0][0].axis('off')
|
||||
|
||||
# Plot original images
|
||||
for label, img, ax in zip(image_names, images, axes[0][1:]):
|
||||
ax.imshow(img)
|
||||
ax.set_title(label)
|
||||
ax.set_title(label, fontsize=9)
|
||||
ax.axis('off')
|
||||
|
||||
for label, (kernel, powers), ax_row in zip(kernel_params, results, axes[1:]):
|
||||
# Plot Gabor kernel
|
||||
ax = ax_row[0]
|
||||
ax.imshow(np.real(kernel), interpolation='nearest')
|
||||
ax.set_ylabel(label)
|
||||
ax.set_ylabel(label, fontsize=7)
|
||||
ax.set_xticks([])
|
||||
ax.set_yticks([])
|
||||
|
||||
|
||||
+33
-32
@@ -53,44 +53,45 @@ for i, patch in enumerate(grass_patches + sky_patches):
|
||||
ys.append(greycoprops(glcm, 'correlation')[0, 0])
|
||||
|
||||
# create the figure
|
||||
plt.figure(figsize=(8, 8))
|
||||
fig = plt.figure(figsize=(8, 8))
|
||||
|
||||
# display original image with locations of patches
|
||||
ax = fig.add_subplot(3, 2, 1)
|
||||
ax.imshow(image, cmap=plt.cm.gray, interpolation='nearest',
|
||||
vmin=0, vmax=255)
|
||||
for (y, x) in grass_locations:
|
||||
ax.plot(x + PATCH_SIZE / 2, y + PATCH_SIZE / 2, 'gs')
|
||||
for (y, x) in sky_locations:
|
||||
ax.plot(x + PATCH_SIZE / 2, y + PATCH_SIZE / 2, 'bs')
|
||||
ax.set_xlabel('Original Image')
|
||||
ax.set_xticks([])
|
||||
ax.set_yticks([])
|
||||
ax.axis('image')
|
||||
|
||||
# for each patch, plot (dissimilarity, correlation)
|
||||
ax = fig.add_subplot(3, 2, 2)
|
||||
ax.plot(xs[:len(grass_patches)], ys[:len(grass_patches)], 'go',
|
||||
label='Grass')
|
||||
ax.plot(xs[len(grass_patches):], ys[len(grass_patches):], 'bo',
|
||||
label='Sky')
|
||||
ax.set_xlabel('GLCM Dissimilarity')
|
||||
ax.set_ylabel('GLVM Correlation')
|
||||
ax.legend()
|
||||
|
||||
# display the image patches
|
||||
for i, patch in enumerate(grass_patches):
|
||||
plt.subplot(3, len(grass_patches), len(grass_patches) * 1 + i + 1)
|
||||
plt.imshow(patch, cmap=plt.cm.gray, interpolation='nearest',
|
||||
vmin=0, vmax=255)
|
||||
plt.xlabel('Grass %d' % (i + 1))
|
||||
ax = fig.add_subplot(3, len(grass_patches), len(grass_patches)*1 + i + 1)
|
||||
ax.imshow(patch, cmap=plt.cm.gray, interpolation='nearest',
|
||||
vmin=0, vmax=255)
|
||||
ax.set_xlabel('Grass %d' % (i + 1))
|
||||
|
||||
for i, patch in enumerate(sky_patches):
|
||||
plt.subplot(3, len(grass_patches), len(grass_patches) * 2 + i + 1)
|
||||
plt.imshow(patch, cmap=plt.cm.gray, interpolation='nearest',
|
||||
vmin=0, vmax=255)
|
||||
plt.xlabel('Sky %d' % (i + 1))
|
||||
ax = fig.add_subplot(3, len(sky_patches), len(sky_patches)*2 + i + 1)
|
||||
ax.imshow(patch, cmap=plt.cm.gray, interpolation='nearest',
|
||||
vmin=0, vmax=255)
|
||||
ax.set_xlabel('Sky %d' % (i + 1))
|
||||
|
||||
# display original image with locations of patches
|
||||
plt.subplot(3, 2, 1)
|
||||
plt.imshow(image, cmap=plt.cm.gray, interpolation='nearest',
|
||||
vmin=0, vmax=255)
|
||||
for (y, x) in grass_locations:
|
||||
plt.plot(x + PATCH_SIZE / 2, y + PATCH_SIZE / 2, 'gs')
|
||||
for (y, x) in sky_locations:
|
||||
plt.plot(x + PATCH_SIZE / 2, y + PATCH_SIZE / 2, 'bs')
|
||||
plt.xlabel('Original Image')
|
||||
plt.xticks([])
|
||||
plt.yticks([])
|
||||
plt.axis('image')
|
||||
|
||||
# for each patch, plot (dissimilarity, correlation)
|
||||
plt.subplot(3, 2, 2)
|
||||
plt.plot(xs[:len(grass_patches)], ys[:len(grass_patches)], 'go',
|
||||
label='Grass')
|
||||
plt.plot(xs[len(grass_patches):], ys[len(grass_patches):], 'bo',
|
||||
label='Sky')
|
||||
plt.xlabel('GLCM Dissimilarity')
|
||||
plt.ylabel('GLVM Correlation')
|
||||
plt.legend()
|
||||
|
||||
# display the patches and plot
|
||||
plt.suptitle('Grey level co-occurrence matrix features', fontsize=14)
|
||||
fig.suptitle('Grey level co-occurrence matrix features', fontsize=14)
|
||||
plt.show()
|
||||
|
||||
@@ -90,16 +90,16 @@ image = color.rgb2gray(data.lena())
|
||||
fd, hog_image = hog(image, orientations=8, pixels_per_cell=(16, 16),
|
||||
cells_per_block=(1, 1), visualise=True)
|
||||
|
||||
plt.figure(figsize=(8, 4))
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
|
||||
|
||||
plt.subplot(121).set_axis_off()
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
plt.title('Input image')
|
||||
ax1.axis('off')
|
||||
ax1.imshow(image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Input image')
|
||||
|
||||
# Rescale histogram for better display
|
||||
hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 0.02))
|
||||
|
||||
plt.subplot(122).set_axis_off()
|
||||
plt.imshow(hog_image_rescaled, cmap=plt.cm.gray)
|
||||
plt.title('Histogram of Oriented Gradients')
|
||||
ax2.axis('off')
|
||||
ax2.imshow(hog_image_rescaled, cmap=plt.cm.gray)
|
||||
ax2.set_title('Histogram of Oriented Gradients')
|
||||
plt.show()
|
||||
|
||||
@@ -22,13 +22,13 @@ image = data.moon()
|
||||
image = rescale_intensity(image, in_range=(50, 200))
|
||||
|
||||
# convenience function for plotting images
|
||||
def imshow(image, **kwargs):
|
||||
plt.figure(figsize=(5, 4))
|
||||
plt.imshow(image, **kwargs)
|
||||
plt.axis('off')
|
||||
def imshow(image, title, **kwargs):
|
||||
fig, ax = plt.subplots(figsize=(5, 4))
|
||||
ax.imshow(image, **kwargs)
|
||||
ax.axis('off')
|
||||
ax.set_title(title)
|
||||
|
||||
imshow(image)
|
||||
plt.title('original image')
|
||||
imshow(image, 'Original image')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -50,8 +50,7 @@ mask = image
|
||||
|
||||
filled = reconstruction(seed, mask, method='erosion')
|
||||
|
||||
imshow(filled, vmin=image.min(), vmax=image.max())
|
||||
plt.title('after filling holes')
|
||||
imshow(filled, 'after filling holes',vmin=image.min(), vmax=image.max())
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -62,8 +61,8 @@ isolate the dark regions by subtracting the reconstructed image from the
|
||||
original image.
|
||||
"""
|
||||
|
||||
imshow(image - filled)
|
||||
plt.title('holes')
|
||||
imshow(image - filled, 'holes')
|
||||
# plt.title('holes')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
@@ -78,8 +77,7 @@ intensity instead of the maximum. The remainder of the process is the same.
|
||||
seed = np.copy(image)
|
||||
seed[1:-1, 1:-1] = image.min()
|
||||
rec = reconstruction(seed, mask, method='dilation')
|
||||
imshow(image - rec)
|
||||
plt.title('peaks')
|
||||
imshow(image - rec, 'peaks')
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
|
||||
@@ -61,10 +61,10 @@ h = rescale_intensity(ihc_hed[:, :, 0], out_range=(0, 1))
|
||||
d = rescale_intensity(ihc_hed[:, :, 2], out_range=(0, 1))
|
||||
zdh = np.dstack((np.zeros_like(h), d, h))
|
||||
|
||||
plt.figure()
|
||||
plt.imshow(zdh)
|
||||
plt.title("Stain separated image (rescaled)")
|
||||
plt.axis('off')
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(zdh)
|
||||
ax.set_title("Stain separated image (rescaled)")
|
||||
ax.axis('off')
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
|
||||
@@ -58,5 +58,5 @@ axes[3].set_title('Join')
|
||||
|
||||
for ax in axes:
|
||||
ax.axis('off')
|
||||
plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
plt.show()
|
||||
|
||||
@@ -43,14 +43,14 @@ image_label_overlay = label2rgb(label_image, image=image)
|
||||
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
|
||||
ax.imshow(image_label_overlay)
|
||||
|
||||
for region in regionprops(label_image, ['Area', 'BoundingBox']):
|
||||
for region in regionprops(label_image):
|
||||
|
||||
# skip small images
|
||||
if region['Area'] < 100:
|
||||
if region.area < 100:
|
||||
continue
|
||||
|
||||
# draw rectangle around segmented coins
|
||||
minr, minc, maxr, maxc = region['BoundingBox']
|
||||
minr, minc, maxr, maxc = region.bbox
|
||||
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
|
||||
fill=False, edgecolor='red', linewidth=2)
|
||||
ax.add_patch(rect)
|
||||
|
||||
@@ -77,30 +77,30 @@ image[idx, idx] = 255
|
||||
|
||||
h, theta, d = hough_line(image)
|
||||
|
||||
plt.figure(figsize=(8, 4))
|
||||
fig, ax = plt.subplots(1, 3, figsize=(8, 4))
|
||||
|
||||
plt.subplot(131)
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
plt.title('Input image')
|
||||
ax[0].imshow(image, cmap=plt.cm.gray)
|
||||
ax[0].set_title('Input image')
|
||||
ax[0].axis('image')
|
||||
|
||||
plt.subplot(132)
|
||||
plt.imshow(np.log(1 + h),
|
||||
ax[1].imshow(np.log(1 + h),
|
||||
extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
|
||||
d[-1], d[0]],
|
||||
cmap=plt.cm.gray, aspect=1/1.5)
|
||||
plt.title('Hough transform')
|
||||
plt.xlabel('Angles (degrees)')
|
||||
plt.ylabel('Distance (pixels)')
|
||||
ax[1].set_title('Hough transform')
|
||||
ax[1].set_xlabel('Angles (degrees)')
|
||||
ax[1].set_ylabel('Distance (pixels)')
|
||||
ax[1].axis('image')
|
||||
|
||||
plt.subplot(133)
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
ax[2].imshow(image, cmap=plt.cm.gray)
|
||||
rows, cols = image.shape
|
||||
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
|
||||
y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
|
||||
y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
|
||||
plt.plot((0, cols), (y0, y1), '-r')
|
||||
plt.axis((0, cols, rows, 0))
|
||||
plt.title('Detected lines')
|
||||
ax[2].plot((0, cols), (y0, y1), '-r')
|
||||
ax[2].axis((0, cols, rows, 0))
|
||||
ax[2].set_title('Detected lines')
|
||||
ax[2].axis('image')
|
||||
|
||||
# Line finding, using the Probabilistic Hough Transform
|
||||
|
||||
@@ -108,23 +108,22 @@ image = data.camera()
|
||||
edges = canny(image, 2, 1, 25)
|
||||
lines = probabilistic_hough_line(edges, threshold=10, line_length=5, line_gap=3)
|
||||
|
||||
plt.figure(figsize=(8, 3))
|
||||
fig2, ax = plt.subplots(1, 3, figsize=(8, 3))
|
||||
|
||||
plt.subplot(131)
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
plt.title('Input image')
|
||||
ax[0].imshow(image, cmap=plt.cm.gray)
|
||||
ax[0].set_title('Input image')
|
||||
ax[0].axis('image')
|
||||
|
||||
plt.subplot(132)
|
||||
plt.imshow(edges, cmap=plt.cm.gray)
|
||||
plt.title('Canny edges')
|
||||
ax[1].imshow(edges, cmap=plt.cm.gray)
|
||||
ax[1].set_title('Canny edges')
|
||||
ax[1].axis('image')
|
||||
|
||||
plt.subplot(133)
|
||||
plt.imshow(edges * 0)
|
||||
ax[2].imshow(edges * 0)
|
||||
|
||||
for line in lines:
|
||||
p0, p1 = line
|
||||
plt.plot((p0[0], p1[0]), (p0[1], p1[1]))
|
||||
ax[2].plot((p0[0], p1[0]), (p0[1], p1[1]))
|
||||
|
||||
plt.title('Probabilistic Hough')
|
||||
plt.axis('image')
|
||||
ax[2].set_title('Probabilistic Hough')
|
||||
ax[2].axis('image')
|
||||
plt.show()
|
||||
|
||||
@@ -20,6 +20,7 @@ References
|
||||
|
||||
"""
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import data
|
||||
@@ -30,6 +31,9 @@ from skimage.morphology import disk
|
||||
from skimage.filter import rank
|
||||
|
||||
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
|
||||
def plot_img_and_hist(img, axes, bins=256):
|
||||
"""Plot an image along with its histogram and cumulative histogram.
|
||||
|
||||
@@ -59,9 +63,7 @@ def plot_img_and_hist(img, axes, bins=256):
|
||||
# Load an example image
|
||||
img = img_as_ubyte(data.moon())
|
||||
|
||||
# Contrast stretching
|
||||
p2 = np.percentile(img, 2)
|
||||
p98 = np.percentile(img, 98)
|
||||
# Global equalize
|
||||
img_rescale = exposure.equalize_hist(img)
|
||||
|
||||
# Equalization
|
||||
@@ -70,7 +72,7 @@ img_eq = rank.equalize(img, selem=selem)
|
||||
|
||||
|
||||
# Display results
|
||||
f, axes = plt.subplots(2, 3, figsize=(8, 4))
|
||||
fig, axes = plt.subplots(2, 3, figsize=(8, 5))
|
||||
|
||||
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
|
||||
ax_img.set_title('Low contrast image')
|
||||
@@ -85,5 +87,5 @@ ax_cdf.set_ylabel('Fraction of total intensity')
|
||||
|
||||
|
||||
# prevent overlap of y-axis labels
|
||||
plt.subplots_adjust(wspace=0.4)
|
||||
fig.subplots_adjust(wspace=0.4)
|
||||
plt.show()
|
||||
|
||||
@@ -15,6 +15,7 @@ The example compares the local threshold with the global threshold.
|
||||
.. [1] http://en.wikipedia.org/wiki/Otsu's_method
|
||||
|
||||
"""
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import data
|
||||
@@ -23,29 +24,38 @@ from skimage.filter import threshold_otsu, rank
|
||||
from skimage.util import img_as_ubyte
|
||||
|
||||
|
||||
p8 = img_as_ubyte(data.page())
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
radius = 10
|
||||
|
||||
img = img_as_ubyte(data.page())
|
||||
|
||||
radius = 15
|
||||
selem = disk(radius)
|
||||
|
||||
loc_otsu = rank.otsu(p8, selem)
|
||||
t_glob_otsu = threshold_otsu(p8)
|
||||
glob_otsu = p8 >= t_glob_otsu
|
||||
local_otsu = rank.otsu(img, selem)
|
||||
threshold_global_otsu = threshold_otsu(img)
|
||||
global_otsu = img >= threshold_global_otsu
|
||||
|
||||
|
||||
plt.figure()
|
||||
plt.subplot(2, 2, 1)
|
||||
plt.imshow(p8, cmap=plt.cm.gray)
|
||||
plt.xlabel('original')
|
||||
plt.colorbar()
|
||||
plt.subplot(2, 2, 2)
|
||||
plt.imshow(loc_otsu, cmap=plt.cm.gray)
|
||||
plt.xlabel('local Otsu ($radius=%d$)' % radius)
|
||||
plt.colorbar()
|
||||
plt.subplot(2, 2, 3)
|
||||
plt.imshow(p8 >= loc_otsu, cmap=plt.cm.gray)
|
||||
plt.xlabel('original >= local Otsu' % t_glob_otsu)
|
||||
plt.subplot(2, 2, 4)
|
||||
plt.imshow(glob_otsu, cmap=plt.cm.gray)
|
||||
plt.xlabel('global Otsu ($t = %d$)' % t_glob_otsu)
|
||||
fig, ax = plt.subplots(2, 2, figsize=(8, 5))
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
fig.colorbar(ax1.imshow(img, cmap=plt.cm.gray),
|
||||
ax=ax1, orientation='horizontal')
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
fig.colorbar(ax2.imshow(local_otsu, cmap=plt.cm.gray),
|
||||
ax=ax2, orientation='horizontal')
|
||||
ax2.set_title('Local Otsu (radius=%d)' % radius)
|
||||
ax2.axis('off')
|
||||
|
||||
ax3.imshow(img >= local_otsu, cmap=plt.cm.gray)
|
||||
ax3.set_title('Original >= Local Otsu' % threshold_global_otsu)
|
||||
ax3.axis('off')
|
||||
|
||||
ax4.imshow(global_otsu, cmap=plt.cm.gray)
|
||||
ax4.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu)
|
||||
ax4.axis('off')
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -51,5 +51,5 @@ ax3.imshow(labels, cmap=plt.cm.spectral, interpolation='nearest', alpha=.7)
|
||||
for ax in axes:
|
||||
ax.axis('off')
|
||||
|
||||
plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
plt.show()
|
||||
|
||||
@@ -27,7 +27,8 @@ from matplotlib import pyplot as plt
|
||||
|
||||
from skimage import data
|
||||
from skimage.util import img_as_float
|
||||
from skimage.feature import corner_harris, corner_subpix, corner_peaks
|
||||
from skimage.feature import (corner_harris, corner_subpix, corner_peaks,
|
||||
plot_matches)
|
||||
from skimage.transform import warp, AffineTransform
|
||||
from skimage.exposure import rescale_intensity
|
||||
from skimage.color import rgb2gray
|
||||
@@ -71,7 +72,7 @@ def gaussian_weights(window_ext, sigma=1):
|
||||
|
||||
|
||||
def match_corner(coord, window_ext=5):
|
||||
r, c = np.round(coord)
|
||||
r, c = np.round(coord).astype(np.intp)
|
||||
window_orig = img_orig[r-window_ext:r+window_ext+1,
|
||||
c-window_ext:c+window_ext+1, :]
|
||||
|
||||
@@ -117,28 +118,21 @@ print(tform.scale, tform.translation, tform.rotation)
|
||||
print(model.scale, model.translation, model.rotation)
|
||||
print(model_robust.scale, model_robust.translation, model_robust.rotation)
|
||||
|
||||
|
||||
# visualize correspondences
|
||||
img_combined = np.concatenate((img_orig_gray, img_warped_gray), axis=1)
|
||||
|
||||
# visualize correspondence
|
||||
fig, ax = plt.subplots(nrows=2, ncols=1)
|
||||
|
||||
plt.gray()
|
||||
|
||||
ax[0].imshow(img_combined, interpolation='nearest')
|
||||
inlier_idxs = np.nonzero(inliers)[0]
|
||||
plot_matches(ax[0], img_orig_gray, img_warped_gray, src, dst,
|
||||
np.column_stack((inlier_idxs, inlier_idxs)), matches_color='b')
|
||||
ax[0].axis('off')
|
||||
ax[0].axis((0, 400, 200, 0))
|
||||
ax[0].set_title('Correct correspondences')
|
||||
ax[1].imshow(img_combined, interpolation='nearest')
|
||||
|
||||
outlier_idxs = np.nonzero(outliers)[0]
|
||||
plot_matches(ax[1], img_orig_gray, img_warped_gray, src, dst,
|
||||
np.column_stack((outlier_idxs, outlier_idxs)), matches_color='r')
|
||||
ax[1].axis('off')
|
||||
ax[1].axis((0, 400, 200, 0))
|
||||
ax[1].set_title('Faulty correspondences')
|
||||
|
||||
|
||||
for ax_idx, (m, color) in enumerate(((inliers, 'g'), (outliers, 'r'))):
|
||||
ax[ax_idx].plot((src[m, 1], dst[m, 1] + 200), (src[m, 0], dst[m, 0]), '-',
|
||||
color=color)
|
||||
ax[ax_idx].plot(src[m, 1], src[m, 0], '.', markersize=10, color=color)
|
||||
ax[ax_idx].plot(dst[m, 1] + 200, dst[m, 0], '.', markersize=10,
|
||||
color=color)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -55,14 +55,12 @@ skel, distance = medial_axis(data, return_distance=True)
|
||||
# Distance to the background for pixels of the skeleton
|
||||
dist_on_skel = distance * skel
|
||||
|
||||
plt.figure(figsize=(8, 4))
|
||||
plt.subplot(121)
|
||||
plt.imshow(data, cmap=plt.cm.gray, interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.subplot(122)
|
||||
plt.imshow(dist_on_skel, cmap=plt.cm.spectral, interpolation='nearest')
|
||||
plt.contour(data, [0.5], colors='w')
|
||||
plt.axis('off')
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
|
||||
ax1.imshow(data, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax1.axis('off')
|
||||
ax2.imshow(dist_on_skel, cmap=plt.cm.spectral, interpolation='nearest')
|
||||
ax2.contour(data, [0.5], colors='w')
|
||||
ax2.axis('off')
|
||||
|
||||
plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
plt.show()
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
==========================================
|
||||
ORB feature detector and binary descriptor
|
||||
==========================================
|
||||
|
||||
This example demonstrates the ORB feature detection and binary description
|
||||
algorithm. It uses an oriented FAST detection method and the rotated BRIEF
|
||||
descriptors.
|
||||
|
||||
Unlike BRIEF, ORB is comparatively scale- and rotation-invariant while still
|
||||
employing the very efficient Hamming distance metric for matching. As such, it
|
||||
is preferred for real-time applications.
|
||||
|
||||
"""
|
||||
from skimage import data
|
||||
from skimage import transform as tf
|
||||
from skimage.feature import (match_descriptors, corner_harris,
|
||||
corner_peaks, ORB, plot_matches)
|
||||
from skimage.color import rgb2gray
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
img1 = rgb2gray(data.lena())
|
||||
img2 = tf.rotate(img1, 180)
|
||||
tform = tf.AffineTransform(scale=(1.3, 1.1), rotation=0.5,
|
||||
translation=(0, -200))
|
||||
img3 = tf.warp(img1, tform)
|
||||
|
||||
descriptor_extractor = ORB(n_keypoints=200)
|
||||
|
||||
descriptor_extractor.detect_and_extract(img1)
|
||||
keypoints1 = descriptor_extractor.keypoints
|
||||
descriptors1 = descriptor_extractor.descriptors
|
||||
|
||||
descriptor_extractor.detect_and_extract(img2)
|
||||
keypoints2 = descriptor_extractor.keypoints
|
||||
descriptors2 = descriptor_extractor.descriptors
|
||||
|
||||
descriptor_extractor.detect_and_extract(img3)
|
||||
keypoints3 = descriptor_extractor.keypoints
|
||||
descriptors3 = descriptor_extractor.descriptors
|
||||
|
||||
matches12 = match_descriptors(descriptors1, descriptors2, cross_check=True)
|
||||
matches13 = match_descriptors(descriptors1, descriptors3, cross_check=True)
|
||||
|
||||
fig, ax = plt.subplots(nrows=2, ncols=1)
|
||||
|
||||
plt.gray()
|
||||
|
||||
plot_matches(ax[0], img1, img2, keypoints1, keypoints2, matches12)
|
||||
ax[0].axis('off')
|
||||
|
||||
plot_matches(ax[1], img1, img3, keypoints1, keypoints3, matches13)
|
||||
ax[1].axis('off')
|
||||
|
||||
plt.show()
|
||||
+14
-13
@@ -14,30 +14,31 @@ the intra-class variance.
|
||||
.. [1] http://en.wikipedia.org/wiki/Otsu's_method
|
||||
|
||||
"""
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage.data import camera
|
||||
from skimage.filter import threshold_otsu
|
||||
|
||||
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
|
||||
image = camera()
|
||||
thresh = threshold_otsu(image)
|
||||
binary = image > thresh
|
||||
|
||||
plt.figure(figsize=(8, 2.5))
|
||||
plt.subplot(1, 3, 1)
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
plt.title('Original')
|
||||
plt.axis('off')
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 2.5))
|
||||
ax1.imshow(image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Original')
|
||||
ax1.axis('off')
|
||||
|
||||
plt.subplot(1, 3, 2, aspect='equal')
|
||||
plt.hist(image)
|
||||
plt.title('Histogram')
|
||||
plt.axvline(thresh, color='r')
|
||||
ax2.hist(image)
|
||||
ax2.set_title('Histogram')
|
||||
ax2.axvline(thresh, color='r')
|
||||
|
||||
plt.subplot(1, 3, 3)
|
||||
plt.imshow(binary, cmap=plt.cm.gray)
|
||||
plt.title('Thresholded')
|
||||
plt.axis('off')
|
||||
ax3.imshow(binary, cmap=plt.cm.gray)
|
||||
ax3.set_title('Thresholded')
|
||||
ax3.axis('off')
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -25,25 +25,23 @@ image_max = ndimage.maximum_filter(im, size=20, mode='constant')
|
||||
coordinates = peak_local_max(im, min_distance=20)
|
||||
|
||||
# display results
|
||||
plt.figure(figsize=(8, 3))
|
||||
plt.subplot(131)
|
||||
plt.imshow(im, cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
plt.title('Original')
|
||||
fig, ax = plt.subplots(1, 3, figsize=(8, 3))
|
||||
ax1, ax2, ax3 = ax.ravel()
|
||||
ax1.imshow(im, cmap=plt.cm.gray)
|
||||
ax1.axis('off')
|
||||
ax1.set_title('Original')
|
||||
|
||||
plt.subplot(132)
|
||||
plt.imshow(image_max, cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
plt.title('Maximum filter')
|
||||
ax2.imshow(image_max, cmap=plt.cm.gray)
|
||||
ax2.axis('off')
|
||||
ax2.set_title('Maximum filter')
|
||||
|
||||
plt.subplot(133)
|
||||
plt.imshow(im, cmap=plt.cm.gray)
|
||||
plt.autoscale(False)
|
||||
plt.plot([p[1] for p in coordinates], [p[0] for p in coordinates], 'r.')
|
||||
plt.axis('off')
|
||||
plt.title('Peak local max')
|
||||
ax3.imshow(im, cmap=plt.cm.gray)
|
||||
ax3.autoscale(False)
|
||||
ax3.plot(coordinates[:, 1], coordinates[:, 0], 'r.')
|
||||
ax3.axis('off')
|
||||
ax3.set_title('Peak local max')
|
||||
|
||||
plt.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9,
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9,
|
||||
bottom=0.02, left=0.02, right=0.98)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
"""
|
||||
================
|
||||
Phase Unwrapping
|
||||
================
|
||||
|
||||
Some signals can only be observed modulo 2*pi, and this can also apply to
|
||||
two- and three dimensional images. In these cases phase unwrapping is
|
||||
needed to recover the underlying, unwrapped signal. In this example we will
|
||||
demonstrate an algorithm [1]_ implemented in ``skimage`` at work for such a
|
||||
problem. One-, two- and three dimensional images can all be unwrapped using
|
||||
skimage. Here we will demonstrate phase unwrapping in the two dimensional case.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
from skimage import data, img_as_float, color, exposure
|
||||
from skimage.restoration import unwrap_phase
|
||||
|
||||
|
||||
# Load an image as a floating-point grayscale
|
||||
image = color.rgb2gray(img_as_float(data.chelsea()))
|
||||
# Scale the image to [0, 4*pi]
|
||||
image = exposure.rescale_intensity(image, out_range=(0, 4 * np.pi))
|
||||
# Create a phase-wrapped image in the interval [-pi, pi)
|
||||
image_wrapped = np.angle(np.exp(1j * image))
|
||||
# Perform phase unwrapping
|
||||
image_unwrapped = unwrap_phase(image_wrapped)
|
||||
|
||||
fig, ax = plt.subplots(2, 2)
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
fig.colorbar(ax1.imshow(image, cmap='gray', vmin=0, vmax=4 * np.pi), ax=ax1)
|
||||
ax1.set_title('Original')
|
||||
|
||||
fig.colorbar(ax2.imshow(image_wrapped, cmap='gray', vmin=-np.pi, vmax=np.pi), ax=ax2)
|
||||
ax2.set_title('Wrapped phase')
|
||||
|
||||
fig.colorbar(ax3.imshow(image_unwrapped, cmap='gray'), ax=ax3)
|
||||
ax3.set_title('After phase unwrapping')
|
||||
|
||||
fig.colorbar(ax4.imshow(image_unwrapped - image, cmap='gray'), ax=ax4)
|
||||
ax4.set_title('Unwrapped minus original')
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
The unwrapping procedure accepts masked arrays, and can also optionally
|
||||
assume cyclic boundaries to connect edges of an image. In the example below,
|
||||
we study a simple phase ramp which has been split in two by masking
|
||||
a row of the image.
|
||||
"""
|
||||
|
||||
# Create a simple ramp
|
||||
image = np.ones((100, 100)) * np.linspace(0, 8 * np.pi, 100).reshape((-1, 1))
|
||||
# Mask the image to split it in two horizontally
|
||||
mask = np.zeros_like(image, dtype=np.bool)
|
||||
mask[image.shape[0] // 2, :] = True
|
||||
|
||||
image_wrapped = np.ma.array(np.angle(np.exp(1j * image)), mask=mask)
|
||||
# Unwrap image without wrap around
|
||||
image_unwrapped_no_wrap_around = unwrap_phase(image_wrapped,
|
||||
wrap_around=(False, False))
|
||||
# Unwrap with wrap around enabled for the 0th dimension
|
||||
image_unwrapped_wrap_around = unwrap_phase(image_wrapped,
|
||||
wrap_around=(True, False))
|
||||
|
||||
fig, ax = plt.subplots(2, 2)
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
|
||||
fig.colorbar(ax1.imshow(np.ma.array(image, mask=mask), cmap='jet'), ax=ax1)
|
||||
ax1.set_title('Original')
|
||||
|
||||
fig.colorbar(ax2.imshow(image_wrapped, cmap='jet', vmin=-np.pi, vmax=np.pi),
|
||||
ax=ax2)
|
||||
ax2.set_title('Wrapped phase')
|
||||
|
||||
fig.colorbar(ax3.imshow(image_unwrapped_no_wrap_around, cmap='jet'),
|
||||
ax=ax3)
|
||||
ax3.set_title('Unwrapped without wrap_around')
|
||||
|
||||
fig.colorbar(ax4.imshow(image_unwrapped_wrap_around, cmap='jet'), ax=ax4)
|
||||
ax4.set_title('Unwrapped with wrap_around')
|
||||
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
In the figures above, the masked row can be seen as a white line across
|
||||
the image. The difference between the two unwrapped images in the bottom row
|
||||
is clear: Without unwrapping (lower left), the regions above and below the
|
||||
masked boundary do not interact at all, resulting in an offset between the
|
||||
two regions of an arbitrary integer times two pi. We could just as well have
|
||||
unwrapped the regions as two separate images. With wrap around enabled for the
|
||||
vertical direction (lower rigth), the situation changes: Unwrapping paths are
|
||||
now allowed to pass from the bottom to the top of the image and vice versa, in
|
||||
effect providing a way to determine the offset between the two regions.
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
.. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor,
|
||||
and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping
|
||||
algorithm based on sorting by reliability following a noncontinuous
|
||||
path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002
|
||||
"""
|
||||
@@ -35,7 +35,8 @@ out_rows = image.shape[0] - 1.5 * 50
|
||||
out_cols = cols
|
||||
out = warp(image, tform, output_shape=(out_rows, out_cols))
|
||||
|
||||
plt.imshow(out)
|
||||
plt.plot(tform.inverse(src)[:, 0], tform.inverse(src)[:, 1], '.b')
|
||||
plt.axis((0, out_cols, out_rows, 0))
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(out)
|
||||
ax.plot(tform.inverse(src)[:, 0], tform.inverse(src)[:, 1], '.b')
|
||||
ax.axis((0, out_cols, out_rows, 0))
|
||||
plt.show()
|
||||
|
||||
@@ -30,5 +30,6 @@ for p in pyramid[1:]:
|
||||
composite_image[i_row:i_row + n_rows, cols:cols + n_cols] = p
|
||||
i_row += n_rows
|
||||
|
||||
plt.imshow(composite_image)
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(composite_image)
|
||||
plt.show()
|
||||
|
||||
@@ -60,22 +60,20 @@ from skimage.transform import radon, rescale
|
||||
image = imread(data_dir + "/phantom.png", as_grey=True)
|
||||
image = rescale(image, scale=0.4)
|
||||
|
||||
plt.figure(figsize=(8, 4.5))
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5))
|
||||
|
||||
plt.subplot(121)
|
||||
plt.title("Original")
|
||||
plt.imshow(image, cmap=plt.cm.Greys_r)
|
||||
ax1.set_title("Original")
|
||||
ax1.imshow(image, cmap=plt.cm.Greys_r)
|
||||
|
||||
theta = np.linspace(0., 180., max(image.shape), endpoint=True)
|
||||
sinogram = radon(image, theta=theta, circle=True)
|
||||
plt.subplot(122)
|
||||
plt.title("Radon transform\n(Sinogram)")
|
||||
plt.xlabel("Projection angle (deg)")
|
||||
plt.ylabel("Projection position (pixels)")
|
||||
plt.imshow(sinogram, cmap=plt.cm.Greys_r,
|
||||
ax2.set_title("Radon transform\n(Sinogram)")
|
||||
ax2.set_xlabel("Projection angle (deg)")
|
||||
ax2.set_ylabel("Projection position (pixels)")
|
||||
ax2.imshow(sinogram, cmap=plt.cm.Greys_r,
|
||||
extent=(0, 180, 0, sinogram.shape[0]), aspect='auto')
|
||||
|
||||
plt.subplots_adjust(hspace=0.4, wspace=0.5)
|
||||
fig.subplots_adjust(hspace=0.4, wspace=0.5)
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
@@ -103,13 +101,11 @@ error = reconstruction_fbp - image
|
||||
print('FBP rms reconstruction error: %.3g' % np.sqrt(np.mean(error**2)))
|
||||
|
||||
imkwargs = dict(vmin=-0.2, vmax=0.2)
|
||||
plt.figure(figsize=(8, 4.5))
|
||||
plt.subplot(121)
|
||||
plt.title("Reconstruction\nFiltered back projection")
|
||||
plt.imshow(reconstruction_fbp, cmap=plt.cm.Greys_r)
|
||||
plt.subplot(122)
|
||||
plt.title("Reconstruction error\nFiltered back projection")
|
||||
plt.imshow(reconstruction_fbp - image, cmap=plt.cm.Greys_r, **imkwargs)
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5))
|
||||
ax1.set_title("Reconstruction\nFiltered back projection")
|
||||
ax1.imshow(reconstruction_fbp, cmap=plt.cm.Greys_r)
|
||||
ax2.set_title("Reconstruction error\nFiltered back projection")
|
||||
ax2.imshow(reconstruction_fbp - image, cmap=plt.cm.Greys_r, **imkwargs)
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
@@ -156,14 +152,12 @@ error = reconstruction_sart - image
|
||||
print('SART (1 iteration) rms reconstruction error: %.3g'
|
||||
% np.sqrt(np.mean(error**2)))
|
||||
|
||||
plt.figure(figsize=(8, 8.5))
|
||||
|
||||
plt.subplot(221)
|
||||
plt.title("Reconstruction\nSART")
|
||||
plt.imshow(reconstruction_sart, cmap=plt.cm.Greys_r)
|
||||
plt.subplot(222)
|
||||
plt.title("Reconstruction error\nSART")
|
||||
plt.imshow(reconstruction_sart - image, cmap=plt.cm.Greys_r, **imkwargs)
|
||||
fig, ax = plt.subplots(2, 2, figsize=(8, 8.5))
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
ax1.set_title("Reconstruction\nSART")
|
||||
ax1.imshow(reconstruction_sart, cmap=plt.cm.Greys_r)
|
||||
ax2.set_title("Reconstruction error\nSART")
|
||||
ax2.imshow(reconstruction_sart - image, cmap=plt.cm.Greys_r, **imkwargs)
|
||||
|
||||
# Run a second iteration of SART by supplying the reconstruction
|
||||
# from the first iteration as an initial estimate
|
||||
@@ -173,12 +167,10 @@ error = reconstruction_sart2 - image
|
||||
print('SART (2 iterations) rms reconstruction error: %.3g'
|
||||
% np.sqrt(np.mean(error**2)))
|
||||
|
||||
plt.subplot(223)
|
||||
plt.title("Reconstruction\nSART, 2 iterations")
|
||||
plt.imshow(reconstruction_sart2, cmap=plt.cm.Greys_r)
|
||||
plt.subplot(224)
|
||||
plt.title("Reconstruction error\nSART, 2 iterations")
|
||||
plt.imshow(reconstruction_sart2 - image, cmap=plt.cm.Greys_r, **imkwargs)
|
||||
ax3.set_title("Reconstruction\nSART, 2 iterations")
|
||||
ax3.imshow(reconstruction_sart2, cmap=plt.cm.Greys_r)
|
||||
ax4.set_title("Reconstruction error\nSART, 2 iterations")
|
||||
ax4.imshow(reconstruction_sart2 - image, cmap=plt.cm.Greys_r, **imkwargs)
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
|
||||
@@ -58,20 +58,17 @@ markers[data > 1.3] = 2
|
||||
labels = random_walker(data, markers, beta=10, mode='bf')
|
||||
|
||||
# Plot results
|
||||
plt.figure(figsize=(8, 3.2))
|
||||
plt.subplot(131)
|
||||
plt.imshow(data, cmap='gray', interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('Noisy data')
|
||||
plt.subplot(132)
|
||||
plt.imshow(markers, cmap='hot', interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('Markers')
|
||||
plt.subplot(133)
|
||||
plt.imshow(labels, cmap='gray', interpolation='nearest')
|
||||
plt.axis('off')
|
||||
plt.title('Segmentation')
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 3.2))
|
||||
ax1.imshow(data, cmap='gray', interpolation='nearest')
|
||||
ax1.axis('off')
|
||||
ax1.set_title('Noisy data')
|
||||
ax2.imshow(markers, cmap='hot', interpolation='nearest')
|
||||
ax2.axis('off')
|
||||
ax2.set_title('Markers')
|
||||
ax3.imshow(labels, cmap='gray', interpolation='nearest')
|
||||
ax3.axis('off')
|
||||
ax3.set_title('Segmentation')
|
||||
|
||||
plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,
|
||||
right=1)
|
||||
plt.show()
|
||||
|
||||
@@ -45,11 +45,12 @@ line_x = np.arange(-250, 250)
|
||||
line_y = model.predict_y(line_x)
|
||||
line_y_robust = model_robust.predict_y(line_x)
|
||||
|
||||
plt.plot(data[inliers, 0], data[inliers, 1], '.b', alpha=0.6,
|
||||
label='Inlier data')
|
||||
plt.plot(data[outliers, 0], data[outliers, 1], '.r', alpha=0.6,
|
||||
label='Outlier data')
|
||||
plt.plot(line_x, line_y, '-k', label='Line model from all data')
|
||||
plt.plot(line_x, line_y_robust, '-b', label='Robust line model')
|
||||
plt.legend(loc='lower left')
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(data[inliers, 0], data[inliers, 1], '.b', alpha=0.6,
|
||||
label='Inlier data')
|
||||
ax.plot(data[outliers, 0], data[outliers, 1], '.r', alpha=0.6,
|
||||
label='Outlier data')
|
||||
ax.plot(line_x, line_y, '-k', label='Line model from all data')
|
||||
ax.plot(line_x, line_y_robust, '-b', label='Robust line model')
|
||||
ax.legend(loc='lower left')
|
||||
plt.show()
|
||||
|
||||
@@ -50,7 +50,7 @@ ax3.imshow(image - dilated)
|
||||
ax3.set_title('image - dilated')
|
||||
ax3.axis('off')
|
||||
|
||||
plt.tight_layout()
|
||||
fig.tight_layout()
|
||||
|
||||
"""
|
||||
|
||||
@@ -98,7 +98,7 @@ ax3.axhline(yslice, color='r', alpha=0.4)
|
||||
ax3.set_title('image - dilated')
|
||||
ax3.axis('off')
|
||||
|
||||
plt.tight_layout()
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
|
||||
@@ -26,7 +26,8 @@ image = rotate(image, angle=15, order=0)
|
||||
label_img = label(image)
|
||||
regions = regionprops(label_img)
|
||||
|
||||
plt.imshow(image)
|
||||
fig, ax = plt.subplots()
|
||||
ax.imshow(image, cmap=plt.cm.gray)
|
||||
|
||||
for props in regions:
|
||||
y0, x0 = props.centroid
|
||||
@@ -36,15 +37,14 @@ for props in regions:
|
||||
x2 = x0 - math.sin(orientation) * 0.5 * props.minor_axis_length
|
||||
y2 = y0 - math.cos(orientation) * 0.5 * props.minor_axis_length
|
||||
|
||||
plt.plot((x0, x1), (y0, y1), '-r', linewidth=2.5)
|
||||
plt.plot((x0, x2), (y0, y2), '-r', linewidth=2.5)
|
||||
plt.plot(x0, y0, '.g', markersize=15)
|
||||
ax.plot((x0, x1), (y0, y1), '-r', linewidth=2.5)
|
||||
ax.plot((x0, x2), (y0, y2), '-r', linewidth=2.5)
|
||||
ax.plot(x0, y0, '.g', markersize=15)
|
||||
|
||||
minr, minc, maxr, maxc = props.bbox
|
||||
bx = (minc, maxc, maxc, minc, minc)
|
||||
by = (minr, minr, maxr, maxr, minr)
|
||||
plt.plot(bx, by, '-b', linewidth=2.5)
|
||||
ax.plot(bx, by, '-b', linewidth=2.5)
|
||||
|
||||
plt.gray()
|
||||
plt.axis((0, 600, 600, 0))
|
||||
ax.axis((0, 600, 600, 0))
|
||||
plt.show()
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
=====================
|
||||
Deconvolution of Lena
|
||||
=====================
|
||||
|
||||
In this example, we deconvolve a noisy version of Lena using Wiener
|
||||
and unsupervised Wiener algorithms. This algorithms are based on
|
||||
linear models that can't restore sharp edge as much as non-linear
|
||||
methods (like TV restoration) but are much faster.
|
||||
|
||||
Wiener filter
|
||||
-------------
|
||||
The inverse filter based on the PSF (Point Spread Function),
|
||||
the prior regularisation (penalisation of high frequency) and the
|
||||
tradeoff between the data and prior adequacy. The regularization
|
||||
parameter must be hand tuned.
|
||||
|
||||
Unsupervised Wiener
|
||||
-------------------
|
||||
This algorithm has a self-tuned regularisation parameters based on
|
||||
data learning. This is not common and based on the following
|
||||
publication. The algorithm is based on a iterative Gibbs sampler that
|
||||
draw alternatively samples of posterior conditionnal law of the image,
|
||||
the noise power and the image frequency power.
|
||||
|
||||
.. [1] François Orieux, Jean-François Giovannelli, and Thomas
|
||||
Rodet, "Bayesian estimation of regularization and point
|
||||
spread function parameters for Wiener-Hunt deconvolution",
|
||||
J. Opt. Soc. Am. A 27, 1593-1607 (2010)
|
||||
"""
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import color, data, restoration
|
||||
|
||||
lena = color.rgb2gray(data.lena())
|
||||
from scipy.signal import convolve2d as conv2
|
||||
psf = np.ones((5, 5)) / 25
|
||||
lena = conv2(lena, psf, 'same')
|
||||
lena += 0.1 * lena.std() * np.random.standard_normal(lena.shape)
|
||||
|
||||
deconvolved, _ = restoration.unsupervised_wiener(lena, psf)
|
||||
|
||||
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 5))
|
||||
|
||||
plt.gray()
|
||||
|
||||
ax[0].imshow(lena, vmin=deconvolved.min(), vmax=deconvolved.max())
|
||||
ax[0].axis('off')
|
||||
ax[0].set_title('Data')
|
||||
|
||||
ax[1].imshow(deconvolved)
|
||||
ax[1].axis('off')
|
||||
ax[1].set_title('Self tuned restoration')
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.2,
|
||||
top=0.9, bottom=0.05, left=0, right=1)
|
||||
|
||||
plt.show()
|
||||
@@ -51,7 +51,7 @@ and image location and is therefore closely related to quickshift. As the
|
||||
clustering method is simpler, it is very efficient. It is essential for this
|
||||
algorithm to work in Lab color space to obtain good results. The algorithm
|
||||
quickly gained momentum and is now widely used. See [3] for details. The
|
||||
``ratio`` parameter trades off color-similarity and proximity, as in the case
|
||||
``compactness`` parameter trades off color-similarity and proximity, as in the case
|
||||
of Quickshift, while ``n_segments`` chooses the number of centers for kmeans.
|
||||
|
||||
.. [3] Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi,
|
||||
@@ -70,7 +70,7 @@ from skimage.util import img_as_float
|
||||
|
||||
img = img_as_float(lena()[::2, ::2])
|
||||
segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
|
||||
segments_slic = slic(img, ratio=10, n_segments=250, sigma=1)
|
||||
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1)
|
||||
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
|
||||
|
||||
print("Felzenszwalb's number of segments: %d" % len(np.unique(segments_fz)))
|
||||
@@ -79,7 +79,7 @@ print("Quickshift number of segments: %d" % len(np.unique(segments_quick)))
|
||||
|
||||
fig, ax = plt.subplots(1, 3)
|
||||
fig.set_size_inches(8, 3, forward=True)
|
||||
plt.subplots_adjust(0.05, 0.05, 0.95, 0.95, 0.05, 0.05)
|
||||
fig.subplots_adjust(0.05, 0.05, 0.95, 0.95, 0.05, 0.05)
|
||||
|
||||
ax[0].imshow(mark_boundaries(img, segments_fz))
|
||||
ax[0].set_title("Felzenszwalbs's method")
|
||||
|
||||
+11
-12
@@ -4,11 +4,17 @@ Shapes
|
||||
======
|
||||
|
||||
This example shows how to draw several different shapes:
|
||||
* line
|
||||
* Bezier curve
|
||||
* polygon
|
||||
* circle
|
||||
* ellipse
|
||||
|
||||
- line
|
||||
- Bezier curve
|
||||
- polygon
|
||||
- circle
|
||||
- ellipse
|
||||
|
||||
Anti-aliased drawing for:
|
||||
|
||||
- line
|
||||
- circle
|
||||
|
||||
"""
|
||||
import math
|
||||
@@ -69,13 +75,6 @@ ax1.imshow(img)
|
||||
ax1.set_title('No anti-aliasing')
|
||||
ax1.axis('off')
|
||||
|
||||
"""
|
||||
|
||||
Anti-aliased drawing for:
|
||||
* line
|
||||
* circle
|
||||
|
||||
"""
|
||||
|
||||
from skimage.draw import line_aa, circle_perimeter_aa
|
||||
|
||||
|
||||
@@ -47,19 +47,17 @@ image[circle2] = 0
|
||||
skeleton = skeletonize(image)
|
||||
|
||||
# display results
|
||||
plt.figure(figsize=(8, 4.5))
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5))
|
||||
|
||||
plt.subplot(121)
|
||||
plt.imshow(image, cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
plt.title('original', fontsize=20)
|
||||
ax1.imshow(image, cmap=plt.cm.gray)
|
||||
ax1.axis('off')
|
||||
ax1.set_title('original', fontsize=20)
|
||||
|
||||
plt.subplot(122)
|
||||
plt.imshow(skeleton, cmap=plt.cm.gray)
|
||||
plt.axis('off')
|
||||
plt.title('skeleton', fontsize=20)
|
||||
ax2.imshow(skeleton, cmap=plt.cm.gray)
|
||||
ax2.axis('off')
|
||||
ax2.set_title('skeleton', fontsize=20)
|
||||
|
||||
plt.subplots_adjust(wspace=0.02, hspace=0.02, top=0.98,
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.98,
|
||||
bottom=0.02, left=0.02, right=0.98)
|
||||
|
||||
plt.show()
|
||||
|
||||
@@ -22,12 +22,16 @@ but with very different mean structural similarity indices.
|
||||
|
||||
"""
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import data, img_as_float
|
||||
from skimage.measure import structural_similarity as ssim
|
||||
|
||||
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
|
||||
img = img_as_float(data.camera())
|
||||
rows, cols = img.shape
|
||||
|
||||
@@ -41,7 +45,7 @@ def mse(x, y):
|
||||
img_noise = img + noise
|
||||
img_const = img + abs(noise)
|
||||
|
||||
f, (ax0, ax1, ax2) = plt.subplots(1, 3)
|
||||
fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, figsize=(8, 4))
|
||||
|
||||
mse_none = mse(img, img)
|
||||
ssim_none = ssim(img, img, dynamic_range=img.max() - img.min())
|
||||
|
||||
@@ -74,7 +74,7 @@ from skimage.transform import swirl
|
||||
image = data.checkerboard()
|
||||
swirled = swirl(image, rotation=0, strength=10, radius=120, order=2)
|
||||
|
||||
f, (ax0, ax1) = plt.subplots(1, 2, figsize=(8, 3))
|
||||
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(8, 3))
|
||||
|
||||
ax0.imshow(image, cmap=plt.cm.gray, interpolation='none')
|
||||
ax0.axis('off')
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
"""
|
||||
=========================
|
||||
Tinting gray-scale images
|
||||
=========================
|
||||
|
||||
It can be useful to artificially tint an image with some color, either to
|
||||
highlight particular regions of an image or maybe just to liven up a grayscale
|
||||
image. This example demonstrates image-tinting by scaling RGB values and by
|
||||
adjusting colors in the HSV color-space.
|
||||
|
||||
In 2D, color images are often represented in RGB---3 layers of 2D arrays, where
|
||||
the 3 layers represent (R)ed, (G)reen and (B)lue channels of the image. The
|
||||
simplest way of getting a tinted image is to set each RGB channel to the
|
||||
grayscale image scaled by a different multiplier for each channel. For example,
|
||||
multiplying the green and blue channels by 0 leaves only the red channel and
|
||||
produces a bright red image. Similarly, zeroing-out the blue channel leaves
|
||||
only the red and green channels, which combine to form yellow.
|
||||
"""
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
from skimage import data
|
||||
from skimage import color
|
||||
from skimage import img_as_float
|
||||
|
||||
grayscale_image = img_as_float(data.camera()[::2, ::2])
|
||||
image = color.gray2rgb(grayscale_image)
|
||||
|
||||
red_multiplier = [1, 0, 0]
|
||||
yellow_multiplier = [1, 1, 0]
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
|
||||
ax1.imshow(red_multiplier * image)
|
||||
ax2.imshow(yellow_multiplier * image)
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
In many cases, dealing with RGB values may not be ideal. Because of that, there
|
||||
are many other `color spaces`_ in which you can represent a color image. One
|
||||
popular color space is called HSV_, which represents hue (~the color),
|
||||
saturation (~colorfulness), and value (~brightness). For example, a color
|
||||
(hue) might be green, but its saturation is how intense that green is---where
|
||||
olive is on the low end and neon on the high end.
|
||||
|
||||
In some implementations, the hue in HSV goes from 0 to 360, since hues wrap
|
||||
around in a circle. In scikit-image, however, hues are float values from 0 to
|
||||
1, so that hue, saturation, and value all share the same scale.
|
||||
|
||||
Below, we plot a linear gradient in the hue, with the saturation and value
|
||||
turned all the way up:
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
hue_gradient = np.linspace(0, 1)
|
||||
hsv = np.ones(shape=(1, len(hue_gradient), 3), dtype=float)
|
||||
hsv[:, :, 0] = hue_gradient
|
||||
|
||||
all_hues = color.hsv2rgb(hsv)
|
||||
|
||||
fig, ax = plt.subplots(figsize=(5, 2))
|
||||
# Set image extent so hues go from 0 to 1 and the image is a nice aspect ratio.
|
||||
ax.imshow(all_hues, extent=(0, 1, 0, 0.2))
|
||||
ax.set_axis_off()
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
Notice how the colors at the far left and far right are the same. That reflects
|
||||
the fact that the hues wrap around like the color wheel (see HSV_ for more
|
||||
info).
|
||||
|
||||
Now, let's create a little utility function to take an RGB image and:
|
||||
|
||||
1. Transform the RGB image to HSV
|
||||
2. Set the hue and saturation
|
||||
3. Transform the HSV image back to RGB
|
||||
|
||||
"""
|
||||
|
||||
def colorize(image, hue, saturation=1):
|
||||
""" Add color of the given hue to an RGB image.
|
||||
|
||||
By default, set the saturation to 1 so that the colors pop!
|
||||
"""
|
||||
hsv = color.rgb2hsv(image)
|
||||
hsv[:, :, 1] = saturation
|
||||
hsv[:, :, 0] = hue
|
||||
return color.hsv2rgb(hsv)
|
||||
|
||||
"""
|
||||
Notice that we need to bump up the saturation; images with zero saturation are
|
||||
grayscale, so we need to a non-zero value to actually see the color we've set.
|
||||
|
||||
Using the function above, we plot six images with a linear gradient in the hue
|
||||
and a non-zero saturation:
|
||||
"""
|
||||
|
||||
hue_rotations = np.linspace(0, 1, 6)
|
||||
|
||||
fig, axes = plt.subplots(nrows=2, ncols=3)
|
||||
|
||||
for ax, hue in zip(axes.flat, hue_rotations):
|
||||
# Turn down the saturation to give it that vintage look.
|
||||
tinted_image = colorize(image, hue, saturation=0.3)
|
||||
ax.imshow(tinted_image, vmin=0, vmax=1)
|
||||
ax.set_axis_off()
|
||||
fig.tight_layout()
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
You can combine this tinting effect with numpy slicing and fancy-indexing to
|
||||
selectively tint your images. In the example below, we set the hue of some
|
||||
rectangles using slicing and scale the RGB values of some pixels found by
|
||||
thresholding. In practice, you might want to define a region for tinting based
|
||||
on segmentation results or blob detection methods.
|
||||
"""
|
||||
|
||||
from skimage.filter import rank
|
||||
|
||||
# Square regions defined as slices over the first two dimensions.
|
||||
top_left = (slice(100),) * 2
|
||||
bottom_right = (slice(-100, None),) * 2
|
||||
|
||||
sliced_image = image.copy()
|
||||
sliced_image[top_left] = colorize(image[top_left], 0.82, saturation=0.5)
|
||||
sliced_image[bottom_right] = colorize(image[bottom_right], 0.5, saturation=0.5)
|
||||
|
||||
# Create a mask selecting regions with interesting texture.
|
||||
noisy = rank.entropy(grayscale_image, np.ones((9, 9)))
|
||||
textured_regions = noisy > 4
|
||||
# Note that using `colorize` here is a bit more difficult, since `rgb2hsv`
|
||||
# expects an RGB image (height x width x channel), but fancy-indexing returns
|
||||
# a set of RGB pixels (# pixels x channel).
|
||||
masked_image = image.copy()
|
||||
masked_image[textured_regions, :] *= red_multiplier
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
|
||||
ax1.imshow(sliced_image)
|
||||
ax2.imshow(masked_image)
|
||||
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
For coloring multiple regions, you may also be interested in
|
||||
`skimage.color.label2rgb <http://scikit-image.org/docs/0.9.x/api/skimage.color.html#label2rgb>`_.
|
||||
|
||||
.. _color spaces:
|
||||
http://en.wikipedia.org/wiki/List_of_color_spaces_and_their_uses
|
||||
.. _HSV: http://en.wikipedia.org/wiki/HSL_and_HSV
|
||||
"""
|
||||
@@ -60,5 +60,5 @@ ax2.imshow(max_view, cmap=cm.Greys_r)
|
||||
ax3.set_title("Block view with\n local median pooling")
|
||||
ax3.imshow(median_view, cmap=cm.Greys_r)
|
||||
|
||||
plt.subplots_adjust(hspace=0.4, wspace=0.4)
|
||||
fig.subplots_adjust(hspace=0.4, wspace=0.4)
|
||||
plt.show()
|
||||
|
||||
@@ -61,6 +61,6 @@ ax2.set_title('Separated objects')
|
||||
for ax in axes:
|
||||
ax.axis('off')
|
||||
|
||||
plt.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,
|
||||
right=1)
|
||||
plt.show()
|
||||
|
||||
@@ -9,7 +9,6 @@ import pydoc
|
||||
from StringIO import StringIO
|
||||
from warnings import warn
|
||||
|
||||
|
||||
class Reader(object):
|
||||
"""A line-based string reader.
|
||||
|
||||
@@ -233,7 +232,8 @@ class NumpyDocString(object):
|
||||
current_func = None
|
||||
if ',' in line:
|
||||
for func in line.split(','):
|
||||
push_item(func, [])
|
||||
if func.strip():
|
||||
push_item(func, [])
|
||||
elif line.strip():
|
||||
current_func = line
|
||||
elif current_func is not None:
|
||||
@@ -284,8 +284,8 @@ class NumpyDocString(object):
|
||||
for (section,content) in self._read_sections():
|
||||
if not section.startswith('..'):
|
||||
section = ' '.join([s.capitalize() for s in section.split(' ')])
|
||||
if section in ('Parameters', 'Attributes', 'Methods',
|
||||
'Returns', 'Raises', 'Warns'):
|
||||
if section in ('Parameters', 'Returns', 'Raises', 'Warns',
|
||||
'Other Parameters', 'Attributes', 'Methods'):
|
||||
self[section] = self._parse_param_list(content)
|
||||
elif section.startswith('.. index::'):
|
||||
self['index'] = self._parse_index(section, content)
|
||||
@@ -370,7 +370,7 @@ class NumpyDocString(object):
|
||||
idx = self['index']
|
||||
out = []
|
||||
out += ['.. index:: %s' % idx.get('default','')]
|
||||
for section, references in idx.items():
|
||||
for section, references in idx.iteritems():
|
||||
if section == 'default':
|
||||
continue
|
||||
out += [' :%s: %s' % (section, ', '.join(references))]
|
||||
@@ -381,7 +381,8 @@ class NumpyDocString(object):
|
||||
out += self._str_signature()
|
||||
out += self._str_summary()
|
||||
out += self._str_extended_summary()
|
||||
for param_list in ('Parameters','Returns','Raises'):
|
||||
for param_list in ('Parameters', 'Returns', 'Other Parameters',
|
||||
'Raises', 'Warns'):
|
||||
out += self._str_param_list(param_list)
|
||||
out += self._str_section('Warnings')
|
||||
out += self._str_see_also(func_role)
|
||||
|
||||
@@ -2,7 +2,6 @@ import re, inspect, textwrap, pydoc
|
||||
import sphinx
|
||||
from docscrape import NumpyDocString, FunctionDoc, ClassDoc
|
||||
|
||||
|
||||
class SphinxDocString(NumpyDocString):
|
||||
def __init__(self, docstring, config={}):
|
||||
self.use_plots = config.get('use_plots', False)
|
||||
@@ -128,7 +127,7 @@ class SphinxDocString(NumpyDocString):
|
||||
return out
|
||||
|
||||
out += ['.. index:: %s' % idx.get('default','')]
|
||||
for section, references in idx.items():
|
||||
for section, references in idx.iteritems():
|
||||
if section == 'default':
|
||||
continue
|
||||
elif section == 'refguide':
|
||||
@@ -179,7 +178,8 @@ class SphinxDocString(NumpyDocString):
|
||||
out += self._str_index() + ['']
|
||||
out += self._str_summary()
|
||||
out += self._str_extended_summary()
|
||||
for param_list in ('Parameters', 'Returns', 'Raises'):
|
||||
for param_list in ('Parameters', 'Returns', 'Other Parameters',
|
||||
'Raises', 'Warns'):
|
||||
out += self._str_param_list(param_list)
|
||||
out += self._str_warnings()
|
||||
out += self._str_see_also(func_role)
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
__all__ = ['python_to_notebook', 'Notebook']
|
||||
|
||||
import json
|
||||
import copy
|
||||
import warnings
|
||||
|
||||
|
||||
# Skeleton notebook in JSON format
|
||||
skeleton_nb = """{
|
||||
"metadata": {
|
||||
"name":""
|
||||
},
|
||||
"nbformat": 3,
|
||||
"nbformat_minor": 0,
|
||||
"worksheets": [
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"collapsed": false,
|
||||
"input": [
|
||||
"%matplotlib inline"
|
||||
],
|
||||
"language": "python",
|
||||
"metadata": {},
|
||||
"outputs": []
|
||||
}
|
||||
],
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}"""
|
||||
|
||||
|
||||
class Notebook(object):
|
||||
"""
|
||||
Notebook object for building an IPython notebook cell-by-cell.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# cell type code
|
||||
self.cell_code = {
|
||||
'cell_type': 'code',
|
||||
'collapsed': False,
|
||||
'input': [
|
||||
'# Code Goes Here'
|
||||
],
|
||||
'language': 'python',
|
||||
'metadata': {},
|
||||
'outputs': []
|
||||
}
|
||||
|
||||
# cell type markdown
|
||||
self.cell_md = {
|
||||
'cell_type': 'markdown',
|
||||
'metadata': {},
|
||||
'source': [
|
||||
'Markdown Goes Here'
|
||||
]
|
||||
}
|
||||
|
||||
self.template = json.loads(skeleton_nb)
|
||||
self.cell_type = {'input': self.cell_code, 'source': self.cell_md}
|
||||
self.valuetype_to_celltype = {'code': 'input', 'markdown': 'source'}
|
||||
|
||||
def add_cell(self, value, cell_type='code'):
|
||||
"""Add a notebook cell.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
value : str
|
||||
Cell content.
|
||||
cell_type : {'code', 'markdown'}
|
||||
Type of content (default is 'code').
|
||||
|
||||
"""
|
||||
if cell_type in ['markdown', 'code']:
|
||||
key = self.valuetype_to_celltype[cell_type]
|
||||
cells = self.template['worksheets'][0]['cells']
|
||||
cells.append(copy.deepcopy(self.cell_type[key]))
|
||||
# assign value to the last cell
|
||||
cells[-1][key] = value
|
||||
else:
|
||||
warnings.warn('Ignoring unsupported cell type (%s)' % cell_type)
|
||||
|
||||
def json(self):
|
||||
"""Return a JSON representation of the notebook.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
JSON notebook.
|
||||
|
||||
"""
|
||||
return json.dumps(self.template, indent=2)
|
||||
|
||||
|
||||
def test_notebook_basic():
|
||||
nb = Notebook()
|
||||
assert(json.loads(nb.json()) == json.loads(skeleton_nb))
|
||||
|
||||
|
||||
def test_notebook_add():
|
||||
nb = Notebook()
|
||||
|
||||
str1 = 'hello world'
|
||||
str2 = 'f = lambda x: x * x'
|
||||
|
||||
nb.add_cell(str1, cell_type='markdown')
|
||||
nb.add_cell(str2, cell_type='code')
|
||||
|
||||
d = json.loads(nb.json())
|
||||
cells = d['worksheets'][0]['cells']
|
||||
values = [c['input'] if c['cell_type'] == 'code' else c['source']
|
||||
for c in cells]
|
||||
|
||||
assert values[1] == str1
|
||||
assert values[2] == str2
|
||||
|
||||
assert cells[1]['cell_type'] == 'markdown'
|
||||
assert cells[2]['cell_type'] == 'code'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import numpy.testing as npt
|
||||
npt.run_module_suite()
|
||||
+38
-2
@@ -80,6 +80,10 @@ from skimage import io
|
||||
from skimage import transform
|
||||
from skimage.util.dtype import dtype_range
|
||||
|
||||
from notebook import Notebook
|
||||
|
||||
from docutils.core import publish_parts
|
||||
|
||||
|
||||
LITERALINCLUDE = """
|
||||
.. literalinclude:: {src_name}
|
||||
@@ -94,6 +98,13 @@ CODE_LINK = """
|
||||
|
||||
"""
|
||||
|
||||
NOTEBOOK_LINK = """
|
||||
|
||||
**IPython Notebook:** :download:`download <{0}>`
|
||||
(generated using ``skimage`` |version|)
|
||||
|
||||
"""
|
||||
|
||||
TOCTREE_TEMPLATE = """
|
||||
.. toctree::
|
||||
:hidden:
|
||||
@@ -305,16 +316,20 @@ def write_example(src_name, src_dir, rst_dir, cfg):
|
||||
|
||||
image_dir = rst_dir.pjoin('images')
|
||||
thumb_dir = image_dir.pjoin('thumb')
|
||||
notebook_dir = rst_dir.pjoin('notebook')
|
||||
image_dir.makedirs()
|
||||
thumb_dir.makedirs()
|
||||
notebook_dir.makedirs()
|
||||
|
||||
base_image_name = os.path.splitext(src_name)[0]
|
||||
image_path = image_dir.pjoin(base_image_name + '_{0}.png')
|
||||
|
||||
basename, py_ext = os.path.splitext(src_name)
|
||||
rst_path = rst_dir.pjoin(basename + cfg.source_suffix)
|
||||
notebook_path = notebook_dir.pjoin(basename + '.ipynb')
|
||||
|
||||
if _plots_are_current(src_path, image_path) and rst_path.exists:
|
||||
if _plots_are_current(src_path, image_path) and rst_path.exists and \
|
||||
notebook_path.exists:
|
||||
return
|
||||
|
||||
blocks = split_code_and_text_blocks(example_file)
|
||||
@@ -341,8 +356,11 @@ def write_example(src_name, src_dir, rst_dir, cfg):
|
||||
example_rst += LITERALINCLUDE.format(**code_info)
|
||||
|
||||
example_rst += CODE_LINK.format(src_name)
|
||||
ipnotebook_name = src_name.replace('.py', '.ipynb')
|
||||
ipnotebook_name = './notebook/' + ipnotebook_name
|
||||
example_rst += NOTEBOOK_LINK.format(ipnotebook_name)
|
||||
|
||||
f = open(rst_path,'w')
|
||||
f = open(rst_path, 'w')
|
||||
f.write(example_rst)
|
||||
f.flush()
|
||||
|
||||
@@ -359,6 +377,24 @@ def write_example(src_name, src_dir, rst_dir, cfg):
|
||||
else:
|
||||
shutil.copy(cfg.plot2rst_default_thumb, thumb_path)
|
||||
|
||||
# Export example to IPython notebook
|
||||
nb = Notebook()
|
||||
|
||||
for (cell_type, _, content) in blocks:
|
||||
content = content.rstrip('\n')
|
||||
|
||||
if cell_type == 'code':
|
||||
nb.add_cell(content, cell_type='code')
|
||||
else:
|
||||
content = content.replace('"""', '')
|
||||
content = '\n'.join([line for line in content.split('\n') if
|
||||
not line.startswith('.. image')])
|
||||
html = publish_parts(content, writer_name='html')['html_body']
|
||||
nb.add_cell(html, cell_type='markdown')
|
||||
|
||||
with open(notebook_path, 'w') as f:
|
||||
f.write(nb.json())
|
||||
|
||||
|
||||
def save_thumbnail(image, thumb_path, shape):
|
||||
"""Save image as a thumbnail with the specified shape.
|
||||
|
||||
Regular → Executable
+7
-6
@@ -30,7 +30,7 @@ from subprocess import Popen, PIPE, CalledProcessError, check_call
|
||||
pages_dir = 'gh-pages'
|
||||
html_dir = 'build/html'
|
||||
pdf_dir = 'build/latex'
|
||||
pages_repo = 'git@github.com:scikit-image/docs.git'
|
||||
pages_repo = 'https://github.com/scikit-image/docs.git'
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Functions
|
||||
@@ -86,13 +86,14 @@ if __name__ == '__main__':
|
||||
if l.startswith('VERSION'):
|
||||
tag = l.split("'")[1]
|
||||
|
||||
# Rename to, e.g., 0.9.x
|
||||
tag = '.'.join(tag.split('.')[:-1] + ['x'])
|
||||
if "dev" in tag:
|
||||
tag = "dev"
|
||||
else:
|
||||
# Rename e.g. 0.9.0 to 0.9.x
|
||||
tag = '.'.join(tag.split('.')[:-1] + ['x'])
|
||||
|
||||
break
|
||||
|
||||
if "dev" in tag:
|
||||
tag = "dev"
|
||||
|
||||
startdir = os.getcwd()
|
||||
if not os.path.exists(pages_dir):
|
||||
@@ -124,7 +125,7 @@ if __name__ == '__main__':
|
||||
sh("touch .nojekyll")
|
||||
sh('git add .nojekyll')
|
||||
sh('git add index.html')
|
||||
sh('git add %s' % tag)
|
||||
sh('git add --all %s' % tag)
|
||||
sh2('git commit -m"Updated doc release: %s"' % tag)
|
||||
|
||||
print('Most recent commit:')
|
||||
|
||||
@@ -5,16 +5,16 @@ import string
|
||||
import shlex
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print "Usage: ./contributors.py tag-of-previous-release"
|
||||
print("Usage: ./contributors.py tag-of-previous-release")
|
||||
sys.exit(-1)
|
||||
|
||||
tag = sys.argv[1]
|
||||
|
||||
def call(cmd):
|
||||
return subprocess.check_output(shlex.split(cmd)).split('\n')
|
||||
return subprocess.check_output(shlex.split(cmd), universal_newlines=True).split('\n')
|
||||
|
||||
tag_date = call("git show --format='%%ci' %s" % tag)[0]
|
||||
print "Release %s was on %s" % (tag, tag_date)
|
||||
print("Release %s was on %s" % (tag, tag_date))
|
||||
|
||||
merges = call("git log --since='%s' --merges --format='>>>%%B' --reverse" % tag_date)
|
||||
merges = [m for m in merges if m.strip()]
|
||||
@@ -22,27 +22,26 @@ merges = '\n'.join(merges).split('>>>')
|
||||
merges = [m.split('\n')[:2] for m in merges]
|
||||
merges = [m for m in merges if len(m) == 2 and m[1].strip()]
|
||||
|
||||
print "\nIt contained the following %d merges:" % len(merges)
|
||||
print
|
||||
print("\nIt contained the following %d merges:\n" % len(merges))
|
||||
for (merge, message) in merges:
|
||||
if merge.startswith('Merge pull request #'):
|
||||
PR = ' (%s)' % merge.split()[3]
|
||||
else:
|
||||
PR = ''
|
||||
|
||||
print '- ' + message + PR
|
||||
print('- ' + message + PR)
|
||||
|
||||
|
||||
print "\nMade by the following committers [alphabetical by last name]:\n"
|
||||
print("\nMade by the following committers [alphabetical by last name]:\n")
|
||||
|
||||
authors = call("git log --since='%s' --format=%%aN" % tag_date)
|
||||
authors = [a.strip() for a in authors if a.strip()]
|
||||
|
||||
def key(author):
|
||||
author = [v for v in author.split() if v[0] in string.letters]
|
||||
author = [v for v in author.split() if v[0] in string.ascii_letters]
|
||||
return author[-1]
|
||||
|
||||
authors = sorted(set(authors), key=key)
|
||||
|
||||
for a in authors:
|
||||
print '-', a
|
||||
print('- ' + a)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var versions = ['dev', '0.9.x', '0.8.0', '0.7.0', '0.6', '0.5', '0.4', '0.3'];
|
||||
var versions = ['dev', '0.10.x', '0.9.x', '0.8.0', '0.7.0', '0.6', '0.5', '0.4', '0.3'];
|
||||
|
||||
function insert_version_links() {
|
||||
for (i = 0; i < versions.length; i++){
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
Version 0.10
|
||||
------------
|
||||
- Removed ``skimage.io.video`` functionality due to broken gstreamer bindings
|
||||
|
||||
Version 0.9
|
||||
-----------
|
||||
- No longer wrap ``imread`` output in an ``Image`` class
|
||||
@@ -20,4 +24,3 @@ Version 0.3
|
||||
- Remove ``as_grey``, ``dtype`` keyword from ImageCollection
|
||||
- Remove ``dtype`` from imread
|
||||
- Generalise ImageCollection to accept a load_func
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ Pre-built installation
|
||||
<http://www.lfd.uci.edu/~gohlke/pythonlibs/#scikits.image>`__
|
||||
are kindly provided by Christoph Gohlke.
|
||||
|
||||
The latest stable release is also included as part of the `Enthought Python
|
||||
Distribution (EPD) <http://enthought.com/products/epd.php>`__, `Python(x,y)
|
||||
<http://code.google.com/p/pythonxy/wiki/Welcome>`__ and
|
||||
The latest stable release is also included as part of
|
||||
`Enthought Canopy <https://www.enthought.com/products/canopy/>`__,
|
||||
`Python(x,y) <http://code.google.com/p/pythonxy/wiki/Welcome>`__ and
|
||||
`Anaconda <https://store.continuum.io/cshop/anaconda/>`__.
|
||||
|
||||
On Debian and Ubuntu, a Debian package ``python-skimage`` can be found in
|
||||
|
||||
@@ -134,7 +134,11 @@ dtype range::
|
||||
|
||||
Here, the ``in_range`` argument is set to the maximum range for a 10-bit image.
|
||||
By default, ``rescale_intensity`` stretches the values of ``in_range`` to match
|
||||
the range of the dtype.
|
||||
the range of the dtype. ``rescale_intensity`` also accepts strings as inputs
|
||||
to ``in_range`` and ``out_range``, so the example above could also be written
|
||||
as::
|
||||
|
||||
>>> image = exposure.rescale_intensity(img10bit, in_range='uint10')
|
||||
|
||||
|
||||
Note about negative values
|
||||
|
||||
@@ -24,26 +24,37 @@ alternatively, ``skimage.io.imshow`` which adds support for multiple
|
||||
io-plugins) to display images. The advantage of ``ImageViewer`` is that you can
|
||||
easily add plugins for manipulating images. Currently, only a few plugins are
|
||||
implemented, but it is easy to write your own. Before going into the details,
|
||||
let's see an example of how a plugin is added to the viewer:
|
||||
let's see an example of how a pre-defined plugin is added to the viewer:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from skimage.viewer.plugins import Canny
|
||||
from skimage.viewer.plugins.lineprofile import LineProfile
|
||||
|
||||
viewer = ImageViewer(image)
|
||||
viewer += Canny(view)
|
||||
viewer.show()
|
||||
viewer += LineProfile(viewer)
|
||||
overlay, data = viewer.show()[0]
|
||||
|
||||
At the moment, there aren't very many plugins pre-defined, but there's a really
|
||||
simple interface for creating your own plugin. First, let's create a plugin to
|
||||
call the total-variation denoising function, ``tv_denoise``:
|
||||
The viewer's ``show()`` method returns a list of tuples, one for each attached
|
||||
plugin. Each tuple contains two elements: an overlay of the same shape as the
|
||||
input image, and a data field (which may be ``None``). A plugin class documents
|
||||
its return value in its ``output`` method.
|
||||
|
||||
In this example, only one plugin is attached, so the list returned by ``show``
|
||||
will have length 1. We extract the single tuple and bind its ``overlay`` and
|
||||
``data`` elements to individual variables. Here, ``overlay`` contains an image
|
||||
of the line drawn on the viewer, and ``data`` contains the 1-dimensional
|
||||
intensity profile along that line.
|
||||
|
||||
At the moment, there are not many plugins pre-defined, but there is a really
|
||||
simple interface for creating your own plugin. First, let us create a plugin to
|
||||
call the total-variation denoising function, ``denoise_tv_bregman``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from skimage.filter import tv_denoise
|
||||
from skimage.filter import denoise_tv_bregman
|
||||
from skimage.viewer.plugins.base import Plugin
|
||||
|
||||
denoise_plugin = Plugin(image_filter=tv_denoise)
|
||||
denoise_plugin = Plugin(image_filter=denoise_tv_bregman)
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -74,8 +85,10 @@ All that's left is to create an image viewer and add the plugin to that viewer.
|
||||
|
||||
viewer = ImageViewer(image)
|
||||
viewer += denoise_plugin
|
||||
viewer.show()
|
||||
denoised = viewer.show()[0][0]
|
||||
|
||||
Here, we access only the overlay returned by the plugin, which contains the
|
||||
filtered image for the last used setting of ``weight``.
|
||||
|
||||
.. image:: data/denoise_viewer_window.png
|
||||
.. image:: data/denoise_plugin_window.png
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
These files were obtained from
|
||||
|
||||
http://groups.google.com/group/sphinx-dev/browse_thread/thread/595ef2eff60084c5/
|
||||
https://www.mail-archive.com/sphinx-dev@googlegroups.com/msg02472.html
|
||||
|
||||
and were released under a BSD/MIT license by Fernando Perez, Matthew Brett and
|
||||
the PyMVPA guys.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
cython>=0.17
|
||||
matplotlib>=1.0
|
||||
numpy>=1.6
|
||||
six>=1.3.0
|
||||
|
||||
@@ -17,13 +17,18 @@ MAINTAINER_EMAIL = 'stefan@sun.ac.za'
|
||||
URL = 'http://scikit-image.org'
|
||||
LICENSE = 'Modified BSD'
|
||||
DOWNLOAD_URL = 'http://github.com/scikit-image/scikit-image'
|
||||
VERSION = '0.9.3'
|
||||
VERSION = '0.10.0'
|
||||
PYTHON_VERSION = (2, 5)
|
||||
DEPENDENCIES = {
|
||||
'numpy': (1, 6),
|
||||
'Cython': (0, 17),
|
||||
'six': (1, 3),
|
||||
}
|
||||
|
||||
# Only require Cython if we have a developer checkout
|
||||
if VERSION.endswith('dev'):
|
||||
DEPENDENCIES['Cython'] = (0, 17)
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
+46
-41
@@ -14,27 +14,34 @@ color
|
||||
data
|
||||
Test images and example data.
|
||||
draw
|
||||
Image drawing primitives (lines, text, etc.).
|
||||
Drawing primitives (lines, text, etc.) that operate on NumPy arrays.
|
||||
exposure
|
||||
Image intensity adjustment (e.g., histogram equalization).
|
||||
Image intensity adjustment, e.g., histogram equalization, etc.
|
||||
feature
|
||||
Feature detection (e.g. texture analysis, corners, etc.).
|
||||
Feature detection and extraction, e.g., texture analysis corners, etc.
|
||||
filter
|
||||
Sharpening, edge finding, denoising, etc.
|
||||
Sharpening, edge finding, rank filters, thresholding, etc.
|
||||
graph
|
||||
Graph-theoretic operations, e.g. dynamic programming (shortest paths).
|
||||
Graph-theoretic operations, e.g., shortest paths.
|
||||
io
|
||||
Reading, saving, and displaying images and video.
|
||||
measure
|
||||
Measurement of image properties, e.g., similarity and contours.
|
||||
morphology
|
||||
Morphological operations, e.g. opening or skeletonization.
|
||||
Morphological operations, e.g., opening or skeletonization.
|
||||
novice
|
||||
Simplified interface for teaching purposes.
|
||||
restoration
|
||||
Restoration algorithms, e.g., deconvolution algorithms, denoising, etc.
|
||||
segmentation
|
||||
Splitting an image into self-similar regions.
|
||||
Partitioning an image into multiple regions.
|
||||
transform
|
||||
Geometric and other transforms, e.g. rotation or the Radon transform.
|
||||
Geometric and other transforms, e.g., rotation or the Radon transform.
|
||||
util
|
||||
Generic utilities.
|
||||
viewer
|
||||
A simple graphical user interface for visualizing results and exploring
|
||||
parameters.
|
||||
|
||||
Utility Functions
|
||||
-----------------
|
||||
@@ -52,6 +59,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 +76,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 +137,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)
|
||||
@@ -137,30 +168,4 @@ class _FakeLog(object):
|
||||
pass
|
||||
|
||||
|
||||
@_deprecated()
|
||||
def get_log(name=None):
|
||||
"""Return a console logger.
|
||||
|
||||
Output may be sent to the logger using the `debug`, `info`, `warning`,
|
||||
`error` and `critical` methods.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name : str
|
||||
Name of the log.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] Logging facility for Python,
|
||||
http://docs.python.org/library/logging.html
|
||||
|
||||
"""
|
||||
if name is None:
|
||||
name = 'skimage'
|
||||
else:
|
||||
name = 'skimage.' + name
|
||||
|
||||
return _FakeLog(name)
|
||||
|
||||
|
||||
from .util.dtype import *
|
||||
|
||||
+3
-21
@@ -3,7 +3,6 @@ import os
|
||||
import hashlib
|
||||
import subprocess
|
||||
|
||||
|
||||
# WindowsError is not defined on unix systems
|
||||
try:
|
||||
WindowsError
|
||||
@@ -26,7 +25,7 @@ def cython(pyx_files, working_path=''):
|
||||
return
|
||||
|
||||
try:
|
||||
import Cython
|
||||
from Cython.Build import cythonize
|
||||
except ImportError:
|
||||
# If cython is not found, we do nothing -- the build will make use of
|
||||
# the distributed .c files
|
||||
@@ -39,24 +38,7 @@ def cython(pyx_files, working_path=''):
|
||||
if not _changed(pyxfile):
|
||||
continue
|
||||
|
||||
c_file = pyxfile[:-4] + '.c'
|
||||
|
||||
# run cython compiler
|
||||
cmd = 'cython -o %s %s' % (c_file, pyxfile)
|
||||
print(cmd)
|
||||
|
||||
try:
|
||||
subprocess.call(['cython', '-o', c_file, pyxfile])
|
||||
except WindowsError:
|
||||
# On Windows cython.exe may be missing if Cython was installed
|
||||
# via distutils. Run the cython.py script instead.
|
||||
subprocess.call(
|
||||
[sys.executable,
|
||||
os.path.join(os.path.dirname(sys.executable),
|
||||
'Scripts', 'cython.py'),
|
||||
'-o', c_file, pyxfile],
|
||||
shell=True)
|
||||
|
||||
cythonize(pyxfile)
|
||||
|
||||
def _md5sum(f):
|
||||
m = hashlib.new('md5')
|
||||
@@ -86,4 +68,4 @@ def _changed(filename):
|
||||
with open(filename_cache, 'wb') as cf:
|
||||
cf.write(md5_new.encode('utf-8'))
|
||||
|
||||
return md5_cached != md5_new
|
||||
return md5_cached != md5_new.encode('utf-8')
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
__all__ = ['all_warnings']
|
||||
|
||||
from contextlib import contextmanager
|
||||
import sys
|
||||
import warnings
|
||||
import inspect
|
||||
|
||||
|
||||
@contextmanager
|
||||
def all_warnings():
|
||||
"""
|
||||
Context for use in testing to ensure that all warnings are raised.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import warnings
|
||||
>>> def foo():
|
||||
... warnings.warn(RuntimeWarning("bar"))
|
||||
|
||||
We raise the warning once, while the warning filter is set to "once".
|
||||
Hereafter, the warning is invisible, even with custom filters:
|
||||
|
||||
>>> with warnings.catch_warnings():
|
||||
... warnings.simplefilter('once')
|
||||
... foo()
|
||||
|
||||
We can now run ``foo()`` without a warning being raised:
|
||||
|
||||
>>> from numpy.testing import assert_warns
|
||||
>>> foo()
|
||||
|
||||
To catch the warning, we call in the help of ``all_warnings``:
|
||||
|
||||
>>> with all_warnings():
|
||||
... assert_warns(RuntimeWarning, foo)
|
||||
"""
|
||||
|
||||
# Whenever a warning is triggered, Python adds a __warningregistry__
|
||||
# member to the *calling* module. The exercize here is to find
|
||||
# and eradicate all those breadcrumbs that were left lying around.
|
||||
#
|
||||
# We proceed by first searching all parent calling frames and explicitly
|
||||
# clearing their warning registries (necessary for the doctests above to
|
||||
# pass). Then, we search for all submodules of skimage and clear theirs
|
||||
# as well (necessary for the skimage test suite to pass).
|
||||
|
||||
frame = inspect.currentframe()
|
||||
if frame:
|
||||
for f in inspect.getouterframes(frame):
|
||||
f[0].f_locals['__warningregistry__'] = {}
|
||||
del frame
|
||||
|
||||
for mod_name, mod in list(sys.modules.items()):
|
||||
if 'six.moves' in mod_name:
|
||||
continue
|
||||
try:
|
||||
mod.__warningregistry__.clear()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
yield w
|
||||
@@ -1,27 +1,333 @@
|
||||
#cython: cdivision=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
from libc.math cimport ceil, floor
|
||||
|
||||
cdef double nearest_neighbour_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r,
|
||||
double c, char mode,
|
||||
double cval)
|
||||
|
||||
cdef double bilinear_interpolation(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
double r, double c, char mode,
|
||||
double cval)
|
||||
cdef inline Py_ssize_t round(double r):
|
||||
return <Py_ssize_t>((r + 0.5) if (r > 0.0) else (r - 0.5))
|
||||
|
||||
cdef double quadratic_interpolation(double x, double[3] f)
|
||||
cdef double biquadratic_interpolation(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
double r, double c, char mode,
|
||||
double cval)
|
||||
|
||||
cdef double cubic_interpolation(double x, double[4] f)
|
||||
cdef double bicubic_interpolation(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
double r, double c, char mode,
|
||||
double cval)
|
||||
cdef inline double nearest_neighbour_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r,
|
||||
double c, char mode,
|
||||
double cval):
|
||||
"""Nearest neighbour interpolation at a given position in the image.
|
||||
|
||||
cdef double get_pixel2d(double* image, Py_ssize_t rows, Py_ssize_t cols, Py_ssize_t r,
|
||||
Py_ssize_t c, char mode, double cval)
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
cdef double get_pixel3d(double* image, Py_ssize_t rows, Py_ssize_t cols, Py_ssize_t dims,
|
||||
Py_ssize_t r, Py_ssize_t c, Py_ssize_t d, char mode, double cval)
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
cdef Py_ssize_t coord_map(Py_ssize_t dim, Py_ssize_t coord, char mode)
|
||||
"""
|
||||
|
||||
return get_pixel2d(image, rows, cols, round(r), round(c), mode, cval)
|
||||
|
||||
|
||||
cdef inline double bilinear_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r, double c,
|
||||
char mode, double cval):
|
||||
"""Bilinear interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
cdef double dr, dc
|
||||
cdef Py_ssize_t minr, minc, maxr, maxc
|
||||
|
||||
minr = <Py_ssize_t>floor(r)
|
||||
minc = <Py_ssize_t>floor(c)
|
||||
maxr = <Py_ssize_t>ceil(r)
|
||||
maxc = <Py_ssize_t>ceil(c)
|
||||
dr = r - minr
|
||||
dc = c - minc
|
||||
top = (1 - dc) * get_pixel2d(image, rows, cols, minr, minc, mode, cval) \
|
||||
+ dc * get_pixel2d(image, rows, cols, minr, maxc, mode, cval)
|
||||
bottom = (1 - dc) * get_pixel2d(image, rows, cols, maxr, minc, mode, cval) \
|
||||
+ dc * get_pixel2d(image, rows, cols, maxr, maxc, mode, cval)
|
||||
return (1 - dr) * top + dr * bottom
|
||||
|
||||
|
||||
cdef inline double quadratic_interpolation(double x, double[3] f):
|
||||
"""Quadratic interpolation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : double
|
||||
Position in the interval [-1, 1].
|
||||
f : double[4]
|
||||
Function values at positions [-1, 0, 1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
return f[1] - 0.25 * (f[0] - f[2]) * x
|
||||
|
||||
|
||||
cdef inline double biquadratic_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r, double c,
|
||||
char mode, double cval):
|
||||
"""Biquadratic interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
cdef Py_ssize_t r0 = round(r)
|
||||
cdef Py_ssize_t c0 = round(c)
|
||||
if r < 0:
|
||||
r0 -= 1
|
||||
if c < 0:
|
||||
c0 -= 1
|
||||
# scale position to range [-1, 1]
|
||||
cdef double xr = (r - r0) - 1
|
||||
cdef double xc = (c - c0) - 1
|
||||
if r == r0:
|
||||
xr += 1
|
||||
if c == c0:
|
||||
xc += 1
|
||||
|
||||
cdef double fc[3]
|
||||
cdef double fr[3]
|
||||
|
||||
cdef Py_ssize_t pr, pc
|
||||
|
||||
# row-wise cubic interpolation
|
||||
for pr in range(r0, r0 + 3):
|
||||
for pc in range(c0, c0 + 3):
|
||||
fc[pc - c0] = get_pixel2d(image, rows, cols, pr, pc, mode, cval)
|
||||
fr[pr - r0] = quadratic_interpolation(xc, fc)
|
||||
|
||||
# cubic interpolation for interpolated values of each row
|
||||
return quadratic_interpolation(xr, fr)
|
||||
|
||||
|
||||
cdef inline double cubic_interpolation(double x, double[4] f):
|
||||
"""Cubic interpolation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : double
|
||||
Position in the interval [0, 1].
|
||||
f : double[4]
|
||||
Function values at positions [0, 1/3, 2/3, 1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
return \
|
||||
f[1] + 0.5 * x * \
|
||||
(f[2] - f[0] + x * \
|
||||
(2.0 * f[0] - 5.0 * f[1] + 4.0 * f[2] - f[3] + x * \
|
||||
(3.0 * (f[1] - f[2]) + f[3] - f[0])))
|
||||
|
||||
|
||||
cdef inline double bicubic_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r, double c,
|
||||
char mode, double cval):
|
||||
"""Bicubic interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
cdef Py_ssize_t r0 = <Py_ssize_t>r - 1
|
||||
cdef Py_ssize_t c0 = <Py_ssize_t>c - 1
|
||||
if r < 0:
|
||||
r0 -= 1
|
||||
if c < 0:
|
||||
c0 -= 1
|
||||
# scale position to range [0, 1]
|
||||
cdef double xr = (r - r0) / 3
|
||||
cdef double xc = (c - c0) / 3
|
||||
|
||||
cdef double fc[4]
|
||||
cdef double fr[4]
|
||||
|
||||
cdef Py_ssize_t pr, pc
|
||||
|
||||
# row-wise cubic interpolation
|
||||
for pr in range(r0, r0 + 4):
|
||||
for pc in range(c0, c0 + 4):
|
||||
fc[pc - c0] = get_pixel2d(image, rows, cols, pr, pc, mode, cval)
|
||||
fr[pr - r0] = cubic_interpolation(xc, fc)
|
||||
|
||||
# cubic interpolation for interpolated values of each row
|
||||
return cubic_interpolation(xr, fr)
|
||||
|
||||
|
||||
cdef inline double get_pixel2d(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
Py_ssize_t r, Py_ssize_t c, char mode, double cval):
|
||||
"""Get a pixel from the image, taking wrapping mode into consideration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : int
|
||||
Position at which to get the pixel.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Pixel value at given position.
|
||||
|
||||
"""
|
||||
if mode == 'C':
|
||||
if (r < 0) or (r > rows - 1) or (c < 0) or (c > cols - 1):
|
||||
return cval
|
||||
else:
|
||||
return image[r * cols + c]
|
||||
else:
|
||||
return image[coord_map(rows, r, mode) * cols + coord_map(cols, c, mode)]
|
||||
|
||||
|
||||
cdef inline double get_pixel3d(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
Py_ssize_t dims, Py_ssize_t r, Py_ssize_t c, Py_ssize_t d,
|
||||
char mode, double cval):
|
||||
"""Get a pixel from the image, taking wrapping mode into consideration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols, dims : int
|
||||
Shape of image.
|
||||
r, c, d : int
|
||||
Position at which to get the pixel.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Pixel value at given position.
|
||||
|
||||
"""
|
||||
if mode == 'C':
|
||||
if (r < 0) or (r > rows - 1) or (c < 0) or (c > cols - 1):
|
||||
return cval
|
||||
else:
|
||||
return image[r * cols * dims + c * dims + d]
|
||||
else:
|
||||
return image[coord_map(rows, r, mode) * cols * dims
|
||||
+ coord_map(cols, c, mode) * dims
|
||||
+ d]
|
||||
|
||||
|
||||
cdef inline Py_ssize_t coord_map(Py_ssize_t dim, Py_ssize_t coord, char mode):
|
||||
"""
|
||||
Wrap a coordinate, according to a given mode.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dim : int
|
||||
Maximum coordinate.
|
||||
coord : int
|
||||
Coord provided by user. May be < 0 or > dim.
|
||||
mode : {'W', 'R', 'N'}
|
||||
Whether to wrap or reflect the coordinate if it
|
||||
falls outside [0, dim).
|
||||
|
||||
"""
|
||||
dim = dim - 1
|
||||
if mode == 'R': # reflect
|
||||
if coord < 0:
|
||||
# How many times times does the coordinate wrap?
|
||||
if <Py_ssize_t>(-coord / dim) % 2 != 0:
|
||||
return dim - <Py_ssize_t>(-coord % dim)
|
||||
else:
|
||||
return <Py_ssize_t>(-coord % dim)
|
||||
elif coord > dim:
|
||||
if <Py_ssize_t>(coord / dim) % 2 != 0:
|
||||
return <Py_ssize_t>(dim - (coord % dim))
|
||||
else:
|
||||
return <Py_ssize_t>(coord % dim)
|
||||
elif mode == 'W': # wrap
|
||||
if coord < 0:
|
||||
return <Py_ssize_t>(dim - (-coord % dim))
|
||||
elif coord > dim:
|
||||
return <Py_ssize_t>(coord % dim)
|
||||
elif mode == 'N': # nearest
|
||||
if coord < 0:
|
||||
return 0
|
||||
elif coord > dim:
|
||||
return dim
|
||||
|
||||
return coord
|
||||
|
||||
@@ -1,331 +0,0 @@
|
||||
#cython: cdivision=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
from libc.math cimport ceil, floor
|
||||
|
||||
|
||||
cdef inline Py_ssize_t round(double r):
|
||||
return <Py_ssize_t>((r + 0.5) if (r > 0.0) else (r - 0.5))
|
||||
|
||||
|
||||
cdef inline double nearest_neighbour_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r,
|
||||
double c, char mode,
|
||||
double cval):
|
||||
"""Nearest neighbour interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
return get_pixel2d(image, rows, cols, round(r), round(c), mode, cval)
|
||||
|
||||
|
||||
cdef inline double bilinear_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r, double c,
|
||||
char mode, double cval):
|
||||
"""Bilinear interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
cdef double dr, dc
|
||||
cdef Py_ssize_t minr, minc, maxr, maxc
|
||||
|
||||
minr = <Py_ssize_t>floor(r)
|
||||
minc = <Py_ssize_t>floor(c)
|
||||
maxr = <Py_ssize_t>ceil(r)
|
||||
maxc = <Py_ssize_t>ceil(c)
|
||||
dr = r - minr
|
||||
dc = c - minc
|
||||
top = (1 - dc) * get_pixel2d(image, rows, cols, minr, minc, mode, cval) \
|
||||
+ dc * get_pixel2d(image, rows, cols, minr, maxc, mode, cval)
|
||||
bottom = (1 - dc) * get_pixel2d(image, rows, cols, maxr, minc, mode, cval) \
|
||||
+ dc * get_pixel2d(image, rows, cols, maxr, maxc, mode, cval)
|
||||
return (1 - dr) * top + dr * bottom
|
||||
|
||||
|
||||
cdef inline double quadratic_interpolation(double x, double[3] f):
|
||||
"""Quadratic interpolation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : double
|
||||
Position in the interval [-1, 1].
|
||||
f : double[4]
|
||||
Function values at positions [-1, 0, 1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
return f[1] - 0.25 * (f[0] - f[2]) * x
|
||||
|
||||
|
||||
cdef inline double biquadratic_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r, double c,
|
||||
char mode, double cval):
|
||||
"""Biquadratic interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
cdef Py_ssize_t r0 = round(r)
|
||||
cdef Py_ssize_t c0 = round(c)
|
||||
if r < 0:
|
||||
r0 -= 1
|
||||
if c < 0:
|
||||
c0 -= 1
|
||||
# scale position to range [-1, 1]
|
||||
cdef double xr = (r - r0) - 1
|
||||
cdef double xc = (c - c0) - 1
|
||||
if r == r0:
|
||||
xr += 1
|
||||
if c == c0:
|
||||
xc += 1
|
||||
|
||||
cdef double fc[3], fr[3]
|
||||
|
||||
cdef Py_ssize_t pr, pc
|
||||
|
||||
# row-wise cubic interpolation
|
||||
for pr in range(r0, r0 + 3):
|
||||
for pc in range(c0, c0 + 3):
|
||||
fc[pc - c0] = get_pixel2d(image, rows, cols, pr, pc, mode, cval)
|
||||
fr[pr - r0] = quadratic_interpolation(xc, fc)
|
||||
|
||||
# cubic interpolation for interpolated values of each row
|
||||
return quadratic_interpolation(xr, fr)
|
||||
|
||||
|
||||
cdef inline double cubic_interpolation(double x, double[4] f):
|
||||
"""Cubic interpolation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : double
|
||||
Position in the interval [0, 1].
|
||||
f : double[4]
|
||||
Function values at positions [0, 1/3, 2/3, 1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
return \
|
||||
f[1] + 0.5 * x * \
|
||||
(f[2] - f[0] + x * \
|
||||
(2.0 * f[0] - 5.0 * f[1] + 4.0 * f[2] - f[3] + x * \
|
||||
(3.0 * (f[1] - f[2]) + f[3] - f[0])))
|
||||
|
||||
|
||||
cdef inline double bicubic_interpolation(double* image, Py_ssize_t rows,
|
||||
Py_ssize_t cols, double r, double c,
|
||||
char mode, double cval):
|
||||
"""Bicubic interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
cdef Py_ssize_t r0 = <Py_ssize_t>r - 1
|
||||
cdef Py_ssize_t c0 = <Py_ssize_t>c - 1
|
||||
if r < 0:
|
||||
r0 -= 1
|
||||
if c < 0:
|
||||
c0 -= 1
|
||||
# scale position to range [0, 1]
|
||||
cdef double xr = (r - r0) / 3
|
||||
cdef double xc = (c - c0) / 3
|
||||
|
||||
cdef double fc[4], fr[4]
|
||||
|
||||
cdef Py_ssize_t pr, pc
|
||||
|
||||
# row-wise cubic interpolation
|
||||
for pr in range(r0, r0 + 4):
|
||||
for pc in range(c0, c0 + 4):
|
||||
fc[pc - c0] = get_pixel2d(image, rows, cols, pr, pc, mode, cval)
|
||||
fr[pr - r0] = cubic_interpolation(xc, fc)
|
||||
|
||||
# cubic interpolation for interpolated values of each row
|
||||
return cubic_interpolation(xr, fr)
|
||||
|
||||
|
||||
cdef inline double get_pixel2d(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
Py_ssize_t r, Py_ssize_t c, char mode, double cval):
|
||||
"""Get a pixel from the image, taking wrapping mode into consideration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : int
|
||||
Position at which to get the pixel.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Pixel value at given position.
|
||||
|
||||
"""
|
||||
if mode == 'C':
|
||||
if (r < 0) or (r > rows - 1) or (c < 0) or (c > cols - 1):
|
||||
return cval
|
||||
else:
|
||||
return image[r * cols + c]
|
||||
else:
|
||||
return image[coord_map(rows, r, mode) * cols + coord_map(cols, c, mode)]
|
||||
|
||||
|
||||
cdef inline double get_pixel3d(double* image, Py_ssize_t rows, Py_ssize_t cols,
|
||||
Py_ssize_t dims, Py_ssize_t r, Py_ssize_t c, Py_ssize_t d,
|
||||
char mode, double cval):
|
||||
"""Get a pixel from the image, taking wrapping mode into consideration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols, dims : int
|
||||
Shape of image.
|
||||
r, c, d : int
|
||||
Position at which to get the pixel.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Pixel value at given position.
|
||||
|
||||
"""
|
||||
if mode == 'C':
|
||||
if (r < 0) or (r > rows - 1) or (c < 0) or (c > cols - 1):
|
||||
return cval
|
||||
else:
|
||||
return image[r * cols * dims + c * dims + d]
|
||||
else:
|
||||
return image[coord_map(rows, r, mode) * cols * dims
|
||||
+ coord_map(cols, c, mode) * dims
|
||||
+ d]
|
||||
|
||||
|
||||
cdef inline Py_ssize_t coord_map(Py_ssize_t dim, Py_ssize_t coord, char mode):
|
||||
"""
|
||||
Wrap a coordinate, according to a given mode.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dim : int
|
||||
Maximum coordinate.
|
||||
coord : int
|
||||
Coord provided by user. May be < 0 or > dim.
|
||||
mode : {'W', 'R', 'N'}
|
||||
Whether to wrap or reflect the coordinate if it
|
||||
falls outside [0, dim).
|
||||
|
||||
"""
|
||||
dim = dim - 1
|
||||
if mode == 'R': # reflect
|
||||
if coord < 0:
|
||||
# How many times times does the coordinate wrap?
|
||||
if <Py_ssize_t>(-coord / dim) % 2 != 0:
|
||||
return dim - <Py_ssize_t>(-coord % dim)
|
||||
else:
|
||||
return <Py_ssize_t>(-coord % dim)
|
||||
elif coord > dim:
|
||||
if <Py_ssize_t>(coord / dim) % 2 != 0:
|
||||
return <Py_ssize_t>(dim - (coord % dim))
|
||||
else:
|
||||
return <Py_ssize_t>(coord % dim)
|
||||
elif mode == 'W': # wrap
|
||||
if coord < 0:
|
||||
return <Py_ssize_t>(dim - (-coord % dim))
|
||||
elif coord > dim:
|
||||
return <Py_ssize_t>(coord % dim)
|
||||
elif mode == 'N': # nearest
|
||||
if coord < 0:
|
||||
return 0
|
||||
elif coord > dim:
|
||||
return dim
|
||||
|
||||
return coord
|
||||
@@ -14,12 +14,9 @@ def configuration(parent_package='', top_path=None):
|
||||
config.add_data_dir('tests')
|
||||
|
||||
cython(['geometry.pyx'], working_path=base_path)
|
||||
cython(['interpolation.pyx'], working_path=base_path)
|
||||
cython(['transform.pyx'], working_path=base_path)
|
||||
|
||||
config.add_extension('geometry', sources=['geometry.c'])
|
||||
config.add_extension('interpolation', sources=['interpolation.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
config.add_extension('transform', sources=['transform.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
|
||||
|
||||
@@ -1,423 +0,0 @@
|
||||
"""Utilities for writing code that runs on Python 2 and 3"""
|
||||
|
||||
# Copyright (c) 2010-2013 Benjamin Peterson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
import operator
|
||||
import sys
|
||||
import types
|
||||
|
||||
__author__ = "Benjamin Peterson <benjamin@python.org>"
|
||||
__version__ = "1.3.0"
|
||||
|
||||
|
||||
# Useful for very coarse version differentiation.
|
||||
PY2 = sys.version_info[0] == 2
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
if PY3:
|
||||
string_types = str,
|
||||
integer_types = int,
|
||||
class_types = type,
|
||||
text_type = str
|
||||
binary_type = bytes
|
||||
|
||||
MAXSIZE = sys.maxsize
|
||||
else:
|
||||
string_types = basestring,
|
||||
integer_types = (int, long)
|
||||
class_types = (type, types.ClassType)
|
||||
text_type = unicode
|
||||
binary_type = str
|
||||
|
||||
if sys.platform.startswith("java"):
|
||||
# Jython always uses 32 bits.
|
||||
MAXSIZE = int((1 << 31) - 1)
|
||||
else:
|
||||
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
|
||||
class X(object):
|
||||
def __len__(self):
|
||||
return 1 << 31
|
||||
try:
|
||||
len(X())
|
||||
except OverflowError:
|
||||
# 32-bit
|
||||
MAXSIZE = int((1 << 31) - 1)
|
||||
else:
|
||||
# 64-bit
|
||||
MAXSIZE = int((1 << 63) - 1)
|
||||
del X
|
||||
|
||||
|
||||
def _add_doc(func, doc):
|
||||
"""Add documentation to a function."""
|
||||
func.__doc__ = doc
|
||||
|
||||
|
||||
def _import_module(name):
|
||||
"""Import module, returning the module after the last dot."""
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
|
||||
|
||||
class _LazyDescr(object):
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __get__(self, obj, tp):
|
||||
result = self._resolve()
|
||||
setattr(obj, self.name, result)
|
||||
# This is a bit ugly, but it avoids running this again.
|
||||
delattr(tp, self.name)
|
||||
return result
|
||||
|
||||
|
||||
class MovedModule(_LazyDescr):
|
||||
|
||||
def __init__(self, name, old, new=None):
|
||||
super(MovedModule, self).__init__(name)
|
||||
if PY3:
|
||||
if new is None:
|
||||
new = name
|
||||
self.mod = new
|
||||
else:
|
||||
self.mod = old
|
||||
|
||||
def _resolve(self):
|
||||
return _import_module(self.mod)
|
||||
|
||||
|
||||
class MovedAttribute(_LazyDescr):
|
||||
|
||||
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
|
||||
super(MovedAttribute, self).__init__(name)
|
||||
if PY3:
|
||||
if new_mod is None:
|
||||
new_mod = name
|
||||
self.mod = new_mod
|
||||
if new_attr is None:
|
||||
if old_attr is None:
|
||||
new_attr = name
|
||||
else:
|
||||
new_attr = old_attr
|
||||
self.attr = new_attr
|
||||
else:
|
||||
self.mod = old_mod
|
||||
if old_attr is None:
|
||||
old_attr = name
|
||||
self.attr = old_attr
|
||||
|
||||
def _resolve(self):
|
||||
module = _import_module(self.mod)
|
||||
return getattr(module, self.attr)
|
||||
|
||||
|
||||
|
||||
class _MovedItems(types.ModuleType):
|
||||
"""Lazy loading of moved objects"""
|
||||
|
||||
|
||||
_moved_attributes = [
|
||||
MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
|
||||
MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
|
||||
MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
|
||||
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
|
||||
MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
|
||||
MovedAttribute("reload_module", "__builtin__", "imp", "reload"),
|
||||
MovedAttribute("reduce", "__builtin__", "functools"),
|
||||
MovedAttribute("StringIO", "StringIO", "io"),
|
||||
MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
|
||||
MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
|
||||
|
||||
MovedModule("builtins", "__builtin__"),
|
||||
MovedModule("configparser", "ConfigParser"),
|
||||
MovedModule("copyreg", "copy_reg"),
|
||||
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
|
||||
MovedModule("http_cookies", "Cookie", "http.cookies"),
|
||||
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
|
||||
MovedModule("html_parser", "HTMLParser", "html.parser"),
|
||||
MovedModule("http_client", "httplib", "http.client"),
|
||||
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
|
||||
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
|
||||
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
|
||||
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
|
||||
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
|
||||
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
|
||||
MovedModule("cPickle", "cPickle", "pickle"),
|
||||
MovedModule("queue", "Queue"),
|
||||
MovedModule("reprlib", "repr"),
|
||||
MovedModule("socketserver", "SocketServer"),
|
||||
MovedModule("tkinter", "Tkinter"),
|
||||
MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
|
||||
MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
|
||||
MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
|
||||
MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
|
||||
MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
|
||||
MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
|
||||
MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
|
||||
MovedModule("tkinter_colorchooser", "tkColorChooser",
|
||||
"tkinter.colorchooser"),
|
||||
MovedModule("tkinter_commondialog", "tkCommonDialog",
|
||||
"tkinter.commondialog"),
|
||||
MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
|
||||
MovedModule("tkinter_font", "tkFont", "tkinter.font"),
|
||||
MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
|
||||
MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
|
||||
"tkinter.simpledialog"),
|
||||
MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
|
||||
MovedModule("winreg", "_winreg"),
|
||||
]
|
||||
for attr in _moved_attributes:
|
||||
setattr(_MovedItems, attr.name, attr)
|
||||
del attr
|
||||
|
||||
moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves")
|
||||
|
||||
|
||||
def add_move(move):
|
||||
"""Add an item to six.moves."""
|
||||
setattr(_MovedItems, move.name, move)
|
||||
|
||||
|
||||
def remove_move(name):
|
||||
"""Remove item from six.moves."""
|
||||
try:
|
||||
delattr(_MovedItems, name)
|
||||
except AttributeError:
|
||||
try:
|
||||
del moves.__dict__[name]
|
||||
except KeyError:
|
||||
raise AttributeError("no such move, %r" % (name,))
|
||||
|
||||
|
||||
if PY3:
|
||||
_meth_func = "__func__"
|
||||
_meth_self = "__self__"
|
||||
|
||||
_func_closure = "__closure__"
|
||||
_func_code = "__code__"
|
||||
_func_defaults = "__defaults__"
|
||||
_func_globals = "__globals__"
|
||||
|
||||
_iterkeys = "keys"
|
||||
_itervalues = "values"
|
||||
_iteritems = "items"
|
||||
_iterlists = "lists"
|
||||
else:
|
||||
_meth_func = "im_func"
|
||||
_meth_self = "im_self"
|
||||
|
||||
_func_closure = "func_closure"
|
||||
_func_code = "func_code"
|
||||
_func_defaults = "func_defaults"
|
||||
_func_globals = "func_globals"
|
||||
|
||||
_iterkeys = "iterkeys"
|
||||
_itervalues = "itervalues"
|
||||
_iteritems = "iteritems"
|
||||
_iterlists = "iterlists"
|
||||
|
||||
|
||||
try:
|
||||
advance_iterator = next
|
||||
except NameError:
|
||||
def advance_iterator(it):
|
||||
return it.next()
|
||||
next = advance_iterator
|
||||
|
||||
|
||||
try:
|
||||
callable = callable
|
||||
except NameError:
|
||||
def callable(obj):
|
||||
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
|
||||
|
||||
|
||||
if PY3:
|
||||
def get_unbound_function(unbound):
|
||||
return unbound
|
||||
|
||||
create_bound_method = types.MethodType
|
||||
|
||||
Iterator = object
|
||||
else:
|
||||
def get_unbound_function(unbound):
|
||||
return unbound.im_func
|
||||
|
||||
def create_bound_method(func, obj):
|
||||
return types.MethodType(func, obj, obj.__class__)
|
||||
|
||||
class Iterator(object):
|
||||
|
||||
def next(self):
|
||||
return type(self).__next__(self)
|
||||
|
||||
callable = callable
|
||||
_add_doc(get_unbound_function,
|
||||
"""Get the function out of a possibly unbound function""")
|
||||
|
||||
|
||||
get_method_function = operator.attrgetter(_meth_func)
|
||||
get_method_self = operator.attrgetter(_meth_self)
|
||||
get_function_closure = operator.attrgetter(_func_closure)
|
||||
get_function_code = operator.attrgetter(_func_code)
|
||||
get_function_defaults = operator.attrgetter(_func_defaults)
|
||||
get_function_globals = operator.attrgetter(_func_globals)
|
||||
|
||||
|
||||
def iterkeys(d, **kw):
|
||||
"""Return an iterator over the keys of a dictionary."""
|
||||
return iter(getattr(d, _iterkeys)(**kw))
|
||||
|
||||
def itervalues(d, **kw):
|
||||
"""Return an iterator over the values of a dictionary."""
|
||||
return iter(getattr(d, _itervalues)(**kw))
|
||||
|
||||
def iteritems(d, **kw):
|
||||
"""Return an iterator over the (key, value) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iteritems)(**kw))
|
||||
|
||||
def iterlists(d, **kw):
|
||||
"""Return an iterator over the (key, [values]) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iterlists)(**kw))
|
||||
|
||||
|
||||
if PY3:
|
||||
def b(s):
|
||||
return s.encode("latin-1")
|
||||
def u(s):
|
||||
return s
|
||||
unichr = chr
|
||||
if sys.version_info[1] <= 1:
|
||||
def int2byte(i):
|
||||
return bytes((i,))
|
||||
else:
|
||||
# This is about 2x faster than the implementation above on 3.2+
|
||||
int2byte = operator.methodcaller("to_bytes", 1, "big")
|
||||
byte2int = operator.itemgetter(0)
|
||||
indexbytes = operator.getitem
|
||||
iterbytes = iter
|
||||
import io
|
||||
StringIO = io.StringIO
|
||||
BytesIO = io.BytesIO
|
||||
else:
|
||||
def b(s):
|
||||
return s
|
||||
def u(s):
|
||||
return unicode(s, "unicode_escape")
|
||||
unichr = unichr
|
||||
int2byte = chr
|
||||
def byte2int(bs):
|
||||
return ord(bs[0])
|
||||
def indexbytes(buf, i):
|
||||
return ord(buf[i])
|
||||
def iterbytes(buf):
|
||||
return (ord(byte) for byte in buf)
|
||||
import StringIO
|
||||
StringIO = BytesIO = StringIO.StringIO
|
||||
_add_doc(b, """Byte literal""")
|
||||
_add_doc(u, """Text literal""")
|
||||
|
||||
|
||||
if PY3:
|
||||
import builtins
|
||||
exec_ = getattr(builtins, "exec")
|
||||
|
||||
|
||||
def reraise(tp, value, tb=None):
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
raise value
|
||||
|
||||
|
||||
print_ = getattr(builtins, "print")
|
||||
del builtins
|
||||
|
||||
else:
|
||||
def exec_(_code_, _globs_=None, _locs_=None):
|
||||
"""Execute code in a namespace."""
|
||||
if _globs_ is None:
|
||||
frame = sys._getframe(1)
|
||||
_globs_ = frame.f_globals
|
||||
if _locs_ is None:
|
||||
_locs_ = frame.f_locals
|
||||
del frame
|
||||
elif _locs_ is None:
|
||||
_locs_ = _globs_
|
||||
exec("""exec _code_ in _globs_, _locs_""")
|
||||
|
||||
|
||||
exec_("""def reraise(tp, value, tb=None):
|
||||
raise tp, value, tb
|
||||
""")
|
||||
|
||||
|
||||
def print_(*args, **kwargs):
|
||||
"""The new-style print function."""
|
||||
fp = kwargs.pop("file", sys.stdout)
|
||||
if fp is None:
|
||||
return
|
||||
def write(data):
|
||||
if not isinstance(data, basestring):
|
||||
data = str(data)
|
||||
fp.write(data)
|
||||
want_unicode = False
|
||||
sep = kwargs.pop("sep", None)
|
||||
if sep is not None:
|
||||
if isinstance(sep, unicode):
|
||||
want_unicode = True
|
||||
elif not isinstance(sep, str):
|
||||
raise TypeError("sep must be None or a string")
|
||||
end = kwargs.pop("end", None)
|
||||
if end is not None:
|
||||
if isinstance(end, unicode):
|
||||
want_unicode = True
|
||||
elif not isinstance(end, str):
|
||||
raise TypeError("end must be None or a string")
|
||||
if kwargs:
|
||||
raise TypeError("invalid keyword arguments to print()")
|
||||
if not want_unicode:
|
||||
for arg in args:
|
||||
if isinstance(arg, unicode):
|
||||
want_unicode = True
|
||||
break
|
||||
if want_unicode:
|
||||
newline = unicode("\n")
|
||||
space = unicode(" ")
|
||||
else:
|
||||
newline = "\n"
|
||||
space = " "
|
||||
if sep is None:
|
||||
sep = space
|
||||
if end is None:
|
||||
end = newline
|
||||
for i, arg in enumerate(args):
|
||||
if i:
|
||||
write(sep)
|
||||
write(arg)
|
||||
write(end)
|
||||
|
||||
_add_doc(reraise, """Reraise an exception.""")
|
||||
|
||||
|
||||
def with_metaclass(meta, *bases):
|
||||
"""Create a base class with a metaclass."""
|
||||
return meta("NewBase", bases, {})
|
||||
@@ -1,6 +1,12 @@
|
||||
"""Testing utilities."""
|
||||
|
||||
|
||||
import re
|
||||
|
||||
|
||||
SKIP_RE = re.compile("(\s*>>>.*?)(\s*)#\s*skip\s+if\s+(.*)$")
|
||||
|
||||
|
||||
def _assert_less(a, b, msg=None):
|
||||
message = "%r is not lower than %r" % (a, b)
|
||||
if msg is not None:
|
||||
@@ -24,3 +30,48 @@ try:
|
||||
from nose.tools import assert_greater
|
||||
except ImportError:
|
||||
assert_greater = _assert_greater
|
||||
|
||||
|
||||
def doctest_skip_parser(func):
|
||||
""" Decorator replaces custom skip test markup in doctests
|
||||
|
||||
Say a function has a docstring::
|
||||
|
||||
>>> something # skip if not HAVE_AMODULE
|
||||
>>> something + else
|
||||
>>> something # skip if HAVE_BMODULE
|
||||
|
||||
This decorator will evaluate the expresssion after ``skip if``. If this
|
||||
evaluates to True, then the comment is replaced by ``# doctest: +SKIP``. If
|
||||
False, then the comment is just removed. The expression is evaluated in the
|
||||
``globals`` scope of `func`.
|
||||
|
||||
For example, if the module global ``HAVE_AMODULE`` is False, and module
|
||||
global ``HAVE_BMODULE`` is False, the returned function will have docstring::
|
||||
|
||||
>>> something # doctest: +SKIP
|
||||
>>> something + else
|
||||
>>> something
|
||||
|
||||
"""
|
||||
lines = func.__doc__.split('\n')
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
match = SKIP_RE.match(line)
|
||||
if match is None:
|
||||
new_lines.append(line)
|
||||
continue
|
||||
code, space, expr = match.groups()
|
||||
|
||||
try:
|
||||
# Works as a function decorator
|
||||
if eval(expr, func.__globals__):
|
||||
code = code + space + "# doctest: +SKIP"
|
||||
except AttributeError:
|
||||
# Works as a class decorator
|
||||
if eval(expr, func.__init__.__globals__):
|
||||
code = code + space + "# doctest: +SKIP"
|
||||
|
||||
new_lines.append(code)
|
||||
func.__doc__ = "\n".join(new_lines)
|
||||
return func
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import numpy as np
|
||||
from skimage._shared.utils import safe_as_int
|
||||
|
||||
|
||||
def test_int_cast_not_possible():
|
||||
np.testing.assert_raises(ValueError, safe_as_int, 7.1)
|
||||
np.testing.assert_raises(ValueError, safe_as_int, [7.1, 0.9])
|
||||
np.testing.assert_raises(ValueError, safe_as_int, np.r_[7.1, 0.9])
|
||||
np.testing.assert_raises(ValueError, safe_as_int, (7.1, 0.9))
|
||||
np.testing.assert_raises(ValueError, safe_as_int, ((3, 4, 1),
|
||||
(2, 7.6, 289)))
|
||||
|
||||
np.testing.assert_raises(ValueError, safe_as_int, 7.1, 0.09)
|
||||
np.testing.assert_raises(ValueError, safe_as_int, [7.1, 0.9], 0.09)
|
||||
np.testing.assert_raises(ValueError, safe_as_int, np.r_[7.1, 0.9], 0.09)
|
||||
np.testing.assert_raises(ValueError, safe_as_int, (7.1, 0.9), 0.09)
|
||||
np.testing.assert_raises(ValueError, safe_as_int, ((3, 4, 1),
|
||||
(2, 7.6, 289)), 0.25)
|
||||
|
||||
|
||||
def test_int_cast_possible():
|
||||
np.testing.assert_equal(safe_as_int(7.1, atol=0.11), 7)
|
||||
np.testing.assert_equal(safe_as_int(-7.1, atol=0.11), -7)
|
||||
np.testing.assert_equal(safe_as_int(41.9, atol=0.11), 42)
|
||||
np.testing.assert_array_equal(safe_as_int([2, 42, 5789234.0, 87, 4]),
|
||||
np.r_[2, 42, 5789234, 87, 4])
|
||||
np.testing.assert_array_equal(safe_as_int(np.r_[[[3, 4, 1.000000001],
|
||||
[7, 2, -8.999999999],
|
||||
[6, 9, -4234918347.]]]),
|
||||
np.r_[[[3, 4, 1],
|
||||
[7, 2, -9],
|
||||
[6, 9, -4234918347]]])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
np.testing.run_module_suite()
|
||||
@@ -0,0 +1,87 @@
|
||||
""" Testing decorators module
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from nose.tools import (assert_true, assert_raises, assert_equal)
|
||||
from skimage._shared.testing import doctest_skip_parser
|
||||
|
||||
|
||||
def test_skipper():
|
||||
def f():
|
||||
pass
|
||||
|
||||
class c():
|
||||
def __init__(self):
|
||||
self.me = "I think, therefore..."
|
||||
|
||||
docstring = \
|
||||
""" Header
|
||||
|
||||
>>> something # skip if not HAVE_AMODULE
|
||||
>>> something + else
|
||||
>>> a = 1 # skip if not HAVE_BMODULE
|
||||
>>> something2 # skip if HAVE_AMODULE
|
||||
"""
|
||||
f.__doc__ = docstring
|
||||
c.__doc__ = docstring
|
||||
|
||||
global HAVE_AMODULE, HAVE_BMODULE
|
||||
HAVE_AMODULE = False
|
||||
HAVE_BMODULE = True
|
||||
|
||||
f2 = doctest_skip_parser(f)
|
||||
c2 = doctest_skip_parser(c)
|
||||
assert_true(f is f2)
|
||||
assert_true(c is c2)
|
||||
|
||||
assert_equal(f2.__doc__,
|
||||
""" Header
|
||||
|
||||
>>> something # doctest: +SKIP
|
||||
>>> something + else
|
||||
>>> a = 1
|
||||
>>> something2
|
||||
""")
|
||||
assert_equal(c2.__doc__,
|
||||
""" Header
|
||||
|
||||
>>> something # doctest: +SKIP
|
||||
>>> something + else
|
||||
>>> a = 1
|
||||
>>> something2
|
||||
""")
|
||||
|
||||
HAVE_AMODULE = True
|
||||
HAVE_BMODULE = False
|
||||
f.__doc__ = docstring
|
||||
c.__doc__ = docstring
|
||||
f2 = doctest_skip_parser(f)
|
||||
c2 = doctest_skip_parser(c)
|
||||
|
||||
assert_true(f is f2)
|
||||
assert_equal(f2.__doc__,
|
||||
""" Header
|
||||
|
||||
>>> something
|
||||
>>> something + else
|
||||
>>> a = 1 # doctest: +SKIP
|
||||
>>> something2 # doctest: +SKIP
|
||||
""")
|
||||
assert_equal(c2.__doc__,
|
||||
""" Header
|
||||
|
||||
>>> something
|
||||
>>> something + else
|
||||
>>> a = 1 # doctest: +SKIP
|
||||
>>> something2 # doctest: +SKIP
|
||||
""")
|
||||
|
||||
del HAVE_AMODULE
|
||||
f.__doc__ = docstring
|
||||
c.__doc__ = docstring
|
||||
assert_raises(NameError, doctest_skip_parser, f)
|
||||
assert_raises(NameError, doctest_skip_parser, c)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
np.testing.run_module_suite()
|
||||
@@ -41,4 +41,5 @@ cdef float integrate(float[:, ::1] sat, Py_ssize_t r0, Py_ssize_t c0,
|
||||
|
||||
if (c0 - 1 >= 0):
|
||||
S -= sat[r1, c0 - 1]
|
||||
|
||||
return S
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import warnings
|
||||
import functools
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
from . import six
|
||||
import six
|
||||
|
||||
from ._warnings import all_warnings
|
||||
|
||||
__all__ = ['deprecated', 'get_bound_method_class']
|
||||
__all__ = ['deprecated', 'get_bound_method_class', 'all_warnings',
|
||||
'safe_as_int']
|
||||
|
||||
|
||||
class skimage_deprecation(Warning):
|
||||
@@ -71,3 +74,70 @@ def get_bound_method_class(m):
|
||||
|
||||
"""
|
||||
return m.im_class if sys.version < '3' else m.__self__.__class__
|
||||
|
||||
|
||||
def safe_as_int(val, atol=1e-3):
|
||||
"""
|
||||
Attempt to safely cast values to integer format.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
val : scalar or iterable of scalars
|
||||
Number or container of numbers which are intended to be interpreted as
|
||||
integers, e.g., for indexing purposes, but which may not carry integer
|
||||
type.
|
||||
atol : float
|
||||
Absolute tolerance away from nearest integer to consider values in
|
||||
``val`` functionally integers.
|
||||
|
||||
Returns
|
||||
-------
|
||||
val_int : NumPy scalar or ndarray of dtype `np.int64`
|
||||
Returns the input value(s) coerced to dtype `np.int64` assuming all
|
||||
were within ``atol`` of the nearest integer.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This operation calculates ``val`` modulo 1, which returns the mantissa of
|
||||
all values. Then all mantissas greater than 0.5 are subtracted from one.
|
||||
Finally, the absolute tolerance from zero is calculated. If it is less
|
||||
than ``atol`` for all value(s) in ``val``, they are rounded and returned
|
||||
in an integer array. Or, if ``val`` was a scalar, a NumPy scalar type is
|
||||
returned.
|
||||
|
||||
If any value(s) are outside the specified tolerance, an informative error
|
||||
is raised.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> _safe_as_int(7.0)
|
||||
7
|
||||
|
||||
>>> _safe_as_int([9, 4, 2.9999999999])
|
||||
array([9, 4, 3], dtype=int32)
|
||||
|
||||
>>> _safe_as_int(53.01)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Integer argument required but received 53.1, check inputs.
|
||||
|
||||
>>> _safe_as_int(53.01, atol=0.01)
|
||||
53
|
||||
|
||||
"""
|
||||
mod = np.asarray(val) % 1 # Extract mantissa
|
||||
|
||||
# Check for and subtract any mod values > 0.5 from 1
|
||||
if mod.ndim == 0: # Scalar input, cannot be indexed
|
||||
if mod > 0.5:
|
||||
mod = 1 - mod
|
||||
else: # Iterable input, now ndarray
|
||||
mod[mod > 0.5] = 1 - mod[mod > 0.5] # Test on each side of nearest int
|
||||
|
||||
try:
|
||||
np.testing.assert_allclose(mod, 0, atol=atol)
|
||||
except AssertionError:
|
||||
raise ValueError("Integer argument required but received "
|
||||
"{0}, check inputs.".format(val))
|
||||
|
||||
return np.round(val).astype(np.int64)
|
||||
|
||||
@@ -13,6 +13,10 @@ from .colorconv import (convert_colorspace,
|
||||
lab2xyz,
|
||||
lab2rgb,
|
||||
rgb2lab,
|
||||
xyz2luv,
|
||||
luv2xyz,
|
||||
luv2rgb,
|
||||
rgb2luv,
|
||||
rgb2hed,
|
||||
hed2rgb,
|
||||
lab2lch,
|
||||
@@ -40,9 +44,7 @@ from .colorconv import (convert_colorspace,
|
||||
rgb_from_ahx,
|
||||
ahx_from_rgb,
|
||||
rgb_from_hpx,
|
||||
hpx_from_rgb,
|
||||
is_rgb,
|
||||
is_gray)
|
||||
hpx_from_rgb)
|
||||
|
||||
from .colorlabel import color_dict, label2rgb
|
||||
|
||||
@@ -96,8 +98,6 @@ __all__ = ['convert_colorspace',
|
||||
'ahx_from_rgb',
|
||||
'rgb_from_hpx',
|
||||
'hpx_from_rgb',
|
||||
'is_rgb',
|
||||
'is_gray',
|
||||
'color_dict',
|
||||
'label2rgb',
|
||||
'deltaE_cie76',
|
||||
|
||||
+247
-90
@@ -29,9 +29,12 @@ Supported color spaces
|
||||
* LAB CIE : Lightness, a, b
|
||||
Colorspace derived from XYZ CIE that is intended to be more
|
||||
perceptually uniform
|
||||
* LUV CIE : Lightness, u, v
|
||||
Colorspace derived from XYZ CIE that is intended to be more
|
||||
perceptually uniform
|
||||
* LCH CIE : Lightness, Chroma, Hue
|
||||
Defined in terms of LAB CIE. C and H are the polar representation of
|
||||
a and b. The polar angle C is defined to be on (0, 2*pi)
|
||||
a and b. The polar angle C is defined to be on ``(0, 2*pi)``
|
||||
|
||||
:author: Nicolas Pinto (rgb2hsv)
|
||||
:author: Ralf Gommers (hsv2rgb)
|
||||
@@ -68,7 +71,7 @@ def guess_spatial_dimensions(image):
|
||||
-------
|
||||
spatial_dims : int or None
|
||||
The number of spatial dimensions of `image`. If ambiguous, the value
|
||||
is `None`.
|
||||
is ``None``.
|
||||
|
||||
Raises
|
||||
------
|
||||
@@ -87,32 +90,6 @@ def guess_spatial_dimensions(image):
|
||||
raise ValueError("Expected 2D, 3D, or 4D array, got %iD." % image.ndim)
|
||||
|
||||
|
||||
@deprecated()
|
||||
def is_rgb(image):
|
||||
"""Test whether the image is RGB or RGBA.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : ndarray
|
||||
Input image.
|
||||
|
||||
"""
|
||||
return (image.ndim == 3 and image.shape[2] in (3, 4))
|
||||
|
||||
|
||||
@deprecated()
|
||||
def is_gray(image):
|
||||
"""Test whether the image is gray (i.e. has only one color band).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : ndarray
|
||||
Input image.
|
||||
|
||||
"""
|
||||
return image.ndim in (2, 3) and not is_rgb(image)
|
||||
|
||||
|
||||
def convert_colorspace(arr, fromspace, tospace):
|
||||
"""Convert an image array to a new color space.
|
||||
|
||||
@@ -122,12 +99,12 @@ def convert_colorspace(arr, fromspace, tospace):
|
||||
The image to convert.
|
||||
fromspace : str
|
||||
The color space to convert from. Valid color space strings are
|
||||
['RGB', 'HSV', 'RGB CIE', 'XYZ']. Value may also be specified as lower
|
||||
case.
|
||||
``['RGB', 'HSV', 'RGB CIE', 'XYZ']``. Value may also be specified as
|
||||
lower case.
|
||||
tospace : str
|
||||
The color space to convert to. Valid color space strings are
|
||||
['RGB', 'HSV', 'RGB CIE', 'XYZ']. Value may also be specified as lower
|
||||
case.
|
||||
``['RGB', 'HSV', 'RGB CIE', 'XYZ']``. Value may also be specified as
|
||||
lower case.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -137,7 +114,7 @@ def convert_colorspace(arr, fromspace, tospace):
|
||||
Notes
|
||||
-----
|
||||
Conversion occurs through the "central" RGB color space, i.e. conversion
|
||||
from XYZ to HSV is implemented as XYZ -> RGB -> HSV instead of directly.
|
||||
from XYZ to HSV is implemented as ``XYZ -> RGB -> HSV`` instead of directly.
|
||||
|
||||
Examples
|
||||
--------
|
||||
@@ -181,17 +158,17 @@ def rgb2hsv(rgb):
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in HSV format, in a 3-D array of shape (.., .., 3).
|
||||
The image in HSV format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3-D array of shape (.., .., 3).
|
||||
If `rgb` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -259,21 +236,21 @@ def hsv2rgb(hsv):
|
||||
Parameters
|
||||
----------
|
||||
hsv : array_like
|
||||
The image in HSV format, in a 3-D array of shape (.., .., 3).
|
||||
The image in HSV format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `hsv` is not a 3-D array of shape (.., .., 3).
|
||||
If `hsv` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
The conversion assumes an input data range of [0, 1] for all
|
||||
The conversion assumes an input data range of ``[0, 1]`` for all
|
||||
color components.
|
||||
|
||||
Conversion between RGB and HSV color spaces results in some loss of
|
||||
@@ -468,17 +445,17 @@ def xyz2rgb(xyz):
|
||||
Parameters
|
||||
----------
|
||||
xyz : array_like
|
||||
The image in XYZ format, in a 3-D array of shape (.., .., 3).
|
||||
The image in XYZ format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `xyz` is not a 3-D array of shape (.., .., 3).
|
||||
If `xyz` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -513,18 +490,18 @@ def rgb2xyz(rgb):
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3- or 4-D array of shape
|
||||
(.., ..,[ ..,] 3).
|
||||
``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in XYZ format, in a 3- or 4-D array of shape
|
||||
(.., ..,[ ..,] 3).
|
||||
``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3- or 4-D array of shape (.., ..,[ ..,] 3).
|
||||
If `rgb` is not a 3- or 4-D array of shape ``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -556,17 +533,17 @@ def rgb2rgbcie(rgb):
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB CIE format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB CIE format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3-D array of shape (.., .., 3).
|
||||
If `rgb` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
References
|
||||
----------
|
||||
@@ -588,17 +565,17 @@ def rgbcie2rgb(rgbcie):
|
||||
Parameters
|
||||
----------
|
||||
rgbcie : array_like
|
||||
The image in RGB CIE format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB CIE format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgbcie` is not a 3-D array of shape (.., .., 3).
|
||||
If `rgbcie` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
References
|
||||
----------
|
||||
@@ -621,8 +598,8 @@ def rgb2gray(rgb):
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3),
|
||||
or in RGBA format with shape (.., .., 4).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``,
|
||||
or in RGBA format with shape ``(.., .., 4)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -632,8 +609,8 @@ def rgb2gray(rgb):
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb2gray` is not a 3-D array of shape (.., .., 3) or
|
||||
(.., .., 4).
|
||||
If `rgb2gray` is not a 3-D array of shape ``(.., .., 3)`` or
|
||||
``(.., .., 4)``.
|
||||
|
||||
References
|
||||
----------
|
||||
@@ -698,18 +675,18 @@ def xyz2lab(xyz):
|
||||
----------
|
||||
xyz : array_like
|
||||
The image in XYZ format, in a 3- or 4-D array of shape
|
||||
(.., ..,[ ..,] 3).
|
||||
``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in CIE-LAB format, in a 3- or 4-D array of shape
|
||||
(.., ..,[ ..,] 3).
|
||||
``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `xyz` is not a 3-D array of shape (.., ..,[ ..,] 3).
|
||||
If `xyz` is not a 3-D array of shape ``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -755,21 +732,21 @@ def lab2xyz(lab):
|
||||
Parameters
|
||||
----------
|
||||
lab : array_like
|
||||
The image in lab format, in a 3-D array of shape (.., .., 3).
|
||||
The image in lab format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in XYZ format, in a 3-D array of shape (.., .., 3).
|
||||
The image in XYZ format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `lab` is not a 3-D array of shape (.., .., 3).
|
||||
If `lab` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Observer= 2A, Illuminant= D65
|
||||
Observer = 2A, Illuminant = D65
|
||||
CIE XYZ tristimulus values x_ref = 95.047, y_ref = 100., z_ref = 108.883
|
||||
|
||||
References
|
||||
@@ -804,18 +781,18 @@ def rgb2lab(rgb):
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3- or 4-D array of shape
|
||||
(.., ..,[ ..,] 3).
|
||||
``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in Lab format, in a 3- or 4-D array of shape
|
||||
(.., ..,[ ..,] 3).
|
||||
``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3- or 4-D array of shape (.., ..,[ ..,] 3).
|
||||
If `rgb` is not a 3- or 4-D array of shape ``(.., ..,[ ..,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -829,18 +806,18 @@ def lab2rgb(lab):
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in Lab format, in a 3-D array of shape (.., .., 3).
|
||||
lab : array_like
|
||||
The image in Lab format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `lab` is not a 3-D array of shape (.., .., 3).
|
||||
If `lab` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -849,23 +826,203 @@ def lab2rgb(lab):
|
||||
return xyz2rgb(lab2xyz(lab))
|
||||
|
||||
|
||||
def xyz2luv(xyz):
|
||||
"""XYZ to CIE-Luv color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
xyz : (M, N, [P,] 3) array_like
|
||||
The 3 or 4 dimensional image in XYZ format. Final dimension denotes
|
||||
channels.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : (M, N, [P,] 3) ndarray
|
||||
The image in CIE-Luv format. Same dimensions as input.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `xyz` is not a 3-D or 4-D array of shape ``(M, N, [P,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
XYZ conversion weights use Observer = 2A. Reference whitepoint for D65
|
||||
Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] http://www.easyrgb.com/index.php?X=MATH&H=16#text16
|
||||
.. [2] http://en.wikipedia.org/wiki/CIELUV
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from skimage import data
|
||||
>>> from skimage.color import rgb2xyz, xyz2luv
|
||||
>>> lena = data.lena()
|
||||
>>> lena_xyz = rgb2xyz(lena)
|
||||
>>> lena_luv = xyz2luv(lena_xyz)
|
||||
"""
|
||||
arr = _prepare_colorarray(xyz)
|
||||
|
||||
# extract channels
|
||||
x, y, z = arr[..., 0], arr[..., 1], arr[..., 2]
|
||||
|
||||
eps = np.finfo(np.float).eps
|
||||
|
||||
# compute y_r and L
|
||||
L = y / lab_ref_white[1]
|
||||
mask = L > 0.008856
|
||||
L[mask] = 116. * np.power(L[mask], 1. / 3.) - 16.
|
||||
L[~mask] = 903.3 * L[~mask]
|
||||
|
||||
u0 = 4*lab_ref_white[0] / np.dot([1, 15, 3], lab_ref_white)
|
||||
v0 = 9*lab_ref_white[1] / np.dot([1, 15, 3], lab_ref_white)
|
||||
|
||||
# u' and v' helper functions
|
||||
def fu(X, Y, Z):
|
||||
return (4.*X) / (X + 15.*Y + 3.*Z + eps)
|
||||
|
||||
def fv(X, Y, Z):
|
||||
return (9.*Y) / (X + 15.*Y + 3.*Z + eps)
|
||||
|
||||
# compute u and v using helper functions
|
||||
u = 13.*L * (fu(x, y, z) - u0)
|
||||
v = 13.*L * (fv(x, y, z) - v0)
|
||||
|
||||
return np.concatenate([q[..., np.newaxis] for q in [L, u, v]], axis=-1)
|
||||
|
||||
|
||||
def luv2xyz(luv):
|
||||
"""CIE-Luv to XYZ color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
luv : (M, N, [P,] 3) array_like
|
||||
The 3 or 4 dimensional image in CIE-Luv format. Final dimension denotes
|
||||
channels.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : (M, N, [P,] 3) ndarray
|
||||
The image in XYZ format. Same dimensions as input.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `luv` is not a 3-D or 4-D array of shape ``(M, N, [P,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
XYZ conversion weights use Observer = 2A. Reference whitepoint for D65
|
||||
Illuminant, with XYZ tristimulus values of ``(95.047, 100., 108.883)``.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] http://www.easyrgb.com/index.php?X=MATH&H=16#text16
|
||||
.. [2] http://en.wikipedia.org/wiki/CIELUV
|
||||
|
||||
"""
|
||||
|
||||
arr = _prepare_colorarray(luv).copy()
|
||||
|
||||
L, u, v = arr[:, :, 0], arr[:, :, 1], arr[:, :, 2]
|
||||
|
||||
eps = np.finfo(np.float).eps
|
||||
|
||||
# compute y
|
||||
y = L.copy()
|
||||
mask = y > 7.999625
|
||||
y[mask] = np.power((y[mask]+16.) / 116., 3.)
|
||||
y[~mask] = y[~mask] / 903.3
|
||||
y *= lab_ref_white[1]
|
||||
|
||||
# reference white x,z
|
||||
uv_weights = [1, 15, 3]
|
||||
u0 = 4*lab_ref_white[0] / np.dot(uv_weights, lab_ref_white)
|
||||
v0 = 9*lab_ref_white[1] / np.dot(uv_weights, lab_ref_white)
|
||||
|
||||
# compute intermediate values
|
||||
a = u0 + u / (13.*L + eps)
|
||||
b = v0 + v / (13.*L + eps)
|
||||
c = 3*y * (5*b-3)
|
||||
|
||||
# compute x and z
|
||||
z = ((a-4)*c - 15*a*b*y) / (12*b)
|
||||
x = -(c/b + 3.*z)
|
||||
|
||||
return np.concatenate([q[..., np.newaxis] for q in [x, y, z]], axis=-1)
|
||||
|
||||
|
||||
def rgb2luv(rgb):
|
||||
"""RGB to CIE-Luv color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rgb : (M, N, [P,] 3) array_like
|
||||
The 3 or 4 dimensional image in RGB format. Final dimension denotes
|
||||
channels.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : (M, N, [P,] 3) ndarray
|
||||
The image in CIE Luv format. Same dimensions as input.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3-D or 4-D array of shape ``(M, N, [P,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This function uses rgb2xyz and xyz2luv.
|
||||
"""
|
||||
return xyz2luv(rgb2xyz(rgb))
|
||||
|
||||
|
||||
def luv2rgb(luv):
|
||||
"""Luv to RGB color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
luv : (M, N, [P,] 3) array_like
|
||||
The 3 or 4 dimensional image in CIE Luv format. Final dimension denotes
|
||||
channels.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : (M, N, [P,] 3) ndarray
|
||||
The image in RGB format. Same dimensions as input.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `luv` is not a 3-D or 4-D array of shape ``(M, N, [P,] 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This function uses luv2xyz and xyz2rgb.
|
||||
"""
|
||||
return xyz2rgb(luv2xyz(luv))
|
||||
|
||||
|
||||
def rgb2hed(rgb):
|
||||
"""RGB to Haematoxylin-Eosin-DAB (HED) color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in HED format, in a 3-D array of shape (.., .., 3).
|
||||
The image in HED format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3-D array of shape (.., .., 3).
|
||||
If `rgb` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
|
||||
References
|
||||
@@ -891,17 +1048,17 @@ def hed2rgb(hed):
|
||||
Parameters
|
||||
----------
|
||||
hed : array_like
|
||||
The image in the HED color space, in a 3-D array of shape (.., .., 3).
|
||||
The image in the HED color space, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `hed` is not a 3-D array of shape (.., .., 3).
|
||||
If `hed` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
References
|
||||
----------
|
||||
@@ -927,19 +1084,19 @@ def separate_stains(rgb, conv_matrix):
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
conv_matrix: ndarray
|
||||
The stain separation matrix as described by G. Landini [1]_.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in stain color space, in a 3-D array of shape (.., .., 3).
|
||||
The image in stain color space, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3-D array of shape (.., .., 3).
|
||||
If `rgb` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -981,19 +1138,19 @@ def combine_stains(stains, conv_matrix):
|
||||
Parameters
|
||||
----------
|
||||
stains : array_like
|
||||
The image in stain color space, in a 3-D array of shape (.., .., 3).
|
||||
The image in stain color space, in a 3-D array of shape ``(.., .., 3)``.
|
||||
conv_matrix: ndarray
|
||||
The stain separation matrix as described by G. Landini [1]_.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
The image in RGB format, in a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `stains` is not a 3-D array of shape (.., .., 3).
|
||||
If `stains` is not a 3-D array of shape ``(.., .., 3)``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -1043,9 +1200,9 @@ def lab2lch(lab):
|
||||
Parameters
|
||||
----------
|
||||
lab : array_like
|
||||
The N-D image in CIE-LAB format. The last (`N+1`th) dimension must have
|
||||
at least 3 elements, corresponding to the ``L``, ``a``, and ``b`` color
|
||||
channels. Subsequent elements are copied.
|
||||
The N-D image in CIE-LAB format. The last (``N+1``-th) dimension must
|
||||
have at least 3 elements, corresponding to the ``L``, ``a``, and ``b``
|
||||
color channels. Subsequent elements are copied.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -1059,7 +1216,7 @@ def lab2lch(lab):
|
||||
|
||||
Notes
|
||||
-----
|
||||
The Hue is expressed as an angle between (0, 2*pi)
|
||||
The Hue is expressed as an angle between ``(0, 2*pi)``
|
||||
|
||||
Examples
|
||||
--------
|
||||
@@ -1079,7 +1236,7 @@ def lab2lch(lab):
|
||||
def _cart2polar_2pi(x, y):
|
||||
"""convert cartesian coordiantes to polar (uses non-standard theta range!)
|
||||
|
||||
NON-STANDARD RANGE! Maps to (0, 2*pi) rather than usual (-pi, +pi)
|
||||
NON-STANDARD RANGE! Maps to ``(0, 2*pi)`` rather than usual ``(-pi, +pi)``
|
||||
"""
|
||||
r, t = np.hypot(x, y), np.arctan2(y, x)
|
||||
t += np.where(t < 0., 2 * np.pi, 0)
|
||||
@@ -1094,9 +1251,9 @@ def lch2lab(lch):
|
||||
Parameters
|
||||
----------
|
||||
lch : array_like
|
||||
The N-D image in CIE-LCH format. The last (`N+1`th) dimension must have
|
||||
at least 3 elements, corresponding to the ``L``, ``a``, and ``b`` color
|
||||
channels. Subsequent elements are copied.
|
||||
The N-D image in CIE-LCH format. The last (``N+1``-th) dimension must
|
||||
have at least 3 elements, corresponding to the ``L``, ``a``, and ``b``
|
||||
color channels. Subsequent elements are copied.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -17,7 +18,8 @@ DEFAULT_COLORS = ('red', 'blue', 'yellow', 'magenta', 'green',
|
||||
'indigo', 'darkorange', 'cyan', 'pink', 'yellowgreen')
|
||||
|
||||
|
||||
color_dict = rgb_colors.__dict__
|
||||
color_dict = dict((k, v) for k, v in six.iteritems(rgb_colors.__dict__)
|
||||
if isinstance(v, tuple))
|
||||
|
||||
|
||||
def _rgb_vector(color):
|
||||
@@ -110,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)
|
||||
|
||||
@@ -33,7 +33,8 @@ from skimage.color import (rgb2hsv, hsv2rgb,
|
||||
rgb2grey, gray2rgb,
|
||||
xyz2lab, lab2xyz,
|
||||
lab2rgb, rgb2lab,
|
||||
is_rgb, is_gray,
|
||||
xyz2luv, luv2xyz,
|
||||
luv2rgb, rgb2luv,
|
||||
lab2lch, lch2lab,
|
||||
guess_spatial_dimensions
|
||||
)
|
||||
@@ -69,17 +70,24 @@ class TestColorconv(TestCase):
|
||||
colbars_point75_array = np.swapaxes(colbars_point75.reshape(3, 4, 2), 0, 2)
|
||||
|
||||
xyz_array = np.array([[[0.4124, 0.21260, 0.01930]], # red
|
||||
[[0, 0, 0]], # black
|
||||
[[.9505, 1., 1.089]], # white
|
||||
[[.1805, .0722, .9505]], # blue
|
||||
[[.07719, .15438, .02573]], # green
|
||||
])
|
||||
[[0, 0, 0]], # black
|
||||
[[.9505, 1., 1.089]], # white
|
||||
[[.1805, .0722, .9505]], # blue
|
||||
[[.07719, .15438, .02573]], # green
|
||||
])
|
||||
lab_array = np.array([[[53.233, 80.109, 67.220]], # red
|
||||
[[0., 0., 0.]], # black
|
||||
[[100.0, 0.005, -0.010]], # white
|
||||
[[32.303, 79.197, -107.864]], # blue
|
||||
[[46.229, -51.7, 49.898]], # green
|
||||
])
|
||||
[[0., 0., 0.]], # black
|
||||
[[100.0, 0.005, -0.010]], # white
|
||||
[[32.303, 79.197, -107.864]], # blue
|
||||
[[46.229, -51.7, 49.898]], # green
|
||||
])
|
||||
|
||||
luv_array = np.array([[[53.233, 175.053, 37.751]], # red
|
||||
[[0., 0., 0.]], # black
|
||||
[[100., 0.001, -0.017]], # white
|
||||
[[32.303, -9.400, -130.358]], # blue
|
||||
[[46.228, -43.774, 56.589]], # green
|
||||
])
|
||||
|
||||
# RGB to HSV
|
||||
def test_rgb2hsv_conversion(self):
|
||||
@@ -250,6 +258,41 @@ class TestColorconv(TestCase):
|
||||
img_rgb = img_as_float(self.img_rgb)
|
||||
assert_array_almost_equal(lab2rgb(rgb2lab(img_rgb)), img_rgb)
|
||||
|
||||
# test matrices for xyz2luv and luv2xyz generated using
|
||||
# http://www.easyrgb.com/index.php?X=CALC
|
||||
# Note: easyrgb website displays xyz*100
|
||||
def test_xyz2luv(self):
|
||||
assert_array_almost_equal(xyz2luv(self.xyz_array),
|
||||
self.luv_array, decimal=3)
|
||||
|
||||
def test_luv2xyz(self):
|
||||
assert_array_almost_equal(luv2xyz(self.luv_array),
|
||||
self.xyz_array, decimal=3)
|
||||
|
||||
def test_rgb2luv_brucelindbloom(self):
|
||||
"""
|
||||
Test the RGB->Lab conversion by comparing to the calculator on the
|
||||
authoritative Bruce Lindbloom
|
||||
[website](http://brucelindbloom.com/index.html?ColorCalculator.html).
|
||||
"""
|
||||
# Obtained with D65 white point, sRGB model and gamma
|
||||
gt_for_colbars = np.array([
|
||||
[100, 0, 0],
|
||||
[97.1393, 7.7056, 106.7866],
|
||||
[91.1132, -70.4773, -15.2042],
|
||||
[87.7347, -83.0776, 107.3985],
|
||||
[60.3242, 84.0714, -108.6834],
|
||||
[53.2408, 175.0151, 37.7564],
|
||||
[32.2970, -9.4054, -130.3423],
|
||||
[0, 0, 0]]).T
|
||||
gt_array = np.swapaxes(gt_for_colbars.reshape(3, 4, 2), 0, 2)
|
||||
assert_array_almost_equal(rgb2luv(self.colbars_array),
|
||||
gt_array, decimal=2)
|
||||
|
||||
def test_luv_rgb_roundtrip(self):
|
||||
img_rgb = img_as_float(self.img_rgb)
|
||||
assert_array_almost_equal(luv2rgb(rgb2luv(img_rgb)), img_rgb)
|
||||
|
||||
def test_lab_lch_roundtrip(self):
|
||||
rgb = img_as_float(self.img_rgb)
|
||||
lab = rgb2lab(rgb)
|
||||
@@ -311,17 +354,6 @@ def test_gray2rgb_rgb():
|
||||
assert_equal(x, y)
|
||||
|
||||
|
||||
def test_is_rgb():
|
||||
color = data.lena()
|
||||
gray = data.camera()
|
||||
|
||||
assert is_rgb(color)
|
||||
assert not is_gray(color)
|
||||
|
||||
assert is_gray(gray)
|
||||
assert not is_gray(color)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from numpy.testing import run_module_suite
|
||||
run_module_suite()
|
||||
|
||||
@@ -24,7 +24,8 @@ __all__ = ['load',
|
||||
'clock',
|
||||
'immunohistochemistry',
|
||||
'chelsea',
|
||||
'coffee']
|
||||
'coffee',
|
||||
'hubble_deep_field']
|
||||
|
||||
|
||||
def load(f):
|
||||
@@ -200,3 +201,23 @@ def coffee():
|
||||
|
||||
"""
|
||||
return load("coffee.png")
|
||||
|
||||
|
||||
def hubble_deep_field():
|
||||
"""Hubble eXtreme Deep Field.
|
||||
|
||||
This photograph contains the Hubble Telescope's farthest ever view of
|
||||
the universe. It can be useful as an example for multi-scale
|
||||
detection.
|
||||
|
||||
Notes
|
||||
-----
|
||||
This image was downloaded from
|
||||
`HubbleSite
|
||||
<http://hubblesite.org/newscenter/archive/releases/2012/37/image/a/>`__.
|
||||
|
||||
The image was captured by NASA and `may be freely used in the
|
||||
public domain <http://www.nasa.gov/audience/formedia/features/MP_Photo_Guidelines.html>`_.
|
||||
|
||||
"""
|
||||
return load("hubble_deep_field.jpg")
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 186 B |
Binary file not shown.
|
After Width: | Height: | Size: 516 KiB |
@@ -0,0 +1,256 @@
|
||||
8.000000000000000000e+00 -3.000000000000000000e+00 9.000000000000000000e+00 5.000000000000000000e+00
|
||||
4.000000000000000000e+00 2.000000000000000000e+00 7.000000000000000000e+00 -1.200000000000000000e+01
|
||||
-1.100000000000000000e+01 9.000000000000000000e+00 -8.000000000000000000e+00 2.000000000000000000e+00
|
||||
7.000000000000000000e+00 -1.200000000000000000e+01 1.200000000000000000e+01 -1.300000000000000000e+01
|
||||
2.000000000000000000e+00 -1.300000000000000000e+01 2.000000000000000000e+00 1.200000000000000000e+01
|
||||
1.000000000000000000e+00 -7.000000000000000000e+00 1.000000000000000000e+00 6.000000000000000000e+00
|
||||
-2.000000000000000000e+00 -1.000000000000000000e+01 -2.000000000000000000e+00 -4.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -1.300000000000000000e+01 -1.100000000000000000e+01 -8.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -3.000000000000000000e+00 -1.200000000000000000e+01 -9.000000000000000000e+00
|
||||
1.000000000000000000e+01 4.000000000000000000e+00 1.100000000000000000e+01 9.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -8.000000000000000000e+00 -8.000000000000000000e+00 -9.000000000000000000e+00
|
||||
-1.100000000000000000e+01 7.000000000000000000e+00 -9.000000000000000000e+00 1.200000000000000000e+01
|
||||
7.000000000000000000e+00 7.000000000000000000e+00 1.200000000000000000e+01 6.000000000000000000e+00
|
||||
-4.000000000000000000e+00 -5.000000000000000000e+00 -3.000000000000000000e+00 0.000000000000000000e+00
|
||||
-1.300000000000000000e+01 2.000000000000000000e+00 -1.200000000000000000e+01 -3.000000000000000000e+00
|
||||
-9.000000000000000000e+00 0.000000000000000000e+00 -7.000000000000000000e+00 5.000000000000000000e+00
|
||||
1.200000000000000000e+01 -6.000000000000000000e+00 1.200000000000000000e+01 -1.000000000000000000e+00
|
||||
-3.000000000000000000e+00 6.000000000000000000e+00 -2.000000000000000000e+00 1.200000000000000000e+01
|
||||
-6.000000000000000000e+00 -1.300000000000000000e+01 -4.000000000000000000e+00 -8.000000000000000000e+00
|
||||
1.100000000000000000e+01 -1.300000000000000000e+01 1.200000000000000000e+01 -8.000000000000000000e+00
|
||||
4.000000000000000000e+00 7.000000000000000000e+00 5.000000000000000000e+00 1.000000000000000000e+00
|
||||
5.000000000000000000e+00 -3.000000000000000000e+00 1.000000000000000000e+01 -3.000000000000000000e+00
|
||||
3.000000000000000000e+00 -7.000000000000000000e+00 6.000000000000000000e+00 1.200000000000000000e+01
|
||||
-8.000000000000000000e+00 -7.000000000000000000e+00 -6.000000000000000000e+00 -2.000000000000000000e+00
|
||||
-2.000000000000000000e+00 1.100000000000000000e+01 -1.000000000000000000e+00 -1.000000000000000000e+01
|
||||
-1.300000000000000000e+01 1.200000000000000000e+01 -8.000000000000000000e+00 1.000000000000000000e+01
|
||||
-7.000000000000000000e+00 3.000000000000000000e+00 -5.000000000000000000e+00 -3.000000000000000000e+00
|
||||
-4.000000000000000000e+00 2.000000000000000000e+00 -3.000000000000000000e+00 7.000000000000000000e+00
|
||||
-1.000000000000000000e+01 -1.200000000000000000e+01 -6.000000000000000000e+00 1.100000000000000000e+01
|
||||
5.000000000000000000e+00 -1.200000000000000000e+01 6.000000000000000000e+00 -7.000000000000000000e+00
|
||||
5.000000000000000000e+00 -6.000000000000000000e+00 7.000000000000000000e+00 -1.000000000000000000e+00
|
||||
1.000000000000000000e+00 0.000000000000000000e+00 4.000000000000000000e+00 -5.000000000000000000e+00
|
||||
9.000000000000000000e+00 1.100000000000000000e+01 1.100000000000000000e+01 -1.300000000000000000e+01
|
||||
4.000000000000000000e+00 7.000000000000000000e+00 4.000000000000000000e+00 1.200000000000000000e+01
|
||||
2.000000000000000000e+00 -1.000000000000000000e+00 4.000000000000000000e+00 4.000000000000000000e+00
|
||||
-4.000000000000000000e+00 -1.200000000000000000e+01 -2.000000000000000000e+00 7.000000000000000000e+00
|
||||
-8.000000000000000000e+00 -5.000000000000000000e+00 -7.000000000000000000e+00 -1.000000000000000000e+01
|
||||
4.000000000000000000e+00 1.100000000000000000e+01 9.000000000000000000e+00 1.200000000000000000e+01
|
||||
0.000000000000000000e+00 -8.000000000000000000e+00 1.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-1.300000000000000000e+01 -2.000000000000000000e+00 -8.000000000000000000e+00 2.000000000000000000e+00
|
||||
-3.000000000000000000e+00 -2.000000000000000000e+00 -2.000000000000000000e+00 3.000000000000000000e+00
|
||||
-6.000000000000000000e+00 9.000000000000000000e+00 -4.000000000000000000e+00 -9.000000000000000000e+00
|
||||
8.000000000000000000e+00 1.200000000000000000e+01 1.000000000000000000e+01 7.000000000000000000e+00
|
||||
0.000000000000000000e+00 9.000000000000000000e+00 1.000000000000000000e+00 3.000000000000000000e+00
|
||||
7.000000000000000000e+00 -5.000000000000000000e+00 1.100000000000000000e+01 -1.000000000000000000e+01
|
||||
-1.300000000000000000e+01 -6.000000000000000000e+00 -1.100000000000000000e+01 0.000000000000000000e+00
|
||||
1.000000000000000000e+01 7.000000000000000000e+00 1.200000000000000000e+01 1.000000000000000000e+00
|
||||
-6.000000000000000000e+00 -3.000000000000000000e+00 -6.000000000000000000e+00 1.200000000000000000e+01
|
||||
1.000000000000000000e+01 -9.000000000000000000e+00 1.200000000000000000e+01 -4.000000000000000000e+00
|
||||
-1.300000000000000000e+01 8.000000000000000000e+00 -8.000000000000000000e+00 -1.200000000000000000e+01
|
||||
-1.300000000000000000e+01 0.000000000000000000e+00 -8.000000000000000000e+00 -4.000000000000000000e+00
|
||||
3.000000000000000000e+00 3.000000000000000000e+00 7.000000000000000000e+00 8.000000000000000000e+00
|
||||
5.000000000000000000e+00 7.000000000000000000e+00 1.000000000000000000e+01 -7.000000000000000000e+00
|
||||
-1.000000000000000000e+00 7.000000000000000000e+00 1.000000000000000000e+00 -1.200000000000000000e+01
|
||||
3.000000000000000000e+00 -1.000000000000000000e+01 5.000000000000000000e+00 6.000000000000000000e+00
|
||||
2.000000000000000000e+00 -4.000000000000000000e+00 3.000000000000000000e+00 -1.000000000000000000e+01
|
||||
-1.300000000000000000e+01 0.000000000000000000e+00 -1.300000000000000000e+01 5.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -7.000000000000000000e+00 -1.200000000000000000e+01 1.200000000000000000e+01
|
||||
-1.300000000000000000e+01 3.000000000000000000e+00 -1.100000000000000000e+01 8.000000000000000000e+00
|
||||
-7.000000000000000000e+00 1.200000000000000000e+01 -4.000000000000000000e+00 7.000000000000000000e+00
|
||||
6.000000000000000000e+00 -1.000000000000000000e+01 1.200000000000000000e+01 8.000000000000000000e+00
|
||||
-9.000000000000000000e+00 -1.000000000000000000e+00 -7.000000000000000000e+00 -6.000000000000000000e+00
|
||||
-2.000000000000000000e+00 -5.000000000000000000e+00 0.000000000000000000e+00 1.200000000000000000e+01
|
||||
-1.200000000000000000e+01 5.000000000000000000e+00 -7.000000000000000000e+00 5.000000000000000000e+00
|
||||
3.000000000000000000e+00 -1.000000000000000000e+01 8.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-7.000000000000000000e+00 -7.000000000000000000e+00 -4.000000000000000000e+00 5.000000000000000000e+00
|
||||
-3.000000000000000000e+00 -2.000000000000000000e+00 -1.000000000000000000e+00 -7.000000000000000000e+00
|
||||
2.000000000000000000e+00 9.000000000000000000e+00 5.000000000000000000e+00 -1.100000000000000000e+01
|
||||
-1.100000000000000000e+01 -1.300000000000000000e+01 -5.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-1.000000000000000000e+00 6.000000000000000000e+00 0.000000000000000000e+00 -1.000000000000000000e+00
|
||||
5.000000000000000000e+00 -3.000000000000000000e+00 5.000000000000000000e+00 2.000000000000000000e+00
|
||||
-4.000000000000000000e+00 -1.300000000000000000e+01 -4.000000000000000000e+00 1.200000000000000000e+01
|
||||
-9.000000000000000000e+00 -6.000000000000000000e+00 -9.000000000000000000e+00 6.000000000000000000e+00
|
||||
-1.200000000000000000e+01 -1.000000000000000000e+01 -8.000000000000000000e+00 -4.000000000000000000e+00
|
||||
1.000000000000000000e+01 2.000000000000000000e+00 1.200000000000000000e+01 -3.000000000000000000e+00
|
||||
7.000000000000000000e+00 1.200000000000000000e+01 1.200000000000000000e+01 1.200000000000000000e+01
|
||||
-7.000000000000000000e+00 -1.300000000000000000e+01 -6.000000000000000000e+00 5.000000000000000000e+00
|
||||
-4.000000000000000000e+00 9.000000000000000000e+00 -3.000000000000000000e+00 4.000000000000000000e+00
|
||||
7.000000000000000000e+00 -1.000000000000000000e+00 1.200000000000000000e+01 2.000000000000000000e+00
|
||||
-7.000000000000000000e+00 6.000000000000000000e+00 -5.000000000000000000e+00 1.000000000000000000e+00
|
||||
-1.300000000000000000e+01 1.100000000000000000e+01 -1.200000000000000000e+01 5.000000000000000000e+00
|
||||
-3.000000000000000000e+00 7.000000000000000000e+00 -2.000000000000000000e+00 -6.000000000000000000e+00
|
||||
7.000000000000000000e+00 -8.000000000000000000e+00 1.200000000000000000e+01 -7.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -7.000000000000000000e+00 -1.100000000000000000e+01 -1.200000000000000000e+01
|
||||
1.000000000000000000e+00 -3.000000000000000000e+00 1.200000000000000000e+01 1.200000000000000000e+01
|
||||
2.000000000000000000e+00 -6.000000000000000000e+00 3.000000000000000000e+00 0.000000000000000000e+00
|
||||
-4.000000000000000000e+00 3.000000000000000000e+00 -2.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-1.000000000000000000e+00 -1.300000000000000000e+01 1.000000000000000000e+00 9.000000000000000000e+00
|
||||
7.000000000000000000e+00 1.000000000000000000e+00 8.000000000000000000e+00 -6.000000000000000000e+00
|
||||
1.000000000000000000e+00 -1.000000000000000000e+00 3.000000000000000000e+00 1.200000000000000000e+01
|
||||
9.000000000000000000e+00 1.000000000000000000e+00 1.200000000000000000e+01 6.000000000000000000e+00
|
||||
-1.000000000000000000e+00 -9.000000000000000000e+00 -1.000000000000000000e+00 3.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -1.300000000000000000e+01 -1.000000000000000000e+01 5.000000000000000000e+00
|
||||
7.000000000000000000e+00 7.000000000000000000e+00 1.000000000000000000e+01 1.200000000000000000e+01
|
||||
1.200000000000000000e+01 -5.000000000000000000e+00 1.200000000000000000e+01 9.000000000000000000e+00
|
||||
6.000000000000000000e+00 3.000000000000000000e+00 7.000000000000000000e+00 1.100000000000000000e+01
|
||||
5.000000000000000000e+00 -1.300000000000000000e+01 6.000000000000000000e+00 1.000000000000000000e+01
|
||||
2.000000000000000000e+00 -1.200000000000000000e+01 2.000000000000000000e+00 3.000000000000000000e+00
|
||||
3.000000000000000000e+00 8.000000000000000000e+00 4.000000000000000000e+00 -6.000000000000000000e+00
|
||||
2.000000000000000000e+00 6.000000000000000000e+00 1.200000000000000000e+01 -1.300000000000000000e+01
|
||||
9.000000000000000000e+00 -1.200000000000000000e+01 1.000000000000000000e+01 3.000000000000000000e+00
|
||||
-8.000000000000000000e+00 4.000000000000000000e+00 -7.000000000000000000e+00 9.000000000000000000e+00
|
||||
-1.100000000000000000e+01 1.200000000000000000e+01 -4.000000000000000000e+00 -6.000000000000000000e+00
|
||||
1.000000000000000000e+00 1.200000000000000000e+01 2.000000000000000000e+00 -8.000000000000000000e+00
|
||||
6.000000000000000000e+00 -9.000000000000000000e+00 7.000000000000000000e+00 -4.000000000000000000e+00
|
||||
2.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 -2.000000000000000000e+00
|
||||
6.000000000000000000e+00 3.000000000000000000e+00 1.100000000000000000e+01 0.000000000000000000e+00
|
||||
3.000000000000000000e+00 -3.000000000000000000e+00 8.000000000000000000e+00 -8.000000000000000000e+00
|
||||
7.000000000000000000e+00 8.000000000000000000e+00 9.000000000000000000e+00 3.000000000000000000e+00
|
||||
-1.100000000000000000e+01 -5.000000000000000000e+00 -6.000000000000000000e+00 -4.000000000000000000e+00
|
||||
-1.000000000000000000e+01 1.100000000000000000e+01 -5.000000000000000000e+00 1.000000000000000000e+01
|
||||
-5.000000000000000000e+00 -8.000000000000000000e+00 -3.000000000000000000e+00 1.200000000000000000e+01
|
||||
-1.000000000000000000e+01 5.000000000000000000e+00 -9.000000000000000000e+00 0.000000000000000000e+00
|
||||
8.000000000000000000e+00 -1.000000000000000000e+00 1.200000000000000000e+01 -6.000000000000000000e+00
|
||||
4.000000000000000000e+00 -6.000000000000000000e+00 6.000000000000000000e+00 -1.100000000000000000e+01
|
||||
-1.000000000000000000e+01 1.200000000000000000e+01 -8.000000000000000000e+00 7.000000000000000000e+00
|
||||
4.000000000000000000e+00 -2.000000000000000000e+00 6.000000000000000000e+00 7.000000000000000000e+00
|
||||
-2.000000000000000000e+00 0.000000000000000000e+00 -2.000000000000000000e+00 1.200000000000000000e+01
|
||||
-5.000000000000000000e+00 -8.000000000000000000e+00 -5.000000000000000000e+00 2.000000000000000000e+00
|
||||
7.000000000000000000e+00 -6.000000000000000000e+00 1.000000000000000000e+01 1.200000000000000000e+01
|
||||
-9.000000000000000000e+00 -1.300000000000000000e+01 -8.000000000000000000e+00 -8.000000000000000000e+00
|
||||
-5.000000000000000000e+00 -1.300000000000000000e+01 -5.000000000000000000e+00 -2.000000000000000000e+00
|
||||
8.000000000000000000e+00 -8.000000000000000000e+00 9.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-9.000000000000000000e+00 -1.100000000000000000e+01 -9.000000000000000000e+00 0.000000000000000000e+00
|
||||
1.000000000000000000e+00 -8.000000000000000000e+00 1.000000000000000000e+00 -2.000000000000000000e+00
|
||||
7.000000000000000000e+00 -4.000000000000000000e+00 9.000000000000000000e+00 1.000000000000000000e+00
|
||||
-2.000000000000000000e+00 1.000000000000000000e+00 -1.000000000000000000e+00 -4.000000000000000000e+00
|
||||
1.100000000000000000e+01 -6.000000000000000000e+00 1.200000000000000000e+01 -1.100000000000000000e+01
|
||||
-1.200000000000000000e+01 -9.000000000000000000e+00 -6.000000000000000000e+00 4.000000000000000000e+00
|
||||
3.000000000000000000e+00 7.000000000000000000e+00 7.000000000000000000e+00 1.200000000000000000e+01
|
||||
5.000000000000000000e+00 5.000000000000000000e+00 1.000000000000000000e+01 8.000000000000000000e+00
|
||||
0.000000000000000000e+00 -4.000000000000000000e+00 2.000000000000000000e+00 8.000000000000000000e+00
|
||||
-9.000000000000000000e+00 1.200000000000000000e+01 -5.000000000000000000e+00 -1.300000000000000000e+01
|
||||
0.000000000000000000e+00 7.000000000000000000e+00 2.000000000000000000e+00 1.200000000000000000e+01
|
||||
-1.000000000000000000e+00 2.000000000000000000e+00 1.000000000000000000e+00 7.000000000000000000e+00
|
||||
5.000000000000000000e+00 1.100000000000000000e+01 7.000000000000000000e+00 -9.000000000000000000e+00
|
||||
3.000000000000000000e+00 5.000000000000000000e+00 6.000000000000000000e+00 -8.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -4.000000000000000000e+00 -8.000000000000000000e+00 9.000000000000000000e+00
|
||||
-5.000000000000000000e+00 9.000000000000000000e+00 -3.000000000000000000e+00 -3.000000000000000000e+00
|
||||
-4.000000000000000000e+00 -7.000000000000000000e+00 -3.000000000000000000e+00 -1.200000000000000000e+01
|
||||
6.000000000000000000e+00 5.000000000000000000e+00 8.000000000000000000e+00 0.000000000000000000e+00
|
||||
-7.000000000000000000e+00 6.000000000000000000e+00 -6.000000000000000000e+00 1.200000000000000000e+01
|
||||
-1.300000000000000000e+01 6.000000000000000000e+00 -5.000000000000000000e+00 -2.000000000000000000e+00
|
||||
1.000000000000000000e+00 -1.000000000000000000e+01 3.000000000000000000e+00 1.000000000000000000e+01
|
||||
4.000000000000000000e+00 1.000000000000000000e+00 8.000000000000000000e+00 -4.000000000000000000e+00
|
||||
-2.000000000000000000e+00 -2.000000000000000000e+00 2.000000000000000000e+00 -1.300000000000000000e+01
|
||||
2.000000000000000000e+00 -1.200000000000000000e+01 1.200000000000000000e+01 1.200000000000000000e+01
|
||||
-2.000000000000000000e+00 -1.300000000000000000e+01 0.000000000000000000e+00 -6.000000000000000000e+00
|
||||
4.000000000000000000e+00 1.000000000000000000e+00 9.000000000000000000e+00 3.000000000000000000e+00
|
||||
-6.000000000000000000e+00 -1.000000000000000000e+01 -3.000000000000000000e+00 -5.000000000000000000e+00
|
||||
-3.000000000000000000e+00 -1.300000000000000000e+01 -1.000000000000000000e+00 1.000000000000000000e+00
|
||||
7.000000000000000000e+00 5.000000000000000000e+00 1.200000000000000000e+01 -1.100000000000000000e+01
|
||||
4.000000000000000000e+00 -2.000000000000000000e+00 5.000000000000000000e+00 -7.000000000000000000e+00
|
||||
-1.300000000000000000e+01 9.000000000000000000e+00 -9.000000000000000000e+00 -5.000000000000000000e+00
|
||||
7.000000000000000000e+00 1.000000000000000000e+00 8.000000000000000000e+00 6.000000000000000000e+00
|
||||
7.000000000000000000e+00 -8.000000000000000000e+00 7.000000000000000000e+00 6.000000000000000000e+00
|
||||
-7.000000000000000000e+00 -4.000000000000000000e+00 -7.000000000000000000e+00 1.000000000000000000e+00
|
||||
-8.000000000000000000e+00 1.100000000000000000e+01 -7.000000000000000000e+00 -8.000000000000000000e+00
|
||||
-1.300000000000000000e+01 6.000000000000000000e+00 -1.200000000000000000e+01 -8.000000000000000000e+00
|
||||
2.000000000000000000e+00 4.000000000000000000e+00 3.000000000000000000e+00 9.000000000000000000e+00
|
||||
1.000000000000000000e+01 -5.000000000000000000e+00 1.200000000000000000e+01 3.000000000000000000e+00
|
||||
-6.000000000000000000e+00 -5.000000000000000000e+00 -6.000000000000000000e+00 7.000000000000000000e+00
|
||||
8.000000000000000000e+00 -3.000000000000000000e+00 9.000000000000000000e+00 -8.000000000000000000e+00
|
||||
2.000000000000000000e+00 -1.200000000000000000e+01 2.000000000000000000e+00 8.000000000000000000e+00
|
||||
-1.100000000000000000e+01 -2.000000000000000000e+00 -1.000000000000000000e+01 3.000000000000000000e+00
|
||||
-1.200000000000000000e+01 -1.300000000000000000e+01 -7.000000000000000000e+00 -9.000000000000000000e+00
|
||||
-1.100000000000000000e+01 0.000000000000000000e+00 -1.000000000000000000e+01 -5.000000000000000000e+00
|
||||
5.000000000000000000e+00 -3.000000000000000000e+00 1.100000000000000000e+01 8.000000000000000000e+00
|
||||
-2.000000000000000000e+00 -1.300000000000000000e+01 -1.000000000000000000e+00 1.200000000000000000e+01
|
||||
-1.000000000000000000e+00 -8.000000000000000000e+00 0.000000000000000000e+00 9.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -1.100000000000000000e+01 -1.200000000000000000e+01 -5.000000000000000000e+00
|
||||
-1.000000000000000000e+01 -2.000000000000000000e+00 -1.000000000000000000e+01 1.100000000000000000e+01
|
||||
-3.000000000000000000e+00 9.000000000000000000e+00 -2.000000000000000000e+00 -1.300000000000000000e+01
|
||||
2.000000000000000000e+00 -3.000000000000000000e+00 3.000000000000000000e+00 2.000000000000000000e+00
|
||||
-9.000000000000000000e+00 -1.300000000000000000e+01 -4.000000000000000000e+00 0.000000000000000000e+00
|
||||
-4.000000000000000000e+00 6.000000000000000000e+00 -3.000000000000000000e+00 -1.000000000000000000e+01
|
||||
-4.000000000000000000e+00 1.200000000000000000e+01 -2.000000000000000000e+00 -7.000000000000000000e+00
|
||||
-6.000000000000000000e+00 -1.100000000000000000e+01 -4.000000000000000000e+00 9.000000000000000000e+00
|
||||
6.000000000000000000e+00 -3.000000000000000000e+00 6.000000000000000000e+00 1.100000000000000000e+01
|
||||
-1.300000000000000000e+01 1.100000000000000000e+01 -5.000000000000000000e+00 5.000000000000000000e+00
|
||||
1.100000000000000000e+01 1.100000000000000000e+01 1.200000000000000000e+01 6.000000000000000000e+00
|
||||
7.000000000000000000e+00 -5.000000000000000000e+00 1.200000000000000000e+01 -2.000000000000000000e+00
|
||||
-1.000000000000000000e+00 1.200000000000000000e+01 0.000000000000000000e+00 7.000000000000000000e+00
|
||||
-4.000000000000000000e+00 -8.000000000000000000e+00 -3.000000000000000000e+00 -2.000000000000000000e+00
|
||||
-7.000000000000000000e+00 1.000000000000000000e+00 -6.000000000000000000e+00 7.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -1.200000000000000000e+01 -8.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-7.000000000000000000e+00 -2.000000000000000000e+00 -6.000000000000000000e+00 -8.000000000000000000e+00
|
||||
-8.000000000000000000e+00 5.000000000000000000e+00 -6.000000000000000000e+00 -9.000000000000000000e+00
|
||||
-5.000000000000000000e+00 -1.000000000000000000e+00 -4.000000000000000000e+00 5.000000000000000000e+00
|
||||
-1.300000000000000000e+01 7.000000000000000000e+00 -8.000000000000000000e+00 1.000000000000000000e+01
|
||||
1.000000000000000000e+00 5.000000000000000000e+00 5.000000000000000000e+00 -1.300000000000000000e+01
|
||||
1.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+01 -1.300000000000000000e+01
|
||||
9.000000000000000000e+00 1.200000000000000000e+01 1.000000000000000000e+01 -1.000000000000000000e+00
|
||||
5.000000000000000000e+00 -8.000000000000000000e+00 1.000000000000000000e+01 -9.000000000000000000e+00
|
||||
-1.000000000000000000e+00 1.100000000000000000e+01 1.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-9.000000000000000000e+00 -3.000000000000000000e+00 -6.000000000000000000e+00 2.000000000000000000e+00
|
||||
-1.000000000000000000e+00 -1.000000000000000000e+01 1.000000000000000000e+00 1.200000000000000000e+01
|
||||
-1.300000000000000000e+01 1.000000000000000000e+00 -8.000000000000000000e+00 -1.000000000000000000e+01
|
||||
8.000000000000000000e+00 -1.100000000000000000e+01 1.000000000000000000e+01 -6.000000000000000000e+00
|
||||
2.000000000000000000e+00 -1.300000000000000000e+01 3.000000000000000000e+00 -6.000000000000000000e+00
|
||||
7.000000000000000000e+00 -1.300000000000000000e+01 1.200000000000000000e+01 -9.000000000000000000e+00
|
||||
-1.000000000000000000e+01 -1.000000000000000000e+01 -5.000000000000000000e+00 -7.000000000000000000e+00
|
||||
-1.000000000000000000e+01 -8.000000000000000000e+00 -8.000000000000000000e+00 -1.300000000000000000e+01
|
||||
4.000000000000000000e+00 -6.000000000000000000e+00 8.000000000000000000e+00 5.000000000000000000e+00
|
||||
3.000000000000000000e+00 1.200000000000000000e+01 8.000000000000000000e+00 -1.300000000000000000e+01
|
||||
-4.000000000000000000e+00 2.000000000000000000e+00 -3.000000000000000000e+00 -3.000000000000000000e+00
|
||||
5.000000000000000000e+00 -1.300000000000000000e+01 1.000000000000000000e+01 -1.200000000000000000e+01
|
||||
4.000000000000000000e+00 -1.300000000000000000e+01 5.000000000000000000e+00 -1.000000000000000000e+00
|
||||
-9.000000000000000000e+00 9.000000000000000000e+00 -4.000000000000000000e+00 3.000000000000000000e+00
|
||||
0.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 -9.000000000000000000e+00
|
||||
-1.200000000000000000e+01 1.000000000000000000e+00 -6.000000000000000000e+00 1.000000000000000000e+00
|
||||
3.000000000000000000e+00 2.000000000000000000e+00 4.000000000000000000e+00 -8.000000000000000000e+00
|
||||
-1.000000000000000000e+01 -1.000000000000000000e+01 -1.000000000000000000e+01 9.000000000000000000e+00
|
||||
8.000000000000000000e+00 -1.300000000000000000e+01 1.200000000000000000e+01 1.200000000000000000e+01
|
||||
-8.000000000000000000e+00 -1.200000000000000000e+01 -6.000000000000000000e+00 -5.000000000000000000e+00
|
||||
2.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00 7.000000000000000000e+00
|
||||
1.000000000000000000e+01 6.000000000000000000e+00 1.100000000000000000e+01 -8.000000000000000000e+00
|
||||
6.000000000000000000e+00 8.000000000000000000e+00 8.000000000000000000e+00 -1.200000000000000000e+01
|
||||
-7.000000000000000000e+00 1.000000000000000000e+01 -6.000000000000000000e+00 5.000000000000000000e+00
|
||||
-3.000000000000000000e+00 -9.000000000000000000e+00 -3.000000000000000000e+00 9.000000000000000000e+00
|
||||
-1.000000000000000000e+00 -1.300000000000000000e+01 -1.000000000000000000e+00 5.000000000000000000e+00
|
||||
-3.000000000000000000e+00 -7.000000000000000000e+00 -3.000000000000000000e+00 4.000000000000000000e+00
|
||||
-8.000000000000000000e+00 -2.000000000000000000e+00 -8.000000000000000000e+00 3.000000000000000000e+00
|
||||
4.000000000000000000e+00 2.000000000000000000e+00 1.200000000000000000e+01 1.200000000000000000e+01
|
||||
2.000000000000000000e+00 -5.000000000000000000e+00 3.000000000000000000e+00 1.100000000000000000e+01
|
||||
6.000000000000000000e+00 -9.000000000000000000e+00 1.100000000000000000e+01 -1.300000000000000000e+01
|
||||
3.000000000000000000e+00 -1.000000000000000000e+00 7.000000000000000000e+00 1.200000000000000000e+01
|
||||
1.100000000000000000e+01 -1.000000000000000000e+00 1.200000000000000000e+01 4.000000000000000000e+00
|
||||
-3.000000000000000000e+00 0.000000000000000000e+00 -3.000000000000000000e+00 6.000000000000000000e+00
|
||||
4.000000000000000000e+00 -1.100000000000000000e+01 4.000000000000000000e+00 1.200000000000000000e+01
|
||||
2.000000000000000000e+00 -4.000000000000000000e+00 2.000000000000000000e+00 1.000000000000000000e+00
|
||||
-1.000000000000000000e+01 -6.000000000000000000e+00 -8.000000000000000000e+00 1.000000000000000000e+00
|
||||
-1.300000000000000000e+01 7.000000000000000000e+00 -1.100000000000000000e+01 1.000000000000000000e+00
|
||||
-1.300000000000000000e+01 1.200000000000000000e+01 -1.100000000000000000e+01 -1.300000000000000000e+01
|
||||
6.000000000000000000e+00 0.000000000000000000e+00 1.100000000000000000e+01 -1.300000000000000000e+01
|
||||
0.000000000000000000e+00 -1.000000000000000000e+00 1.000000000000000000e+00 4.000000000000000000e+00
|
||||
-1.300000000000000000e+01 3.000000000000000000e+00 -9.000000000000000000e+00 -2.000000000000000000e+00
|
||||
-9.000000000000000000e+00 8.000000000000000000e+00 -6.000000000000000000e+00 -3.000000000000000000e+00
|
||||
-1.300000000000000000e+01 -6.000000000000000000e+00 -8.000000000000000000e+00 -2.000000000000000000e+00
|
||||
5.000000000000000000e+00 -9.000000000000000000e+00 8.000000000000000000e+00 1.000000000000000000e+01
|
||||
2.000000000000000000e+00 7.000000000000000000e+00 3.000000000000000000e+00 -9.000000000000000000e+00
|
||||
-1.000000000000000000e+00 -6.000000000000000000e+00 -1.000000000000000000e+00 -1.000000000000000000e+00
|
||||
9.000000000000000000e+00 5.000000000000000000e+00 1.100000000000000000e+01 -2.000000000000000000e+00
|
||||
1.100000000000000000e+01 -3.000000000000000000e+00 1.200000000000000000e+01 -8.000000000000000000e+00
|
||||
3.000000000000000000e+00 0.000000000000000000e+00 3.000000000000000000e+00 5.000000000000000000e+00
|
||||
-1.000000000000000000e+00 4.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+01
|
||||
3.000000000000000000e+00 -6.000000000000000000e+00 4.000000000000000000e+00 5.000000000000000000e+00
|
||||
-1.300000000000000000e+01 0.000000000000000000e+00 -1.000000000000000000e+01 5.000000000000000000e+00
|
||||
5.000000000000000000e+00 8.000000000000000000e+00 1.200000000000000000e+01 1.100000000000000000e+01
|
||||
8.000000000000000000e+00 9.000000000000000000e+00 9.000000000000000000e+00 -6.000000000000000000e+00
|
||||
7.000000000000000000e+00 -4.000000000000000000e+00 8.000000000000000000e+00 -1.200000000000000000e+01
|
||||
-1.000000000000000000e+01 4.000000000000000000e+00 -1.000000000000000000e+01 9.000000000000000000e+00
|
||||
7.000000000000000000e+00 3.000000000000000000e+00 1.200000000000000000e+01 4.000000000000000000e+00
|
||||
9.000000000000000000e+00 -7.000000000000000000e+00 1.000000000000000000e+01 -2.000000000000000000e+00
|
||||
7.000000000000000000e+00 0.000000000000000000e+00 1.200000000000000000e+01 -2.000000000000000000e+00
|
||||
-1.000000000000000000e+00 -6.000000000000000000e+00 0.000000000000000000e+00 -1.100000000000000000e+01
|
||||
@@ -60,7 +60,7 @@ def ellipse(cy, cx, yradius, xradius, shape=None):
|
||||
cc += cx - xradius
|
||||
|
||||
if shape is not None:
|
||||
_coords_inside_image(rr, cc, shape)
|
||||
return _coords_inside_image(rr, cc, shape)
|
||||
|
||||
return rr, cc
|
||||
|
||||
|
||||
@@ -325,6 +325,33 @@ def test_ellipse():
|
||||
assert_array_equal(img, img_)
|
||||
|
||||
|
||||
def test_ellipse_with_shape():
|
||||
img = np.zeros((15, 15), 'uint8')
|
||||
|
||||
rr, cc = ellipse(7, 7, 3, 10, shape=img.shape)
|
||||
img[rr, cc] = 1
|
||||
|
||||
img_ = np.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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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]]
|
||||
)
|
||||
|
||||
assert_array_equal(img, img_)
|
||||
|
||||
|
||||
def test_ellipse_perimeter_dot_zeroangle():
|
||||
# dot, angle == 0
|
||||
img = np.zeros((30, 15), 'uint8')
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
import numpy as np
|
||||
from numpy.testing import assert_array_equal, assert_allclose
|
||||
from nose.tools import raises
|
||||
|
||||
from skimage.draw import ellipsoid, ellipsoid_stats
|
||||
|
||||
|
||||
@raises(ValueError)
|
||||
def test_ellipsoid_sign_parameters1():
|
||||
ellipsoid(-1, 2, 2)
|
||||
|
||||
|
||||
@raises(ValueError)
|
||||
def test_ellipsoid_sign_parameters2():
|
||||
ellipsoid(0, 2, 2)
|
||||
|
||||
|
||||
@raises(ValueError)
|
||||
def test_ellipsoid_sign_parameters3():
|
||||
ellipsoid(-3, -2, 2)
|
||||
|
||||
|
||||
def test_ellipsoid_bool():
|
||||
test = ellipsoid(2, 2, 2)[1:-1, 1:-1, 1:-1]
|
||||
test_anisotropic = ellipsoid(2, 2, 4, spacing=(1., 1., 2.))
|
||||
@@ -86,18 +102,18 @@ def test_ellipsoid_levelset():
|
||||
def test_ellipsoid_stats():
|
||||
# Test comparison values generated by Wolfram Alpha
|
||||
vol, surf = ellipsoid_stats(6, 10, 16)
|
||||
assert(round(1280 * np.pi, 4) == round(vol, 4))
|
||||
assert(1383.28 == round(surf, 2))
|
||||
assert_allclose(1280 * np.pi, vol, atol=1e-4)
|
||||
assert_allclose(1383.28, surf, atol=1e-2)
|
||||
|
||||
# Test when a <= b <= c does not hold
|
||||
vol, surf = ellipsoid_stats(16, 6, 10)
|
||||
assert(round(1280 * np.pi, 4) == round(vol, 4))
|
||||
assert(1383.28 == round(surf, 2))
|
||||
assert_allclose(1280 * np.pi, vol, atol=1e-4)
|
||||
assert_allclose(1383.28, surf, atol=1e-2)
|
||||
|
||||
# Larger test to ensure reliability over broad range
|
||||
vol, surf = ellipsoid_stats(17, 27, 169)
|
||||
assert(round(103428 * np.pi, 4) == round(vol, 4))
|
||||
assert(37426.3 == round(surf, 1))
|
||||
assert_allclose(103428 * np.pi, vol, atol=1e-4)
|
||||
assert_allclose(37426.3, surf, atol=1e-1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from .exposure import histogram, equalize, equalize_hist, \
|
||||
from .exposure import histogram, equalize_hist, \
|
||||
rescale_intensity, cumulative_distribution, \
|
||||
adjust_gamma, adjust_sigmoid, adjust_log
|
||||
|
||||
from ._adapthist import equalize_adapthist
|
||||
|
||||
|
||||
__all__ = ['histogram',
|
||||
'equalize',
|
||||
'equalize_hist',
|
||||
'equalize_adapthist',
|
||||
'rescale_intensity',
|
||||
|
||||
@@ -126,8 +126,8 @@ def _clahe(image, ntiles_x, ntiles_y, clip_limit, nbins=128):
|
||||
x_res = image.shape[1] - image.shape[1] % ntiles_x
|
||||
image = image[: y_res, : x_res]
|
||||
|
||||
x_size = image.shape[1] / ntiles_x # Actual size of contextual regions
|
||||
y_size = image.shape[0] / ntiles_y
|
||||
x_size = image.shape[1] // ntiles_x # Actual size of contextual regions
|
||||
y_size = image.shape[0] // ntiles_y
|
||||
n_pixels = x_size * y_size
|
||||
|
||||
if clip_limit > 0.0: # Calculate actual cliplimit
|
||||
@@ -139,7 +139,7 @@ def _clahe(image, ntiles_x, ntiles_y, clip_limit, nbins=128):
|
||||
|
||||
bin_size = 1 + NR_OF_GREY / nbins
|
||||
aLUT = np.arange(NR_OF_GREY)
|
||||
aLUT /= bin_size
|
||||
aLUT //= bin_size
|
||||
img_blocks = view_as_blocks(image, (y_size, x_size))
|
||||
|
||||
# Calculate greylevel mappings for each contextual region
|
||||
@@ -315,7 +315,8 @@ def interpolate(image, xslice, yslice,
|
||||
np.arange(yslice.size))
|
||||
x_inv_coef, y_inv_coef = x_coef[:, ::-1] + 1, y_coef[::-1] + 1
|
||||
|
||||
view = image[yslice[0]: yslice[-1] + 1, xslice[0]: xslice[-1] + 1]
|
||||
view = image[int(yslice[0]):int(yslice[-1] + 1),
|
||||
int(xslice[0]):int(xslice[-1] + 1)]
|
||||
im_slice = aLUT[view]
|
||||
new = ((y_inv_coef * (x_inv_coef * mapLU[im_slice]
|
||||
+ x_coef * mapRU[im_slice])
|
||||
|
||||
@@ -7,14 +7,21 @@ from skimage._shared.utils import deprecated
|
||||
|
||||
|
||||
__all__ = ['histogram', 'cumulative_distribution', 'equalize',
|
||||
'rescale_intensity', 'adjust_gamma',
|
||||
'adjust_log', 'adjust_sigmoid']
|
||||
'rescale_intensity', 'adjust_gamma', 'adjust_log', 'adjust_sigmoid']
|
||||
|
||||
|
||||
DTYPE_RANGE = dtype_range.copy()
|
||||
DTYPE_RANGE.update((d.__name__, limits) for d, limits in dtype_range.items())
|
||||
DTYPE_RANGE.update({'uint10': (0, 2**10 - 1),
|
||||
'uint12': (0, 2**12 - 1),
|
||||
'uint14': (0, 2**14 - 1),
|
||||
'bool': dtype_range[np.bool_],
|
||||
'float': dtype_range[np.float64]})
|
||||
|
||||
|
||||
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 +47,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:
|
||||
@@ -97,11 +105,6 @@ def cumulative_distribution(image, nbins=256):
|
||||
return img_cdf, bin_centers
|
||||
|
||||
|
||||
@deprecated('equalize_hist')
|
||||
def equalize(image, nbins=256):
|
||||
return equalize_hist(image, nbins)
|
||||
|
||||
|
||||
def equalize_hist(image, nbins=256):
|
||||
"""Return image after histogram equalization.
|
||||
|
||||
@@ -143,14 +146,15 @@ def rescale_intensity(image, in_range=None, out_range=None):
|
||||
----------
|
||||
image : array
|
||||
Image array.
|
||||
in_range : 2-tuple (float, float)
|
||||
in_range : 2-tuple (float, float) or str
|
||||
Min and max *allowed* intensity values of input image. If None, the
|
||||
*allowed* min/max values are set to the *actual* min/max values in the
|
||||
input image.
|
||||
out_range : 2-tuple (float, float)
|
||||
input image. Intensity values outside this range are clipped.
|
||||
If string, use data limits of dtype specified by the string.
|
||||
out_range : 2-tuple (float, float) or str
|
||||
Min and max intensity values of output image. If None, use the min/max
|
||||
intensities of the image data type. See `skimage.util.dtype` for
|
||||
details.
|
||||
details. If string, use data limits of dtype specified by the string.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -201,11 +205,14 @@ def rescale_intensity(image, in_range=None, out_range=None):
|
||||
if in_range is None:
|
||||
imin = np.min(image)
|
||||
imax = np.max(image)
|
||||
elif in_range in DTYPE_RANGE:
|
||||
imin, imax = DTYPE_RANGE[in_range]
|
||||
else:
|
||||
imin, imax = in_range
|
||||
|
||||
if out_range is None:
|
||||
omin, omax = dtype_range[dtype]
|
||||
if out_range is None or out_range in DTYPE_RANGE:
|
||||
out_range = dtype if out_range is None else out_range
|
||||
omin, omax = DTYPE_RANGE[out_range]
|
||||
if imin >= 0:
|
||||
omin = 0
|
||||
else:
|
||||
@@ -263,7 +270,7 @@ def adjust_gamma(image, gamma=1, gain=1):
|
||||
dtype = image.dtype.type
|
||||
|
||||
if gamma < 0:
|
||||
return "Gamma should be a non-negative real number"
|
||||
raise ValueError("Gamma should be a non-negative real number.")
|
||||
|
||||
scale = float(dtype_limits(image, True)[1] - dtype_limits(image, True)[0])
|
||||
|
||||
@@ -339,7 +346,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)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
|
||||
from skimage._build import cython
|
||||
|
||||
base_path = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def configuration(parent_package='', top_path=None):
|
||||
from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs
|
||||
|
||||
config = Configuration('exposure', parent_package, top_path)
|
||||
config.add_data_dir('tests')
|
||||
|
||||
return config
|
||||
|
||||
if __name__ == '__main__':
|
||||
from numpy.distutils.core import setup
|
||||
setup(maintainer='scikit-image Developers',
|
||||
author='scikit-image Developers',
|
||||
maintainer_email='scikit-image@googlegroups.com',
|
||||
description='Exposure corrections',
|
||||
url='https://github.com/scikit-image/scikit-image',
|
||||
license='SciPy License (BSD Style)',
|
||||
**(configuration(top_path='').todict())
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user