Fix setup merge conflict

This commit is contained in:
Johannes Schönberger
2013-03-04 21:46:52 +01:00
340 changed files with 21485 additions and 5483 deletions
+2 -1
View File
@@ -22,4 +22,5 @@ doc/source/auto_examples/images/plot_*.png
doc/source/auto_examples/images/thumb
doc/source/auto_examples/applications/
doc/source/_static/random.js
.idea/
*.log
+29
View File
@@ -0,0 +1,29 @@
# vim ft=yaml
# travis-ci.org definition for skimage build
#
# We pretend to be erlang because we need 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
- sudo apt-get install $PYTHON-numpy
- sudo apt-get install $PYTHON-scipy
- sudo apt-get install $PYTHON-setuptools
- sudo apt-get install $PYTHON-nose
- sudo easy_install$PYSUF pip
- sudo pip-$PYVER install cython
- sudo apt-get install libfreeimage3
- $PYTHON setup.py build
- sudo $PYTHON setup.py install
script:
# Change into an innocuous directory and find tests from installation
- mkdir for_test
- cd for_test
- nosetests-$PYVER --exe -v --cover-package=skimage skimage
+35 -6
View File
@@ -2,9 +2,9 @@
Project coordination
- Nicolas Pinto
Colour spaces and filters.
Colour spaces and filters, and image resizing.
Shape views: ``util.shape.view_as_windows`` and ``util.shape.view_as_blocks``
Montage helpers: ``util.montage``
Montage helpers: ``util.montage``.
- Damian Eads
Morphological operators
@@ -73,7 +73,8 @@
From whom we borrowed the example generation tools.
- Andreas Mueller
Example data set loader.
Example data set loader. Nosetest compatibility functions.
Quickshift image segmentation, Felzenszwalbs fast graph based segmentation.
- Yaroslav Halchenko
For sharing his expert advice on Debian packaging.
@@ -102,8 +103,36 @@
- Nicolas Poilvert
Shape views: ``util.shape.view_as_windows`` and ``util.shape.view_as_blocks``
Image resizing.
- Johannes Schönberger
Polygon, circle and ellipse drawing functions
Adaptive thresholding
Implementation of Matlab's `regionprops`
Drawing functions, adaptive thresholding, regionprops, geometric
transformations, LBPs, polygon approximations, web layout, and more.
- Pavel Campr
Fixes and tests for Histograms of Oriented Gradients.
- Joshua Warner
Multichannel random walker segmentation.
- Petter Strandmark
Perimeter calculation in regionprops.
- Olivier Debeir
Rank filters (8- and 16-bits) using sliding window.
- Luis Pedro Coelho
imread plugin
- Steven Silvester, Karel Zuiderveld
Adaptive Histogram Equalization
- Anders Boesen Lindbo Larsen
Dense DAISY feature description, circle perimeter drawing.
- François Boulogne
Andres Method for circle perimeter, ellipse perimeter drawing.
Circular Hough Transform
- Thouis Jones
Vectorized operators for arrays of 16-bit ints.
+5 -1
View File
@@ -4,10 +4,13 @@ Build Requirements
* `Numpy >= 1.6 <http://numpy.scipy.org/>`__
* `Cython >= 0.15 <http://www.cython.org/>`__
`Matplotlib >= 1.0 <http://matplotlib.sf.net>`__ is needed to generate the
examples in the documentation.
Runtime requirements
--------------------
* `SciPy >= 0.10 <http://scipy.org>`__
Known build errors
------------------
On Windows, the error ``Error:unable to find vcvarsall.bat`` means that
@@ -34,3 +37,4 @@ functionality is only available with the following installed:
`FreeImage <http://freeimage.sf.net>`__
The ``freeimage`` plugin provides support for reading various types of
image file formats, including multi-page TIFFs.
+69 -25
View File
@@ -1,51 +1,94 @@
Development process
-------------------
:doc:`Read this overview <gitwash/index>` of how to use Git with
``skimage``. Here's the long and short of it:
Here's the long and short of it:
* Go to `https://github.com/scikits-image/scikits-image
<http://github.com/scikits-image/scikits-image>`_ and follow the
* Go to `https://github.com/scikit-image/scikit-image
<http://github.com/scikit-image/scikit-image>`_ and follow the
instructions on making your own fork.
* Create a new branch for the feature you want to work on. Since the
branch name will appear in the merge message, use a sensible name
such as 'your_name-transform-speedups'.
such as 'transform-speedups'.
* Commit locally as you progress.
* Push your changes back to github and create a pull request by
clicking "request pull" in GitHub.
* Optionally, mail the mailing list, explaining your changes.
* Push your changes back to GitHub and create a Pull Request by
clicking 'Pull Request' in GitHub.
* Optionally, post on the `mailing list <http://groups.google.com/group/scikit-image>`_ to explain your changes.
Read these :doc:`detailed documents <gitwash/index>` on how to use Git with
``scikit-image`` (`<http://scikit-image.org/docs/dev/gitwash/index.html>`_).
.. note::
Do *not* merge the main branch into yours. If GitHub indicates that the
Pull Request can no longer be merged automatically, rebase onto master.
(If you are curious, here's a further discussion on
the `dangers of rebasing <http://tinyurl.com/lll385>`__. Also
see this `LWN article <http://tinyurl.com/nqcbkj>`__.)
* To reviewers: add a short explanation of what a branch did to the merge
message or, if closing a bug, add "Closes gh-XXXX".
You may also read this summary by Fernando Perez of the IPython
project on how they manage to keep review overhead to a minimum:
http://mail.scipy.org/pipermail/ipython-dev/2010-October/006746.html
.. note::
Do *not* merge the main branch into yours. You may rebase,
as long as you are `aware of its dangers <http://tinyurl.com/lll385>`_
(also see `LWN article <http://tinyurl.com/nqcbkj>`_).
* To reviewers: add a short explanation of what a branch did to the merge
message or, if closing a bug, add "Closes gh-XXXX".
Guidelines
``````````
* All code should have tests (see "Test coverage" below for more details).
----------
* All code should have tests (see `test coverage`_ below for more details).
* All code should be documented, to the same
`standard <http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines>`_
as NumPy and SciPy. If possible, also add a section to the user guide.
as NumPy and SciPy. For new functionality, always add an example to the
gallery.
* Follow the `Python PEPs <http://www.python.org/dev/peps/pep-0008/>`_
where possible.
* No major changes should be committed without review. Ask on the
`mailing list <http://groups.google.com/group/scikits-image>`_ if
`mailing list <http://groups.google.com/group/scikit-image>`_ if
you get no response to your pull request.
* Examples in the gallery should have a maximum figure width of 8 inches.
Stylistic Guidelines
--------------------
* Use numpy data types instead of strings (``np.uint8`` instead of
``"uint8"``).
* Use the following import conventions::
import numpy as np
import matplotlib.pyplot as plt
cimport numpy as cnp # in Cython code
* When documenting array parameters, use ``image : (M, N) ndarray``,
``image : (M, N, 3) ndarray`` and then refer to ``M`` and ``N`` in the
docstring.
* Set up your editor to remove trailing whitespace. Follow `PEP08
<www.python.org/dev/peps/pep-0008/>`__. Check code with pyflakes / flake8.
* If a function name, say ``segment(...)``, has the same name as the file in
which it is implemented, name that file ``_segment.py`` so that it can still
be imported. All Cython files start with an underscore, e.g.
``_some_module.pyx``.
* Functions should support all input image dtypes. Use utility functions such
as ``img_as_float`` to help convert to an appropriate type. The output
format can be whatever is most efficient. This allows us to string together
several functions into a pipeline, e.g.::
hough(canny(my_image))
* Use `Py_ssize_t` as data type for all indexing, shape and size variables in
C/C++ and Cython code.
Test coverage
`````````````
-------------
Tests for a module should ideally cover all code in that module,
i.e. statement coverage should be at 100%.
i.e., statement coverage should be at 100%.
To measure the test coverage, install
`coverage.py <http://nedbatchelder.com/code/coverage/>`__
@@ -63,5 +106,6 @@ detailing the test coverage::
...
Bugs
````
Please `report bugs on Github <https://github.com/scikits-image/scikits-image/issues>`_.
----
Please `report bugs on GitHub <https://github.com/scikit-image/scikit-image/issues>`_.
+1 -1
View File
@@ -1,7 +1,7 @@
Unless otherwise specified by LICENSE.txt files in individual
directories, all code is
Copyright (C) 2011, the scikits-image team
Copyright (C) 2011, the scikit-image team
All rights reserved.
Redistribution and use in source and binary forms, with or without
+2 -7
View File
@@ -3,11 +3,11 @@ Image Processing SciKit
Source
------
https://github.com/scikits-image/scikits-image
https://github.com/scikit-image/scikit-image
Mailing List
------------
http://groups.google.com/group/scikits-image
http://groups.google.com/group/scikit-image
Installation from source
------------------------
@@ -29,8 +29,3 @@ this path to your PYTHONPATH variable and compiling the extensions:
License
-------
Please read LICENSE.txt in this directory.
Contact
-------
Stefan van der Walt <stefan at sun.ac.za>
+72 -13
View File
@@ -2,30 +2,89 @@ How to make a new release of ``skimage``
========================================
- Update release notes.
- Update the version number in setup.py and bento.info and commit
- To show a list contributors, run ``doc/release/contributors.sh <commit>``,
where ``<commit>`` is the first commit since the previous release.
- Update the version number in ``setup.py`` and ``bento.info`` and commit
- Update the docs:
- Edit ``doc/source/themes/agogo/static/docversions.js`` and commit
- Build a clean version of the docs. Run "make" in the root dir, then
``rm build -rf; make html`` in the docs.
- Push upstream using "make gh-pages"
- Build a clean version of the docs. Run ``make`` 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!
- Build using ``make gh-pages``.
- Push upstream: ``git push`` in ``doc/gh-pages``.
- Add the version number as a tag in git::
git tag v0.6
git tag v0.X.0
- Push the new meta-data to github::
git push --tags origin master
git push --tags origin master
- Publish on PyPi:
- Publish on PyPi::
python setup.py register
python setup.py sdist upload
python setup.py register
python setup.py sdist upload
- Increase the version number in the setup.py file to ``0.Xdev``.
- Increase the version number
- In ``setup.py``, set to ``0.Xdev``.
- In ``bento.info``, set to ``0.X.dev0``.
- Update the web frontpage:
The webpage is kept in a separate repo: scikits-image-web
- ``_templates/sidebar_versions.html``
- ``index.rst``
The webpage is kept in a separate repo: scikit-image-web
- Sync your branch with the remote repo: ``git pull``.
If you try to ``make gh-pages`` when your branch is out of sync, it
creates headaches.
- Update stable and development version numbers in
``_templates/sidebar_versions.html``.
- Add release date to ``index.rst`` under "Announcements".
- Build using ``make gh-pages``.
- Push upstream: ``git push`` in ``gh-pages``.
- Post release notes on mailing lists, blog, G+, etc.
Debian
------
- Tag the release as per instructions above.
- git checkout debian
- git merge v0.x.x
- uscan <- not sure if this step is necessary
- Update changelog (emacs has a good mode, requires package dpkg-dev-el)
- C-C C-v add new version, C-c C-c timestamp / save
- git commit -m 'Changelog entry for 0.x.x'
- git-buildpackage -uc -us -rfakeroot
- Sign the changes: debsign skimage_0.x.x-x_amd64.changes
- cd ../build-area && dput mentors skimage_0.x.x-x_amd64.changes
- The package should now be available at:
http://mentors.debian.net/package/skimage
For the last lines above to work, you need ``~/.gbp.conf``::
[DEFAULT]
upstream-tag = %(version)s
[git-buildpackage]
sign-tags = True
export-dir = ../build-area/
tarball-dir = ../tarballs/
As well as ``~/dput.cf``::
[mentors]
fqdn = mentors.debian.net
incoming = /upload
method = http
allow_unsigned_uploads = 0
progress_indicator = 2
# Allow uploads for UNRELEASED packages
allowed_distributions = .*
+6 -102
View File
@@ -1,5 +1,6 @@
.. role:: strike
.. _howto_contribute:
How to contribute to ``skimage``
@@ -14,112 +15,15 @@ How to contribute to ``skimage``
cell_profiler
Developing Open Source is great fun! Join us on the `skimage mailing
list <http://groups.google.com/group/scikits-image>`_ and tell us which of the
Developing Open Source is great fun! Join us on the `scikit-image mailing
list <http://groups.google.com/group/scikit-image>`_ and tell us which of the
following challenges you'd like to solve.
* Mentoring is available for those new to scientific programming in Python.
* The technical detail of the `development process`_ is given below.
* :doc:`How to use GitHub <gitwash/index>` when developing skimage
* If you're looking for something to implement, you can find a list of `requested features on GitHub <https://github.com/scikit-image/scikit-image/wiki/Requested-features>`__. In addition, you can browse the `open issues on GitHub <https://github.com/scikit-image/scikit-image/issues?state=open>`__.
* The technical detail of the `development process`_ is summed up below.
Refer to the :doc:`gitwash <gitwash/index>` for a step-by-step tutorial.
.. contents::
:local:
Tasks
-----
.. :doc:`gsoc2011`
.. :doc:`coverage_table`
Implement Algorithms
````````````````````
- Graph cut segmentation
- `Image colorization <http://www.cs.huji.ac.il/~yweiss/Colorization/>`__
- Fast 2D convex hull (consider using CellProfiler version)
`Algorithm overview <http://www.tcs.fudan.edu.cn/rudolf/Courses/Algorithms/Alg_cs_07w/Webprojects/Zhaobo_hull/index.html#section26>`__.
`One free implementation
<http://cm.bell-labs.com/cm/cs/who/clarkson/2dch.c>`_.
[Compare against current implementation]
- Convex hulls of objects in a labels matrix (simply adapt current convex hull
image code--this one's low hanging fruit). Generalise this solution to also
skeletonize objects in a labels matrix.
Drawing (directly on an ndarray)
````````````````````````````````
- Wu's algorithm for circles
- Text rendering
Infrastructure
--------------
- :strike:`Implement a new backend system so that we may start including
PyOpenCL-based algorithms`
Adapt existing code for use
```````````````````````````
These snippets and packages have already been written. Some need to be
modified to work as part of the scikit, others may be lacking in documentation
or tests.
* :strike:`Connected components`
* Nadav's bilateral filtering (first compare against CellProfiler's
code, based on http://groups.csail.mit.edu/graphics/bilagrid/bilagrid_web.pdf)
Also see https://github.com/stefanv/scikits-image/tree/bilateral
* 2D image warping via thin-plate splines [ask Zach Pincus]
Merge code provided by `CellProfiler <http://www.cellprofiler.org>`_ team
`````````````````````````````````````````````````````````````````````````
* Roberts filter - convolution with diagonal and anti-diagonal
kernels to detect edges
* Minimum enclosing circles of objects in a labels matrix
* spur removal, thinning, thickening, and other morphological operations on
binary images, framework for creating arbitrary morphological operations
using a 3x3 grid.
Their SVN repository is read-accessible at
- https://svn.broadinstitute.org/CellProfiler/trunk/CellProfiler/cellprofiler
The files for the above algorithms are
- https://svn.broadinstitute.org/CellProfiler/trunk/CellProfiler/cellprofiler/cpmath/cpmorphology.py
- https://svn.broadinstitute.org/CellProfiler/trunk/CellProfiler/cellprofiler/cpmath/filter.py
There are test suites for the files at
- https://svn.broadinstitute.org/CellProfiler/trunk/CellProfiler/cellprofiler/cpmath/tests/test_cpmorphology.py
- https://svn.broadinstitute.org/CellProfiler/trunk/CellProfiler/cellprofiler/cpmath/tests/test_filter.py
Quoting a message from Lee Kamentsky to Stefan van der Walt sent on
5 August 2009::
We're part of the Broad Institute which is non-profit. We would be happy
to include our algorithm code in SciPy under the BSD license since that is
more appropriate for a library that might be integrated into a
commercial product whereas CellProfiler needs the more stringent
protection of GPL as an application.
In 2010, Vebjorn Ljosa officially released parts of the code under a
BSD license (:doc:`cell_profiler` | `original message
<http://groups.google.com/group/scikits-image/browse_thread/thread/c4f8fc584bfd839d>`_).
Thanks to Lee Kamentsky, Thouis Jones and Anne Carpenter and their colleagues
who contributed.
Rework linear filters
`````````````````````
* Fast, SSE2 convolution (high priority) (see prototype in pull requests)
* Should take kernel or function for parameter (currently only takes function)
* Kernel shape should be specifiable (currently defaults to image shape)
io
``
* Update ``qt_plugin.py`` and other plugins to view collections.
* Rewrite GTK backend using GObject Introspection for Py3K compatibility.
* Add DICOM plugin for `GDCM <http://sourceforge.net/apps/mediawiki/gdcm>`__.
docs
````
* Add examples to the gallery
* Write topics for the `user guide
<http://scikits-image.org/docs/dev/user_guide.html>`_
* Integrate BiBTeX plugin into Sphinx build
+71 -14
View File
@@ -1,15 +1,15 @@
Name: scikits-image
Version: 0.6
Name: scikit-image
Version: 0.8.0
Summary: Image processing routines for SciPy
Url: http://scikits-image.org
DownloadUrl: http://github.com/scikits-image/scikits-image
Url: http://scikit-image.org
DownloadUrl: http://github.com/scikit-image/scikit-image
Description: Image Processing SciKit
Image processing algorithms for SciPy, including IO, morphology, filtering,
warping, color manipulation, object detection, etc.
Please refer to the online documentation at
http://scikits-image.org/
http://scikit-image.org/
Maintainer: Stefan van der Walt
MaintainerEmail: stefan@sun.ac.za
License: Modified BSD
@@ -40,9 +40,6 @@ Library:
Extension: skimage.morphology._pnpoly
Sources:
skimage/morphology/_pnpoly.pyx
Extension: skimage.feature._greycomatrix
Sources:
skimage/feature/_greycomatrix.pyx
Extension: skimage.feature._template
Sources:
skimage/feature/_template.pyx
@@ -67,6 +64,9 @@ Library:
Extension: skimage.filter._ctmf
Sources:
skimage/filter/_ctmf.pyx
Extension: skimage.filter._denoise_cy
Sources:
skimage/filter/_denoise_cy.pyx
Extension: skimage.morphology.ccomp
Sources:
skimage/morphology/ccomp.pyx
@@ -76,15 +76,9 @@ Library:
Extension: skimage.morphology._convex_hull
Sources:
skimage/morphology/_convex_hull.pyx
Extension: skimage.morphology._skeletonize
Sources:
skimage/morphology/_skeletonize.pyx
Extension: skimage.draw._draw
Sources:
skimage/draw/_draw.pyx
Extension: skimage.transform._project
Sources:
skimage/transform/_project.pyx
Extension: skimage.graph._spath
Sources:
skimage/graph/_spath.pyx
@@ -94,6 +88,69 @@ Library:
Extension: skimage.graph.heap
Sources:
skimage/graph/heap.pyx
Extension: skimage.morphology._greyreconstruct
Sources:
skimage/morphology/_greyreconstruct.pyx
Extension: skimage.feature.corner_cy
Sources:
skimage/feature/corner_cy.pyx
Extension: skimage.feature._texture
Sources:
skimage/feature/_texture.pyx
Extension: skimage._shared.transform
Sources:
skimage/_shared/transform.pyx
Extension: skimage.segmentation._slic
Sources:
skimage/segmentation/_slic.pyx
Extension: skimage.segmentation._quickshift
Sources:
skimage/segmentation/_quickshift.pyx
Extension: skimage.morphology._skeletonize_cy
Sources:
skimage/morphology/_skeletonize_cy.pyx
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
Extension: skimage._shared.geometry
Sources:
skimage/_shared/geometry.pyx
Extension: skimage.filter.rank._core16
Sources:
skimage/filter/rank/_core16.pyx
Extension: skimage.filter.rank._crank8
Sources:
skimage/filter/rank/_crank8.pyx
Extension: skimage.filter.rank._crank16
Sources:
skimage/filter/rank/_crank16.pyx
Extension: skimage.filter.rank._core8
Sources:
skimage/filter/rank/_core8.pyx
Extension: skimage.filter.rank.rank
Sources:
skimage/filter/rank/rank.pyx
Extension: skimage.filter.rank.bilateral_rank
Sources:
skimage/filter/rank/bilateral_rank.pyx
Extension: skimage.filter.rank._crank16_percentiles
Sources:
skimage/filter/rank/_crank16_percentiles.pyx
Extension: skimage.filter.rank.percentile_rank
Sources:
skimage/filter/rank/percentile_rank.pyx
Extension: skimage.filter.rank._crank8_percentiles
Sources:
skimage/filter/rank/_crank8_percentiles.pyx
Extension: skimage.filter.rank._crank16_bilateral
Sources:
skimage/filter/rank/_crank16_bilateral.pyx
Executable: skivi
Module: skimage.scripts.skivi
+95
View File
@@ -0,0 +1,95 @@
"""
Check that Cython extensions in setup.py files match those in bento.info.
"""
import os
import re
RE_CYTHON = re.compile("config.add_extension\(\s*['\"]([\S]+)['\"]")
BENTO_TEMPLATE = """
Extension: {module_path}
Sources:
{dir_path}.pyx"""
def each_setup_in_pkg(top_dir):
"""Yield path and file object for each setup.py file"""
for dir_path, dir_names, filenames in os.walk(top_dir):
for fname in filenames:
if fname == 'setup.py':
with open(os.path.join(dir_path, 'setup.py')) as f:
yield dir_path, f
def each_cy_in_setup(top_dir):
"""Yield path for each cython extension package's setup file."""
for dir_path, f in each_setup_in_pkg(top_dir):
text = f.read()
match = RE_CYTHON.findall(text)
if match:
for cy_file in match:
# if cython files in different directory than setup.py
if '.' in cy_file:
parts = cy_file.split('.')
cy_file = parts[-1]
# Don't overwrite dir_path for subsequent iterations.
path = os.path.join(dir_path, *parts[:-1])
else:
path = dir_path
full_path = os.path.join(path, cy_file)
yield full_path
def each_cy_in_bento(bento_file='bento.info'):
"""Yield path for each cython extension in bento info file."""
with open(bento_file) as f:
for line in f:
line = line.strip()
if line.startswith('Extension:'):
path = line.lstrip('Extension:').strip()
yield path
def remove_common_extensions(cy_bento, cy_setup):
# normalize so that cy_setup and cy_bento have the same separator
cy_setup = set(ext.replace('/', '.') for ext in cy_setup)
cy_setup_diff = cy_setup.difference(cy_bento)
cy_setup_diff = set(ext.replace('.', '/') for ext in cy_setup_diff)
cy_bento_diff = cy_bento.difference(cy_setup)
return cy_bento_diff, cy_setup_diff
def print_results(cy_bento, cy_setup):
def info(text):
print
print(text)
print('-' * len(text))
if not (cy_bento or cy_setup):
print "bento.info and setup.py files match."
if cy_bento:
info("Extensions found in 'bento.info' but not in any 'setup.py:")
print('\n'.join(cy_bento))
if cy_setup:
info("Extensions found in a 'setup.py' but not in any 'bento.info:")
print('\n'.join(cy_setup))
info("Consider adding the following to the 'bento.info' Library:")
for dir_path in cy_setup:
module_path = dir_path.replace('/', '.')
print BENTO_TEMPLATE.format(module_path=module_path,
dir_path=dir_path)
if __name__ == '__main__':
# All cython extensions defined in 'setup.py' files.
cy_setup = set(each_cy_in_setup('skimage'))
# All cython extensions defined 'bento.info' file.
cy_bento = set(each_cy_in_bento())
cy_bento, cy_setup = remove_common_extensions(cy_bento, cy_setup)
print_results(cy_bento, cy_setup)
+9 -9
View File
@@ -77,17 +77,17 @@ qthelp:
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in build/qthelp, like this:"
@echo "# qcollectiongenerator build/qthelp/scikitsimage.qhcp"
@echo "# qcollectiongenerator build/qthelp/scikitimage.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile build/qthelp/scikitsimage.qhc"
@echo "# assistant -collectionFile build/qthelp/scikitimage.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(DEST)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/scikitsimage"
@echo "# ln -s build/devhelp $$HOME/.local/share/devhelp/scikitsimage"
@echo "# mkdir -p $$HOME/.local/share/devhelp/scikitimage"
@echo "# ln -s build/devhelp $$HOME/.local/share/devhelp/scikitimage"
@echo "# devhelp"
latex:
@@ -123,9 +123,9 @@ gh-pages:
python gh-pages.py
gitwash:
python tools/gitwash/gitwash_dumper.py source scikits-image \
--project-url=http://scikits-image.org \
--project-ml-url=http://groups.google.com/group/scikits-image \
--repo-name=scikits-image \
--github-user=scikits-image \
python tools/gitwash/gitwash_dumper.py source scikit-image \
--project-url=http://scikit-image.org \
--project-ml-url=http://groups.google.com/group/scikit-image \
--repo-name=scikit-image \
--github-user=scikit-image \
--source-suffix=.txt
View File
@@ -90,12 +90,8 @@ plt.title('Filling the holes')
Small spurious objects are easily removed by setting a minimum size for valid
objects.
"""
label_objects, nb_labels = ndimage.label(fill_coins)
sizes = np.bincount(label_objects.ravel())
mask_sizes = sizes > 20
mask_sizes[0] = 0
coins_cleaned = mask_sizes[label_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')
@@ -149,8 +145,7 @@ plt.title('markers')
Finally, we use the watershed transform to fill regions of the elevation map starting from the markers determined above:
"""
from skimage.morphology import watershed
segmentation = watershed(elevation_map, markers)
segmentation = morphology.watershed(elevation_map, markers)
plt.figure(figsize=(4, 3))
plt.imshow(segmentation, cmap=plt.cm.gray, interpolation='nearest')
+132
View File
@@ -0,0 +1,132 @@
"""
===============================
Using geometric transformations
===============================
In this example, we will see how to use geometric transformations in the context
of image processing.
"""
import math
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage import transform as tf
margins = dict(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
"""
Basics
======
Several different geometric transformation types are supported: similarity,
affine, projective and polynomial.
Geometric transformations can either be created using the explicit parameters
(e.g. scale, shear, rotation and translation) or the transformation matrix:
First we create a transformation using explicit parameters:
"""
tform = tf.SimilarityTransform(scale=1, rotation=math.pi / 2,
translation=(0, 1))
print tform._matrix
"""
Alternatively you can define a transformation by the transformation matrix
itself:
"""
matrix = tform._matrix.copy()
matrix[1, 2] = 2
tform2 = tf.SimilarityTransform(matrix)
"""
These transformation objects can then be used to apply forward and inverse
coordinate transformations between the source and destination coordinate
systems:
"""
coord = [1, 0]
print tform2(coord)
print tform2.inverse(tform(coord))
"""
Image warping
=============
Geometric transformations can also be used to warp images:
"""
text = data.text()
tform = tf.SimilarityTransform(scale=1, rotation=math.pi / 4,
translation=(text.shape[0] / 2, -100))
rotated = tf.warp(text, tform)
back_rotated = tf.warp(rotated, tform.inverse)
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 3))
fig.subplots_adjust(**margins)
plt.gray()
ax1.imshow(text)
ax1.axis('off')
ax2.imshow(rotated)
ax2.axis('off')
ax3.imshow(back_rotated)
ax3.axis('off')
"""
.. image:: PLOT2RST.current_figure
Parameter estimation
====================
In addition to the basic functionality mentioned above you can also estimate the
parameters of a geometric transformation using the least-squares method.
This can amongst other things be used for image registration or rectification,
where you have a set of control points or homologous/corresponding points in two
images.
Let's assume we want to recognize letters on a photograph which was not taken
from the front but at a certain angle. In the simplest case of a plane paper
surface the letters are projectively distorted. Simple matching algorithms would
not be able to match such symbols. One solution to this problem would be to warp
the image so that the distortion is removed and then apply a matching algorithm:
"""
text = data.text()
src = np.array((
(0, 0),
(0, 50),
(300, 50),
(300, 0)
))
dst = np.array((
(155, 15),
(65, 40),
(260, 130),
(360, 95)
))
tform3 = tf.ProjectiveTransform()
tform3.estimate(src, dst)
warped = tf.warp(text, tform3, output_shape=(50, 300))
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(8, 3))
fig.subplots_adjust(**margins)
plt.gray()
ax1.imshow(text)
ax1.plot(dst[:, 0], dst[:, 1], '.r')
ax1.axis('off')
ax2.imshow(warped)
ax2.axis('off')
"""
.. image:: PLOT2RST.current_figure
"""
plt.show()
@@ -0,0 +1,719 @@
"""
============
Rank filters
============
Rank filters are non-linear filters using the local greylevels ordering to
compute the filtered value. This ensemble of filters share a common base: the
local grey-level histogram extraction computed on the neighborhood of a pixel
(defined by a 2D structuring element). If the filtered value is taken as the
middle value of the histogram, we get the classical median filter.
Rank filters can be used for several purposes such as:
* image quality enhancement
e.g. image smoothing, sharpening
* image pre-processing
e.g. noise reduction, contrast enhancement
* feature extraction
e.g. border detection, isolated point detection
* post-processing
e.g. small object removal, object grouping, contour smoothing
Some well known filters are specific cases of rank filters [1]_ e.g.
morphological dilation, morphological erosion, median filters.
The different implementation availables in `skimage` are compared.
In this example, we will see how to filter a greylevel image using some of the
linear and non-linear filters availables in skimage. We use the `camera`
image from `skimage.data`.
.. [1] Pierre Soille, On morphological operators based on rank filters, Pattern
Recognition 35 (2002) 527-535.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
ima = data.camera()
hist = np.histogram(ima, bins=np.arange(0, 256))
plt.figure(figsize=(8, 3))
plt.subplot(1, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray, 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')
"""
.. image:: PLOT2RST.current_figure
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`
"""
noise = np.random.random(ima.shape)
nima = data.camera()
nima[noise > 0.99] = 255
nima[noise < 0.01] = 0
from skimage.filter.rank import median
from skimage.morphology import disk
fig = plt.figure(figsize=[10, 7])
lo = median(nima, disk(1))
hi = median(nima, disk(5))
ext = median(nima, disk(20))
plt.subplot(2, 2, 1)
plt.imshow(nima, cmap=plt.cm.gray, vmin=0, vmax=255)
plt.xlabel('noised image')
plt.subplot(2, 2, 2)
plt.imshow(lo, cmap=plt.cm.gray, vmin=0, vmax=255)
plt.xlabel('median $r=1$')
plt.subplot(2, 2, 3)
plt.imshow(hi, cmap=plt.cm.gray, vmin=0, vmax=255)
plt.xlabel('median $r=5$')
plt.subplot(2, 2, 4)
plt.imshow(ext, cmap=plt.cm.gray, vmin=0, vmax=255)
plt.xlabel('median $r=20$')
"""
.. image:: PLOT2RST.current_figure
The added noise is efficiently removed, as the image defaults are small (1 pixel
wide), a small filter radius is sufficient. As the radius is increasing, objects
with a bigger size are filtered as well, such as the camera tripod. The median
filter is commonly used for noise removal because borders are preserved.
Image smoothing
================
The example hereunder shows how a local **mean** smoothes the camera man image.
"""
from skimage.filter.rank import mean
fig = plt.figure(figsize=[10, 7])
loc_mean = mean(nima, disk(10))
plt.subplot(1, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray, vmin=0, vmax=255)
plt.xlabel('original')
plt.subplot(1, 2, 2)
plt.imshow(loc_mean, cmap=plt.cm.gray, vmin=0, vmax=255)
plt.xlabel('local mean $r=10$')
"""
.. image:: PLOT2RST.current_figure
One may be interested in smoothing an image while preserving important borders
(median filters already achieved this), here we use the **bilateral** filter
that restricts the local neighborhood to pixel having a greylevel similar to
the central one.
.. note::
a different implementation is available for color images in
`skimage.filter.denoise_bilateral`.
"""
from skimage.filter.rank import bilateral_mean
ima = data.camera()
selem = disk(10)
bilat = bilateral_mean(ima.astype(np.uint16), disk(20), s0=10, s1=10)
# display results
fig = plt.figure(figsize=[10, 7])
plt.subplot(2, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray)
plt.xlabel('original')
plt.subplot(2, 2, 3)
plt.imshow(bilat, cmap=plt.cm.gray)
plt.xlabel('bilateral mean')
plt.subplot(2, 2, 2)
plt.imshow(ima[200:350, 350:450], cmap=plt.cm.gray)
plt.subplot(2, 2, 4)
plt.imshow(bilat[200:350, 350:450], cmap=plt.cm.gray)
"""
.. image:: PLOT2RST.current_figure
One can see that the large continuous part of the image (e.g. sky) is smoothed
whereas other details are preserved.
Contrast enhancement
====================
We compare here how the global histogram equalization is applied locally.
The equalized image [2]_ has a roughly linear cumulative distribution function
for each pixel neighborhood. The local version [3]_ of the histogram
equalization emphasizes every local greylevel variations.
.. [2] http://en.wikipedia.org/wiki/Histogram_equalization
.. [3] http://en.wikipedia.org/wiki/Adaptive_histogram_equalization
"""
from skimage import exposure
from skimage.filter import rank
ima = data.camera()
# equalize globally and locally
glob = exposure.equalize(ima) * 255
loc = rank.equalize(ima, disk(20))
# extract histogram for each image
hist = np.histogram(ima, 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))
plt.subplot(321)
plt.imshow(ima, cmap=plt.cm.gray, interpolation='nearest')
plt.axis('off')
plt.subplot(322)
plt.plot(hist[1][:-1], hist[0], lw=2)
plt.title('histogram of grey values')
plt.subplot(323)
plt.imshow(glob, cmap=plt.cm.gray, interpolation='nearest')
plt.axis('off')
plt.subplot(324)
plt.plot(glob_hist[1][:-1], glob_hist[0], lw=2)
plt.title('histogram of grey values')
plt.subplot(325)
plt.imshow(loc, cmap=plt.cm.gray, interpolation='nearest')
plt.axis('off')
plt.subplot(326)
plt.plot(loc_hist[1][:-1], loc_hist[0], lw=2)
plt.title('histogram of grey values')
"""
.. image:: PLOT2RST.current_figure
another way to maximize the number of greylevels used for an image is to apply
a local autoleveling, i.e. here a pixel greylevel is proportionally remapped
between local minimum and local maximum.
The following example shows how local autolevel enhances the camara man picture.
"""
from skimage.filter.rank import autolevel
ima = data.camera()
selem = disk(10)
auto = autolevel(ima.astype(np.uint16), disk(20))
# display results
fig = plt.figure(figsize=[10, 7])
plt.subplot(1, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray)
plt.xlabel('original')
plt.subplot(1, 2, 2)
plt.imshow(auto, cmap=plt.cm.gray)
plt.xlabel('local autolevel')
"""
.. image:: PLOT2RST.current_figure
This filter is very sensitive to local outlayers, see the little white spot in
the sky left part. This is due to a local maximum which is very high comparing
to the rest of the neighborhood. One can moderate this using the percentile
version of the autolevel filter which uses given percentiles (one inferior,
one superior) in place of local minimum and maximum. The example below
illustrates how the percentile parameters influence the local autolevel result.
"""
from skimage.filter.rank import percentile_autolevel
image = data.camera()
selem = disk(20)
loc_autolevel = autolevel(image, selem=selem)
loc_perc_autolevel0 = percentile_autolevel(image, selem=selem, p0=.00, p1=1.0)
loc_perc_autolevel1 = percentile_autolevel(image, selem=selem, p0=.01, p1=.99)
loc_perc_autolevel2 = percentile_autolevel(image, selem=selem, p0=.05, p1=.95)
loc_perc_autolevel3 = percentile_autolevel(image, selem=selem, p0=.1, p1=.9)
fig, axes = plt.subplots(nrows=3, figsize=(7, 8))
ax0, ax1, ax2 = axes
plt.gray()
ax0.imshow(np.hstack((image, loc_autolevel)))
ax0.set_title('original / autolevel')
ax1.imshow(
np.hstack((loc_perc_autolevel0, loc_perc_autolevel1)), vmin=0, vmax=255)
ax1.set_title('percentile autolevel 0%,1%')
ax2.imshow(
np.hstack((loc_perc_autolevel2, loc_perc_autolevel3)), vmin=0, vmax=255)
ax2.set_title('percentile autolevel 5% and 10%')
for ax in axes:
ax.axis('off')
"""
.. image:: PLOT2RST.current_figure
The morphological contrast enhancement filter replaces the central pixel by the
local maximum if the original pixel value is closest to local maximum, otherwise
by the minimum local.
"""
from skimage.filter.rank import morph_contr_enh
ima = data.camera()
enh = morph_contr_enh(ima, disk(5))
# display results
fig = plt.figure(figsize=[10, 7])
plt.subplot(2, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray)
plt.xlabel('original')
plt.subplot(2, 2, 3)
plt.imshow(enh, cmap=plt.cm.gray)
plt.xlabel('local morphlogical contrast enhancement')
plt.subplot(2, 2, 2)
plt.imshow(ima[200:350, 350:450], cmap=plt.cm.gray)
plt.subplot(2, 2, 4)
plt.imshow(enh[200:350, 350:450], cmap=plt.cm.gray)
"""
.. image:: PLOT2RST.current_figure
The percentile version of the local morphological contrast enhancement uses
percentile *p0* and *p1* instead of the local minimum and maximum.
"""
from skimage.filter.rank import percentile_morph_contr_enh
ima = data.camera()
penh = percentile_morph_contr_enh(ima, disk(5), p0=.1, p1=.9)
# display results
fig = plt.figure(figsize=[10, 7])
plt.subplot(2, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray)
plt.xlabel('original')
plt.subplot(2, 2, 3)
plt.imshow(penh, cmap=plt.cm.gray)
plt.xlabel('local percentile morphlogical\n contrast enhancement')
plt.subplot(2, 2, 2)
plt.imshow(ima[200:350, 350:450], cmap=plt.cm.gray)
plt.subplot(2, 2, 4)
plt.imshow(penh[200:350, 350:450], cmap=plt.cm.gray)
"""
.. image:: PLOT2RST.current_figure
Image threshold
===============
The Otsu's threshold [1]_ method can be applied locally using the local
greylevel distribution. In the example below, for each pixel, an "optimal"
threshold is determined by maximizing the variance between two classes of pixels
of the local neighborhood defined by a structuring element.
The example compares the local threshold with the global threshold
`skimage.filter.threshold_otsu`.
.. note::
Local thresholding is much slower than global one. There exists a function
for global Otsu thresholding: `skimage.filter.threshold_otsu`.
.. [1] http://en.wikipedia.org/wiki/Otsu's_method
"""
from skimage.filter.rank import otsu
from skimage.filter import threshold_otsu
p8 = data.page()
radius = 10
selem = disk(radius)
# t_loc_otsu is an image
t_loc_otsu = otsu(p8, selem)
loc_otsu = p8 >= t_loc_otsu
# t_glob_otsu is a scalar
t_glob_otsu = threshold_otsu(p8)
glob_otsu = p8 >= t_glob_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(t_loc_otsu, cmap=plt.cm.gray)
plt.xlabel('local Otsu ($radius=%d$)' % radius)
plt.colorbar()
plt.subplot(2, 2, 3)
plt.imshow(p8 >= t_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)
"""
.. image:: PLOT2RST.current_figure
The following example shows how local Otsu's threshold handles a global level
shift applied to a synthetic image .
"""
n = 100
theta = np.linspace(0, 10 * np.pi, n)
x = np.sin(theta)
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()
plt.subplot(1, 2, 1)
plt.imshow(m)
plt.xlabel('original')
plt.subplot(1, 2, 2)
plt.imshow(m >= t, interpolation='nearest')
plt.xlabel('local Otsu ($radius=%d$)' % radius)
"""
.. image:: PLOT2RST.current_figure
Image morphology
================
Local maximum and local minimum are the base operators for greylevel
morphology.
.. note::
`skimage.dilate` and `skimage.erode` are equivalent filters (see below for
comparison).
Here is an example of the classical morphological greylevel filters: opening,
closing and morphological gradient.
"""
from skimage.filter.rank import maximum, minimum, gradient
ima = data.camera()
closing = maximum(minimum(ima, disk(5)), disk(5))
opening = minimum(maximum(ima, disk(5)), disk(5))
grad = gradient(ima, disk(5))
# display results
fig = plt.figure(figsize=[10, 7])
plt.subplot(2, 2, 1)
plt.imshow(ima, cmap=plt.cm.gray)
plt.xlabel('original')
plt.subplot(2, 2, 2)
plt.imshow(closing, cmap=plt.cm.gray)
plt.xlabel('greylevel closing')
plt.subplot(2, 2, 3)
plt.imshow(opening, cmap=plt.cm.gray)
plt.xlabel('greylevel opening')
plt.subplot(2, 2, 4)
plt.imshow(grad, cmap=plt.cm.gray)
plt.xlabel('morphological gradient')
"""
.. image:: PLOT2RST.current_figure
Feature extraction
===================
Local histogram can be exploited to compute local entropy, which is related to
the local image complexity. Entropy is computed using base 2 logarithm i.e. the
filter returns the minimum number of bits needed to encode local greylevel
distribution.
`skimage.rank.entropy` returns local entropy on a given structuring element.
The following example shows this filter applied on 8- and 16- bit images.
.. note::
to better use the available image bit, the function returns 10x entropy for
8-bit images and 1000x entropy for 16-bit images.
"""
from skimage import data
from skimage.filter.rank import entropy
from skimage.morphology import disk
import numpy as np
import matplotlib.pyplot as plt
# defining a 8- and a 16-bit test images
a8 = data.camera()
a16 = data.camera().astype(np.uint16) * 4
ent8 = entropy(a8, disk(5)) # pixel value contain 10x the local entropy
ent16 = entropy(a16, disk(5)) # pixel value contain 1000x the local entropy
# display results
plt.figure(figsize=(10, 10))
plt.subplot(2, 2, 1)
plt.imshow(a8, cmap=plt.cm.gray)
plt.xlabel('8-bit image')
plt.colorbar()
plt.subplot(2, 2, 2)
plt.imshow(ent8, cmap=plt.cm.jet)
plt.xlabel('entropy*10')
plt.colorbar()
plt.subplot(2, 2, 3)
plt.imshow(a16, cmap=plt.cm.gray)
plt.xlabel('16-bit image')
plt.colorbar()
plt.subplot(2, 2, 4)
plt.imshow(ent16, cmap=plt.cm.jet)
plt.xlabel('entropy*1000')
plt.colorbar()
"""
.. image:: PLOT2RST.current_figure
Implementation
================
The central part of the `skimage.rank` filters is build on a sliding window that
update local greylevel histogram. This approach limits the algorithm complexity
to O(n) where n is the number of image pixels. The complexity is also limited
with respect to the structuring element size.
"""
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
def exec_and_timeit(func):
"""Decorator that returns both function results and execution time."""
def wrapper(*arg):
t1 = time()
res = func(*arg)
t2 = time()
ms = (t2 - t1) * 1000.0
return (res, ms)
return wrapper
@exec_and_timeit
def cr_med(image, selem):
return median(image=image, selem=selem)
@exec_and_timeit
def cr_max(image, selem):
return maximum(image=image, selem=selem)
@exec_and_timeit
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)
"""
Comparison between
* `rank.maximum`
* `cmorph.dilate`
on increasing structuring element size
"""
a = data.camera()
rec = []
e_range = range(1, 20, 2)
for r in e_range:
elem = disk(r + 1)
rc, ms_rc = cr_max(a, elem)
rcm, ms_rcm = cm_dil(a, elem)
rec.append((ms_rc, ms_rcm))
rec = np.asarray(rec)
plt.figure()
plt.title('increasing element size')
plt.ylabel('time (ms)')
plt.xlabel('element radius')
plt.plot(e_range, rec)
plt.legend(['crank.maximum', 'cmorph.dilate'])
"""
and increasing image size
.. image:: PLOT2RST.current_figure
"""
r = 9
elem = disk(r + 1)
rec = []
s_range = range(100, 1000, 100)
for s in s_range:
a = (np.random.random((s, s)) * 256).astype('uint8')
(rc, ms_rc) = cr_max(a, elem)
(rcm, ms_rcm) = cm_dil(a, elem)
rec.append((ms_rc, ms_rcm))
rec = np.asarray(rec)
plt.figure()
plt.title('increasing image size')
plt.ylabel('time (ms)')
plt.xlabel('image size')
plt.plot(s_range, rec)
plt.legend(['crank.maximum', 'cmorph.dilate'])
"""
.. image:: PLOT2RST.current_figure
Comparison between:
* `rank.median`
* `ctmf.median_filter`
* `ndimage.percentile`
on increasing structuring element size
"""
a = data.camera()
rec = []
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 = np.asarray(rec)
plt.figure()
plt.title('increasing element size')
plt.plot(e_range, rec)
plt.legend(['rank.median', 'ctmf.median_filter', 'ndimage.percentile'])
plt.ylabel('time (ms)')
plt.xlabel('element radius')
"""
.. image:: PLOT2RST.current_figure
comparison of outcome of the three methods
"""
plt.figure()
plt.imshow(np.hstack((rc, rctmf, rndi)))
plt.xlabel('rank.median vs ctmf.median_filter vs ndimage.percentile')
"""
.. image:: PLOT2RST.current_figure
and increasing image size
"""
r = 9
elem = disk(r + 1)
rec = []
s_range = [100, 200, 500, 1000]
for s in s_range:
a = (np.random.random((s, s)) * 256).astype('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 = np.asarray(rec)
plt.figure()
plt.title('increasing image size')
plt.plot(s_range, rec)
plt.legend(['rank.median', 'ctmf.median_filter', 'ndimage.percentile'])
plt.ylabel('time (ms)')
plt.xlabel('image size')
"""
.. image:: PLOT2RST.current_figure
"""
plt.show()
+47
View File
@@ -0,0 +1,47 @@
"""
==============================
Bilateral mean
==============================
This example compares
* local mean
* percentile mean
* bilateral mean
build on the local histogram distribution
local mean uses all pixels belonging to the structuring element to compute average gray level,
percentile mean uses only values between percentiles p0 and p1 (here 10% and 90%),
whereas bilateral mean uses only pixels of the structuring element having a gray level situated inside
g-s0 and g+s1 (here g-500 and g+500).
The filters are applied on a 16 bit image (actual bitdepth is 12bit).
Percentile and usual mean give here similar results, these filters smooth the complete image (background and details).
Bilateral mean exhibits a high filtering rate for continuous area (i.e. background) while image higher frequencies
remains untouched.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.morphology import disk
import skimage.filter.rank as rank
a16 = (data.coins()).astype('uint16') * 16
selem = disk(20)
f1 = rank.percentile_mean(a16, selem=selem, p0=.1, p1=.9)
f2 = rank.bilateral_mean(a16, selem=selem, s0=500, s1=500)
f3 = rank.mean(a16, selem=selem)
# display results
fig, axes = plt.subplots(nrows=3, figsize=(15, 10))
ax0, ax1, ax2 = axes
ax0.imshow(np.hstack((a16, f1)))
ax0.set_title('percentile mean')
ax1.imshow(np.hstack((a16, f2)))
ax1.set_title('bilateral mean')
ax2.imshow(np.hstack((a16, f3)))
ax2.set_title('local mean')
plt.show()
+72
View File
@@ -0,0 +1,72 @@
"""
========================
Circular Hough Transform
========================
The Hough transform in its simplest form is a `method to detect
straight lines <http://en.wikipedia.org/wiki/Hough_transform>`__
but it can also be used to detect circles.
In the following example, the Hough transform is used to detect
coin positions and match their edges. We provide a range of
plausible radii. For each radius, two circles are extracted and
we finally keep the five most prominent candidates.
The result shows that coin positions are well-detected.
Algorithm overview
------------------
Given a black circle on a white background, we first guess its
radius (or a range of radii) to construct a new circle.
This circle is applied on each black pixel of the original picture
and the coordinates of this circle are voting in an accumulator.
From this geometrical construction, the original circle center
position receives the highest score.
Note that the accumulator size is built to be larger than the
original picture in order to detect centers outside the frame.
Its size is extended by two times the larger radius.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, filter, color
from skimage.transform import hough_circle
from skimage.feature import peak_local_max
from skimage.draw import circle_perimeter
# Load picture and detect edges
image = 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))
# Detect two radii
hough_radii = np.arange(15, 30, 2)
hough_res = hough_circle(edges, hough_radii)
centers = []
accums = []
radii = []
for radius, h in zip(hough_radii, hough_res):
# For each radius, extract two circles
peaks = peak_local_max(h, num_peaks=2)
centers.extend(peaks - hough_radii.max())
accums.extend(h[peaks[:, 0], peaks[:, 1]])
radii.extend([radius, radius])
# Draw the most prominent 5 circles
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:5]:
center_x, center_y = centers[idx]
radius = radii[idx]
cx, cy = circle_perimeter(center_y, center_x, radius)
image[cy, cx] = (220, 20, 20)
ax.imshow(image, cmap=plt.cm.gray)
plt.show()
+37
View File
@@ -0,0 +1,37 @@
"""
================
Corner detection
================
Detect corner points using the Harris corner detector and determine subpixel
position of corners.
.. [1] http://en.wikipedia.org/wiki/Corner_detection
.. [2] http://en.wikipedia.org/wiki/Interest_point_detection
"""
from matplotlib import pyplot as plt
from skimage import data
from skimage.feature import corner_harris, corner_subpix, corner_peaks
from skimage.transform import warp, AffineTransform
from skimage.draw import ellipse
tform = AffineTransform(scale=(1.3, 1.1), rotation=1, shear=0.7,
translation=(210, 50))
image = warp(data.checkerboard(), tform.inverse, output_shape=(350, 350))
rr, cc = ellipse(310, 175, 10, 100)
image[rr, cc] = 1
image[180:230, 10:60] = 1
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))
plt.show()
+28
View File
@@ -0,0 +1,28 @@
"""
===============================
Dense DAISY feature description
===============================
The DAISY local image descriptor is based on gradient orientation histograms
similar to the SIFT descriptor. It is formulated in a way that allows for fast
dense extraction which is useful for e.g. bag-of-features image
representations.
In this example a limited number of DAISY descriptors are extracted at a large
scale for illustrative purposes.
"""
from skimage.feature import daisy
from skimage import data
import matplotlib.pyplot as plt
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)
descs_num = descs.shape[0] * descs.shape[1]
plt.title('%i DAISY descriptors extracted:' % descs_num)
plt.show()
+68
View File
@@ -0,0 +1,68 @@
"""
=============================
Denoising the picture of Lena
=============================
In this example, we denoise a noisy version of the picture of Lena using the
total variation and bilateral denoising filter.
These algorithms typically produce "posterized" images with flat domains
separated by sharp edges. It is possible to change the degree of posterization
by controlling the tradeoff between denoising and faithfulness to the original
image.
Total variation filter
----------------------
The result of this filter is an image that has a minimal total variation norm,
while being as close to the initial image as possible. The total variation is
the L1 norm of the gradient of the image.
Bilateral filter
----------------
A bilateral filter is an edge-preserving and noise reducing filter. It averages
pixels based on their spatial closeness and radiometric similarity.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color, img_as_float
from skimage.filter import denoise_tv_chambolle, denoise_bilateral
lena = img_as_float(data.lena())
lena = lena[220:300, 220:320]
noisy = lena + 0.6 * lena.std() * np.random.random(lena.shape)
noisy = np.clip(noisy, 0, 1)
fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(8, 5))
plt.gray()
ax[0, 0].imshow(noisy)
ax[0, 0].axis('off')
ax[0, 0].set_title('noisy')
ax[0, 1].imshow(denoise_tv_chambolle(noisy, weight=0.1, multichannel=True))
ax[0, 1].axis('off')
ax[0, 1].set_title('TV')
ax[0, 2].imshow(denoise_bilateral(noisy, sigma_range=0.05, sigma_spatial=15))
ax[0, 2].axis('off')
ax[0, 2].set_title('Bilateral')
ax[1, 0].imshow(denoise_tv_chambolle(noisy, weight=0.2, multichannel=True))
ax[1, 0].axis('off')
ax[1, 0].set_title('(more) TV')
ax[1, 1].imshow(denoise_bilateral(noisy, sigma_range=0.1, sigma_spatial=15))
ax[1, 1].axis('off')
ax[1, 1].set_title('(more) Bilateral')
ax[1, 2].imshow(lena)
ax[1, 2].axis('off')
ax[1, 2].set_title('original')
fig.subplots_adjust(wspace=0.02, hspace=0.2,
top=0.9, bottom=0.05, left=0, right=1)
plt.show()
+44
View File
@@ -0,0 +1,44 @@
"""
===================
Entropy
===================
"""
from skimage import data
from skimage.filter.rank import entropy
from skimage.morphology import disk
import numpy as np
import matplotlib.pyplot as plt
# defining a 8- and a 16-bit test images
a8 = data.camera()
a16 = data.camera().astype(np.uint16)*4
ent8 = entropy(a8,disk(5)) # pixel value contain 10x the local entropy
ent16 = entropy(a16,disk(5)) # pixel value contain 1000x the local entropy
# display results
plt.figure(figsize=(10, 10))
plt.subplot(2,2,1)
plt.imshow(a8, cmap=plt.cm.gray)
plt.xlabel('8-bit image')
plt.colorbar()
plt.subplot(2,2,2)
plt.imshow(ent8, cmap=plt.cm.jet)
plt.xlabel('entropy*10')
plt.colorbar()
plt.subplot(2,2,3)
plt.imshow(a16, cmap=plt.cm.gray)
plt.xlabel('16-bit image')
plt.colorbar()
plt.subplot(2,2,4)
plt.imshow(ent16, cmap=plt.cm.jet)
plt.xlabel('entropy*1000')
plt.colorbar()
plt.show()
+19 -11
View File
@@ -18,18 +18,18 @@ that fall within the 2nd and 98th percentiles [2]_.
"""
from skimage import data
from skimage.util.dtype import dtype_range
from skimage import data, img_as_float
from skimage import exposure
import matplotlib.pyplot as plt
import numpy as np
def plot_img_and_hist(img, axes, bins=256):
"""Plot an image along with its histogram and cumulative histogram.
"""
img = img_as_float(img)
ax_img, ax_hist = axes
ax_cdf = ax_hist.twinx()
@@ -38,16 +38,16 @@ def plot_img_and_hist(img, axes, bins=256):
ax_img.set_axis_off()
# Display histogram
ax_hist.hist(img.ravel(), bins=bins)
ax_hist.hist(img.ravel(), bins=bins, histtype='step', color='black')
ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))
ax_hist.set_xlabel('Pixel intensity')
xmin, xmax = dtype_range[img.dtype.type]
ax_hist.set_xlim(xmin, xmax)
ax_hist.set_xlim(0, 1)
ax_hist.set_yticks([])
# Display cumulative distribution
img_cdf, bins = exposure.cumulative_distribution(img, bins)
ax_cdf.plot(bins, img_cdf, 'r')
ax_cdf.set_yticks([])
return ax_img, ax_hist, ax_cdf
@@ -61,25 +61,33 @@ p98 = np.percentile(img, 98)
img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))
# Equalization
img_eq = exposure.equalize(img)
img_eq = exposure.equalize_hist(img)
# Adaptive Equalization
img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03)
# Display results
f, axes = plt.subplots(2, 3, figsize=(8, 4))
f, axes = plt.subplots(2, 4, figsize=(8, 4))
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
ax_img.set_title('Low contrast image')
y_min, y_max = ax_hist.get_ylim()
ax_hist.set_ylabel('Number of pixels')
ax_hist.set_yticks(np.linspace(0, y_max, 5))
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1])
ax_img.set_title('Contrast stretching')
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2])
ax_img.set_title('Histogram equalization')
ax_cdf.set_ylabel('Fraction of total intensity')
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_adapteq, axes[:, 3])
ax_img.set_title('Adaptive equalization')
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)
plt.show()
-42
View File
@@ -1,42 +0,0 @@
"""
===============================================================================
Harris Corner detector
===============================================================================
The Harris corner filter [1]_ detects "interest points" [2]_ using edge
detection in multiple directions.
.. [1] http://en.wikipedia.org/wiki/Corner_detection
.. [2] http://en.wikipedia.org/wiki/Interest_point_detection
"""
import numpy as np
from matplotlib import pyplot as plt
from skimage import data, img_as_float
from skimage.feature import harris
def plot_harris_points(image, filtered_coords):
""" plots corners found in image"""
plt.imshow(image)
y, x = np.transpose(filtered_coords)
plt.plot(x, y, 'b.')
plt.axis('off')
# display results
plt.figure(figsize=(8, 3))
im_lena = img_as_float(data.lena())
im_text = img_as_float(data.text())
filtered_coords = harris(im_lena, min_distance=4)
plt.axes([0, 0, 0.3, 0.95])
plot_harris_points(im_lena, filtered_coords)
filtered_coords = harris(im_text, min_distance=4)
plt.axes([0.2, 0, 0.77, 1])
plot_harris_points(im_text, filtered_coords)
plt.show()
+86
View File
@@ -0,0 +1,86 @@
"""
===============================
Filling holes and finding peaks
===============================
In this example, we fill holes (i.e. isolated, dark spots) in an image using
morphological reconstruction by erosion. Erosion expands the minimal values of
the seed image until it encounters a mask image. Thus, the seed image and mask
image represent the maximum and minimum possible values of the reconstructed
image.
We start with an image containing both peaks and holes:
"""
import matplotlib.pyplot as plt
from skimage import data
from skimage.exposure import rescale_intensity
image = data.moon()
# Rescale image intensity so that we can see dim features.
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')
imshow(image)
plt.title('original image')
"""
.. image:: PLOT2RST.current_figure
Now we need to create the seed image, where the minima represent the starting
points for erosion. To fill holes, we initialize the seed image to the maximum
value of the original image. Along the borders, however, we use the original
values of the image. These border pixels will be the starting points for the
erosion process. We then limit the erosion by setting the mask to the values
of the original image.
"""
import numpy as np
from skimage.morphology import reconstruction
seed = np.copy(image)
seed[1:-1, 1:-1] = image.max()
mask = image
filled = reconstruction(seed, mask, method='erosion')
imshow(filled, vmin=image.min(), vmax=image.max())
plt.title('after filling holes')
"""
.. image:: PLOT2RST.current_figure
As shown above, eroding inward from the edges removes holes, since (by
definition) holes are surrounded by pixels of brighter value. Finally, we can
isolate the dark regions by subtracting the reconstructed image from the
original image.
"""
imshow(image - filled)
plt.title('holes')
"""
.. image:: PLOT2RST.current_figure
Alternatively, we can find bright spots in an image using morphological
reconstruction by dilation. Dilation is the inverse of erosion and expands the
*maximal* values of the seed image until it encounters a mask image. Since this
is an inverse operation, we initialize the seed image to the minimum image
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')
plt.show()
"""
.. image:: PLOT2RST.current_figure
"""
+14 -6
View File
@@ -59,7 +59,7 @@ References
'''
from skimage.transform import hough, probabilistic_hough
from skimage.transform import hough, hough_peaks, probabilistic_hough
from skimage.filter import canny
from skimage import data
@@ -81,11 +81,11 @@ h, theta, d = hough(image)
plt.figure(figsize=(8, 4))
plt.subplot(121)
plt.subplot(131)
plt.imshow(image, cmap=plt.cm.gray)
plt.title('Input image')
plt.subplot(122)
plt.subplot(132)
plt.imshow(np.log(1 + h),
extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
d[-1], d[0]],
@@ -94,6 +94,15 @@ plt.title('Hough transform')
plt.xlabel('Angles (degrees)')
plt.ylabel('Distance (pixels)')
plt.subplot(133)
plt.imshow(image, cmap=plt.cm.gray)
rows, cols = image.shape
for _, angle, dist in zip(*hough_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')
# Line finding, using the Probabilistic Hough Transform
@@ -109,7 +118,7 @@ plt.title('Input image')
plt.subplot(132)
plt.imshow(edges, cmap=plt.cm.gray)
plt.title('Sobel edges')
plt.title('Canny edges')
plt.subplot(133)
plt.imshow(edges * 0)
@@ -118,7 +127,6 @@ for line in lines:
p0, p1 = line
plt.plot((p0[0], p1[0]), (p0[1], p1[1]))
plt.title('Lines found with PHT')
plt.title('Probabilistic Hough')
plt.axis('image')
plt.show()
+69
View File
@@ -0,0 +1,69 @@
"""
==========================================
Find the intersection of two segmentations
==========================================
When segmenting an image, you may want to combine multiple alternative
segmentations. The `skimage.segmentation.join_segmentations` function
computes the join of two segmentations, in which a pixel is placed in
the same segment if and only if it is in the same segment in _both_
segmentations.
"""
import numpy as np
from scipy import ndimage as nd
import matplotlib.pyplot as plt
import matplotlib as mpl
from skimage.filter import sobel
from skimage.segmentation import slic, join_segmentations
from skimage.morphology import watershed
from skimage import data
coins = data.coins()
# make segmentation using edge-detection and watershed
edges = sobel(coins)
markers = np.zeros_like(coins)
foreground, background = 1, 2
markers[coins < 30] = background
markers[coins > 150] = foreground
ws = watershed(edges, markers)
seg1 = nd.label(ws == foreground)[0]
# make segmentation using SLIC superpixels
# make the RGB equivalent of `coins`
coins_colour = np.tile(coins[..., np.newaxis], (1, 1, 3))
seg2 = slic(coins_colour, n_segments=30, max_iter=160, sigma=1, ratio=9,
convert2lab=False)
# combine the two
segj = join_segmentations(seg1, seg2)
### Display the result ###
# make a random colormap for a set number of values
def random_cmap(im):
np.random.seed(9)
cmap_array = np.concatenate(
(np.zeros((1, 3)), np.random.rand(np.ceil(im.max()), 3)))
return mpl.colors.ListedColormap(cmap_array)
# show the segmentations
fig, axes = plt.subplots(ncols=4, figsize=(9, 2.5))
axes[0].imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
axes[0].set_title('Image')
axes[1].imshow(seg1, cmap=random_cmap(seg1), interpolation='nearest')
axes[1].set_title('Sobel+Watershed')
axes[2].imshow(seg2, cmap=random_cmap(seg2), interpolation='nearest')
axes[2].set_title('SLIC superpixels')
axes[3].imshow(segj, cmap=random_cmap(segj), interpolation='nearest')
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)
plt.show()
+57
View File
@@ -0,0 +1,57 @@
"""
===================
Label image regions
===================
This example shows how to segment an image with image labelling. The following
steps are applied:
1. Thresholding with automatic Otsu method
2. Close small holes with binary closing
3. Remove artifacts touching image border
4. Measure image regions to filter small objects
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage import data
from skimage.filter import threshold_otsu
from skimage.segmentation import clear_border
from skimage.morphology import label, closing, square
from skimage.measure import regionprops
image = data.coins()[50:-50, 50:-50]
# apply threshold
thresh = threshold_otsu(image)
bw = closing(image > thresh, square(3))
# remove artifacts connected to image border
cleared = bw.copy()
clear_border(cleared)
# label image regions
label_image = label(cleared)
borders = np.logical_xor(bw, cleared)
label_image[borders] = -1
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(label_image, cmap='jet')
for region in regionprops(label_image, ['Area', 'BoundingBox']):
# skip small images
if region['Area'] < 100:
continue
# draw rectangle around segmented coins
minr, minc, maxr, maxc = region['BoundingBox']
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax.add_patch(rect)
plt.show()
-51
View File
@@ -1,51 +0,0 @@
"""
====================================================
Denoising the picture of Lena using total variation
====================================================
In this example, we denoise a noisy version of the picture of Lena
using the total variation denoising filter. The result of this filter
is an image that has a minimal total variation norm, while being as
close to the initial image as possible. The total variation is the L1
norm of the gradient of the image, and minimizing the total variation
typically produces "posterized" images with flat domains separated by
sharp edges.
It is possible to change the degree of posterization by controlling
the tradeoff between denoising and faithfulness to the original image.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color, img_as_ubyte
from skimage.filter import tv_denoise
l = img_as_ubyte(color.rgb2gray(data.lena()))
l = l[230:290, 220:320]
noisy = l + 0.4 * l.std() * np.random.random(l.shape)
tv_denoised = tv_denoise(noisy, weight=10)
plt.figure(figsize=(8, 2))
plt.subplot(131)
plt.imshow(noisy, cmap=plt.cm.gray, vmin=40, vmax=220)
plt.axis('off')
plt.title('noisy', fontsize=20)
plt.subplot(132)
plt.imshow(tv_denoised, cmap=plt.cm.gray, vmin=40, vmax=220)
plt.axis('off')
plt.title('TV denoising', fontsize=20)
tv_denoised = tv_denoise(noisy, weight=50)
plt.subplot(133)
plt.imshow(tv_denoised, cmap=plt.cm.gray, vmin=40, vmax=220)
plt.axis('off')
plt.title('(more) TV denoising', fontsize=20)
plt.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9, bottom=0, left=0,
right=1)
plt.show()
+87
View File
@@ -0,0 +1,87 @@
"""
===============================================
Local Binary Pattern for texture classification
===============================================
In this example, we will see how to classify textures based on LBP (Local
Binary Pattern). The histogram of the LBP result is a good measure to classify
textures. For simplicity the histogram distributions are then tested against
each other using the Kullback-Leibler-Divergence.
"""
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import scipy.ndimage as nd
import skimage.feature as ft
from skimage import data
# settings for LBP
METHOD = 'uniform'
P = 16
R = 2
matplotlib.rcParams['font.size'] = 9
def kullback_leibler_divergence(p, q):
p = np.asarray(p)
q = np.asarray(q)
filt = np.logical_and(p != 0, q != 0)
return np.sum(p[filt] * np.log2(p[filt] / q[filt]))
def match(refs, img):
best_score = 10
best_name = None
lbp = ft.local_binary_pattern(img, P, R, METHOD)
hist, _ = np.histogram(lbp, normed=True, bins=P + 2, range=(0, P + 2))
for name, ref in refs.items():
ref_hist, _ = np.histogram(ref, normed=True, bins=P + 2,
range=(0, P + 2))
score = kullback_leibler_divergence(hist, ref_hist)
if score < best_score:
best_score = score
best_name = name
return best_name
brick = data.load('brick.png')
grass = data.load('grass.png')
wall = data.load('rough-wall.png')
refs = {
'brick': ft.local_binary_pattern(brick, P, R, METHOD),
'grass': ft.local_binary_pattern(grass, P, R, METHOD),
'wall': ft.local_binary_pattern(wall, P, R, METHOD)
}
# classify rotated textures
print 'Rotated images matched against references using LBP:'
print 'original: brick, rotated: 30deg, match result:',
print match(refs, nd.rotate(brick, angle=30, reshape=False))
print 'original: brick, rotated: 70deg, match result:',
print match(refs, nd.rotate(brick, angle=70, reshape=False))
print 'original: grass, rotated: 145deg, match result:',
print match(refs, nd.rotate(grass, angle=145, reshape=False))
# plot histograms of LBP of textures
fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(nrows=2, ncols=3,
figsize=(9, 6))
plt.gray()
ax1.imshow(brick)
ax1.axis('off')
ax4.hist(refs['brick'].ravel(), normed=True, bins=P + 2, range=(0, P + 2))
ax4.set_ylabel('Percentage')
ax2.imshow(grass)
ax2.axis('off')
ax5.hist(refs['grass'].ravel(), normed=True, bins=P + 2, range=(0, P + 2))
ax5.set_xlabel('Uniform LBP values')
ax3.imshow(wall)
ax3.axis('off')
ax6.hist(refs['wall'].ravel(), normed=True, bins=P + 2, range=(0, P + 2))
plt.show()
+84
View File
@@ -0,0 +1,84 @@
"""
===============================
Local Histogram Equalization
===============================
This examples enhances an image with low contrast, using a method called
*local histogram equalization*, which "spreads out the most frequent intensity
values" in an image .
The equalized image [1]_ has a roughly linear cumulative distribution function for each pixel neighborhood.
The local version [2]_ of the histogram equalization emphasized every local graylevel variations.
.. [1] http://en.wikipedia.org/wiki/Histogram_equalization
.. [2] http://en.wikipedia.org/wiki/Adaptive_histogram_equalization
"""
from skimage import data
from skimage.util.dtype import dtype_range
from skimage import exposure
from skimage.morphology import disk
import matplotlib.pyplot as plt
import numpy as np
from skimage.filter import rank
def plot_img_and_hist(img, axes, bins=256):
"""Plot an image along with its histogram and cumulative histogram.
"""
ax_img, ax_hist = axes
ax_cdf = ax_hist.twinx()
# Display image
ax_img.imshow(img, cmap=plt.cm.gray)
ax_img.set_axis_off()
# Display histogram
ax_hist.hist(img.ravel(), bins=bins)
ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))
ax_hist.set_xlabel('Pixel intensity')
xmin, xmax = dtype_range[img.dtype.type]
ax_hist.set_xlim(xmin, xmax)
# Display cumulative distribution
img_cdf, bins = exposure.cumulative_distribution(img, bins)
ax_cdf.plot(bins, img_cdf, 'r')
return ax_img, ax_hist, ax_cdf
# Load an example image
img = data.moon()
# Contrast stretching
p2 = np.percentile(img, 2)
p98 = np.percentile(img, 98)
img_rescale = exposure.equalize_hist(img)
# Equalization
selem = disk(30)
img_eq = rank.equalize(img, selem=selem)
# Display results
f, axes = plt.subplots(2, 3, figsize=(8, 4))
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
ax_img.set_title('Low contrast image')
ax_hist.set_ylabel('Number of pixels')
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1])
ax_img.set_title('Global equalise')
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2])
ax_img.set_title('Local equalize')
ax_cdf.set_ylabel('Fraction of total intensity')
# prevent overlap of y-axis labels
plt.subplots_adjust(wspace=0.4)
plt.show()
+49
View File
@@ -0,0 +1,49 @@
"""
=====================
Local Otsu Threshold
=====================
This example shows how Otsu's threshold [1]_ method can be applied locally.
For each pixel, an "optimal" threshold is determined by maximizing the variance between two classes of pixels
of the local neighborhood defined by a structuring element.
The example compares the local threshold with the global threshold.
.. note: local threshold is much slower than global one.
.. [1] http://en.wikipedia.org/wiki/Otsu's_method
"""
import matplotlib.pyplot as plt
from skimage import data
from skimage.morphology.selem import disk
import skimage.filter.rank as rank
from skimage.filter import threshold_otsu
p8 = data.page()
radius = 10
selem = disk(radius)
loc_otsu = rank.otsu(p8, selem)
t_glob_otsu = threshold_otsu(p8)
glob_otsu = p8 >= t_glob_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)
plt.show()
+54
View File
@@ -0,0 +1,54 @@
"""
================================
Markers for watershed transform
================================
The watershed is a classical algorithm used for **segmentation**, that
is, for separating different objects in an image.
Here a marker image is build from the region of low gradient inside the image.
See Wikipedia_ for more details on the algorithm.
.. _Wikipedia: http://en.wikipedia.org/wiki/Watershed_(image_processing)
"""
from scipy import ndimage
import matplotlib.pyplot as plt
from skimage.morphology import watershed, disk
from skimage import data
# original data
from skimage.filter import rank
image = data.camera()
# denoise image
denoised = rank.median(image, disk(2))
# find continuous region (low gradient) --> markers
markers = rank.gradient(denoised, disk(5)) < 10
markers = ndimage.label(markers)[0]
#local gradient
gradient = rank.gradient(denoised, disk(2))
# process the watershed
labels = watershed(gradient, markers)
# display results
fig, axes = plt.subplots(ncols=4, figsize=(8, 2.7))
ax0, ax1, ax2, ax3 = axes
ax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
ax1.imshow(gradient, cmap=plt.cm.spectral, interpolation='nearest')
ax2.imshow(markers, cmap=plt.cm.spectral, interpolation='nearest')
ax3.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
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)
plt.show()
+41
View File
@@ -0,0 +1,41 @@
"""
===============================
Piecewise Affine Transformation
===============================
This example shows how to use the Piecewise Affine Transformation.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage.transform import PiecewiseAffineTransform, warp
from skimage import data
image = data.lena()
rows, cols = image.shape[0], image.shape[1]
src_cols = np.linspace(0, cols, 20)
src_rows = np.linspace(0, rows, 10)
src_rows, src_cols = np.meshgrid(src_rows, src_cols)
src = np.dstack([src_cols.flat, src_rows.flat])[0]
# add sinusoidal oscillation to row coordinates
dst_rows = src[:, 1] - np.sin(np.linspace(0, 3 * np.pi, src.shape[0])) * 50
dst_cols = src[:, 0]
dst_rows *= 1.5
dst_rows -= 1.5 * 50
dst = np.vstack([dst_cols, dst_rows]).T
tform = PiecewiseAffineTransform()
tform.estimate(src, dst)
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))
plt.show()
+77
View File
@@ -0,0 +1,77 @@
"""
==================================
Approximate and subdivide polygons
==================================
This example shows how to approximate (Douglas-Peucker algorithm) and subdivide
(B-Splines) polygonal chains.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage.draw import ellipse
from skimage.measure import find_contours, approximate_polygon, \
subdivide_polygon
hand = np.array([[1.64516129, 1.16145833],
[1.64516129, 1.59375 ],
[1.35080645, 1.921875 ],
[1.375 , 2.18229167],
[1.68548387, 1.9375 ],
[1.60887097, 2.55208333],
[1.68548387, 2.69791667],
[1.76209677, 2.56770833],
[1.83064516, 1.97395833],
[1.89516129, 2.75 ],
[1.9516129 , 2.84895833],
[2.01209677, 2.76041667],
[1.99193548, 1.99479167],
[2.11290323, 2.63020833],
[2.2016129 , 2.734375 ],
[2.25403226, 2.60416667],
[2.14919355, 1.953125 ],
[2.30645161, 2.36979167],
[2.39112903, 2.36979167],
[2.41532258, 2.1875 ],
[2.1733871 , 1.703125 ],
[2.07782258, 1.16666667]])
# subdivide polygon using 2nd degree B-Splines
new_hand = hand.copy()
for _ in range(5):
new_hand = subdivide_polygon(new_hand, degree=2, preserve_ends=True)
# approximate subdivided polygon with Douglas-Peucker algorithm
appr_hand = approximate_polygon(new_hand, tolerance=0.02)
print "Number of coordinates:", len(hand), len(new_hand), len(appr_hand)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(9, 4))
ax1.plot(hand[:, 0], hand[:, 1])
ax1.plot(new_hand[:, 0], new_hand[:, 1])
ax1.plot(appr_hand[:, 0], appr_hand[:, 1])
# create two ellipses in image
img = np.zeros((800, 800), 'int32')
rr, cc = ellipse(250, 250, 180, 230, img.shape)
img[rr, cc] = 1
rr, cc = ellipse(600, 600, 150, 90, img.shape)
img[rr, cc] = 1
plt.gray()
ax2.imshow(img)
# approximate / simplify coordinates of the two ellipses
for contour in find_contours(img, 0):
coords = approximate_polygon(contour, tolerance=2.5)
ax2.plot(coords[:, 1], coords[:, 0], '-r', linewidth=2)
coords2 = approximate_polygon(contour, tolerance=39.5)
ax2.plot(coords2[:, 1], coords2[:, 0], '-g', linewidth=2)
print "Number of coordinates:", len(contour), len(coords), len(coords2)
ax2.axis((0, 800, 0, 800))
plt.show()
+35
View File
@@ -0,0 +1,35 @@
"""
====================
Build image pyramids
====================
The `pyramid_gaussian` function takes an image and yields successive images
shrunk by a constant scale factor. Image pyramids are often used, e.g., to
implement algorithms for denoising, texture discrimination, and scale- invariant
detection.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.transform import pyramid_gaussian
image = data.lena()
rows, cols, dim = image.shape
pyramid = tuple(pyramid_gaussian(image, downscale=2))
composite_image = np.zeros((rows, cols + cols / 2, 3), dtype=np.double)
composite_image[:rows, :cols, :] = pyramid[0]
i_row = 0
for p in pyramid[1:]:
n_rows, n_cols = p.shape[:2]
composite_image[i_row:i_row + n_rows, cols:cols + n_cols] = p
i_row += n_rows
plt.imshow(composite_image)
plt.show()
@@ -19,7 +19,6 @@ values, and use the random walker for the segmentation.
.. [1] *Random walks for image segmentation*, Leo Grady, IEEE Trans. Pattern
Anal. Mach. Intell. 2006 Nov; 28(11):1768-83
"""
print __doc__
import numpy as np
from scipy import ndimage
+113
View File
@@ -0,0 +1,113 @@
"""
=========================
Filtering regional maxima
=========================
Here, we use morphological reconstruction to create a background image, which
we can subtract from the original image to isolate bright features (regional
maxima).
First we try reconstruction by dilation starting at the edges of the image. We
initialize a seed image to the minimum intensity of the image, and set its
border to be the pixel values in the original image. These maximal pixels will
get dilated in order to reconstruct the background image.
"""
import numpy as np
from skimage import data
from skimage import img_as_float
from skimage.morphology import reconstruction
from scipy.ndimage import gaussian_filter
import matplotlib.pyplot as plt
# Convert to float: Important for subtraction later which won't work with uint8
image = img_as_float(data.coins())
image = gaussian_filter(image, 1)
seed = np.copy(image)
seed[1:-1, 1:-1] = image.min()
mask = image
dilated = reconstruction(seed, mask, method='dilation')
"""
Subtracting the dilated image leaves an image with just the coins and a flat,
black background, as shown below.
"""
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 2.5))
ax1.imshow(image)
ax1.set_title('original image')
ax1.axis('off')
ax2.imshow(dilated, vmin=image.min(), vmax=image.max())
ax2.set_title('dilated')
ax2.axis('off')
ax3.imshow(image - dilated)
ax3.set_title('image - dilated')
ax3.axis('off')
plt.tight_layout()
"""
.. image:: PLOT2RST.current_figure
Although the features (i.e. the coins) are clearly isolated, the coins
surrounded by a bright background in the original image are dimmer in the
subtracted image. We can attempt to correct this using a different seed image.
Instead of creating a seed image with maxima along the image border, we can use
the features of the image itself to seed the reconstruction process. Here, the
seed image is the original image minus a fixed value, ``h``.
"""
h = 0.4
seed = image - h
dilated = reconstruction(seed, mask, method='dilation')
hdome = image - dilated
"""
To get a feel for the reconstruction process, we plot the intensity of the
mask, seed, and dilated images along a slice of the image (indicated by red
line).
"""
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 2.5))
yslice = 197
ax1.plot(mask[yslice], '0.5', label='mask')
ax1.plot(seed[yslice], 'k', label='seed')
ax1.plot(dilated[yslice], 'r', label='dilated')
ax1.set_ylim(-0.2, 2)
ax1.set_title('image slice')
ax1.set_xticks([])
ax1.legend()
ax2.imshow(dilated, vmin=image.min(), vmax=image.max())
ax2.axhline(yslice, color='r', alpha=0.4)
ax2.set_title('dilated')
ax2.axis('off')
ax3.imshow(hdome)
ax3.axhline(yslice, color='r', alpha=0.4)
ax3.set_title('image - dilated')
ax3.axis('off')
plt.tight_layout()
plt.show()
"""
.. image:: PLOT2RST.current_figure
As you can see in the image slice, each coin is given a different baseline
intensity in the reconstructed image; this is because we used the local
intensity (shifted by ``h``) as a seed value. As a result, the coins in the
subtracted image have similar pixel intensities. The final result is known as
the h-dome of an image since this tends to isolate regional maxima of height
``h``. This operation is particularly useful when your images are unevenly
illuminated.
"""
+92
View File
@@ -0,0 +1,92 @@
"""
====================================================
Comparison of segmentation and superpixel algorithms
====================================================
This example compares three popular low-level image segmentation methods. As
it is difficult to obtain good segmentations, and the definition of "good"
often depends on the application, these methods are usually used for obtaining
an oversegmentation, also known as superpixels. These superpixels then serve as
a basis for more sophisticated algorithms such as conditional random fields
(CRF).
Felzenszwalb's efficient graph based segmentation
-------------------------------------------------
This fast 2D image segmentation algorithm, proposed in [1]_ is popular in the
computer vision community.
The algorithm has a single ``scale`` parameter that influences the segment
size. The actual size and number of segments can vary greatly, depending on
local contrast.
.. [1] Efficient graph-based image segmentation, Felzenszwalb, P.F. and
Huttenlocher, D.P. International Journal of Computer Vision, 2004
Quickshift image segmentation
-----------------------------
Quickshift is a relatively recent 2D image segmentation algorithm, based on an
approximation of kernelized mean-shift. Therefore it belongs to the family of
local mode-seeking algorithms and is applied to the 5D space consisting of
color information and image location [2]_.
One of the benefits of quickshift is that it actually computes a
hierarchical segmentation on multiple scales simultaneously.
Quickshift has two main parameters: ``sigma`` controls the scale of the local
density approximation, ``max_dist`` selects a level in the hierarchical
segmentation that is produced. There is also a trade-off between distance in
color-space and distance in image-space, given by ``ratio``.
.. [2] Quick shift and kernel methods for mode seeking,
Vedaldi, A. and Soatto, S.
European Conference on Computer Vision, 2008
SLIC - K-Means based image segmentation
---------------------------------------
This algorithm simply performs K-means in the 5d space of color information
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
of Quickshift, while ``n_segments`` chooses the number of centers for kmeans.
.. [3] Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi,
Pascal Fua, and Sabine Suesstrunk, SLIC Superpixels Compared to
State-of-the-art Superpixel Methods, TPAMI, May 2012.
"""
import matplotlib.pyplot as plt
import numpy as np
from skimage.data import lena
from skimage.segmentation import felzenszwalb, slic, quickshift
from skimage.segmentation import mark_boundaries
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_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
print("Felzenszwalb's number of segments: %d" % len(np.unique(segments_fz)))
print("Slic number of segments: %d" % len(np.unique(segments_slic)))
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)
ax[0].imshow(mark_boundaries(img, segments_fz))
ax[0].set_title("Felzenszwalbs's method")
ax[1].imshow(mark_boundaries(img, segments_slic))
ax[1].set_title("SLIC")
ax[2].imshow(mark_boundaries(img, segments_quick))
ax[2].set_title("Quickshift")
for a in ax:
a.set_xticks(())
a.set_yticks(())
plt.show()
+10 -6
View File
@@ -13,17 +13,17 @@ This example shows how to fill several different shapes:
import matplotlib.pyplot as plt
from skimage.draw import line, polygon, circle, ellipse
from skimage.draw import line, polygon, circle, circle_perimeter, ellipse
import numpy as np
img = np.zeros((500, 500, 3), 'uint8')
#: draw line
# draw line
rr, cc = line(120, 123, 20, 400)
img[rr,cc,0] = 255
#: fill polygon
# fill polygon
poly = np.array((
(300, 300),
(480, 320),
@@ -34,13 +34,17 @@ poly = np.array((
rr, cc = polygon(poly[:,0], poly[:,1], img.shape)
img[rr,cc,1] = 255
#: fill circle
# fill circle
rr, cc = circle(200, 200, 100, img.shape)
img[rr,cc,:] = (255, 255, 0)
#: fill ellipse
# fill ellipse
rr, cc = ellipse(300, 300, 100, 200, img.shape)
img[rr,cc,2] = 255
# circle
rr, cc = circle_perimeter(120, 400, 50)
img[rr, cc, :] = (255, 0, 255)
plt.imshow(img)
plt.show()
plt.show()
+1 -1
View File
@@ -16,7 +16,7 @@ In the case of boolean, 'True' indicates foreground, and for integer arrays,
the foreground is 1's.
"""
from skimage.morphology import skeletonize
from skimage.draw import draw
from skimage import draw
import numpy as np
import matplotlib.pyplot as plt
+1 -1
View File
@@ -26,7 +26,7 @@ See Wikipedia_ for more details on the algorithm.
"""
import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
from skimage.morphology import watershed, is_local_maximum
+45 -8
View File
@@ -9,7 +9,7 @@ To generate your own examples, add this extension to the list of
example directory(ies) in `plot2rst_paths` (see below) points to a directory
with examples named `plot_*.py` and include an `index.rst` file.
This code was adapted from scikits-image, which took it from scikits-learn.
This code was adapted from scikit-image, which took it from scikit-learn.
Options
-------
@@ -27,9 +27,10 @@ plot2rst_rcparams : dict
plot2rst_default_thumb : str
Path (relative to doc root) of default thumbnail image.
plot2rst_thumb_scale : float
Scale factor for thumbnail (e.g., 0.2 to scale plot to 1/5th the
original size).
plot2rst_thumb_shape : float
Shape of thumbnail in pixels. The image is resized to fit within this shape
and the excess is filled with white pixels. This fixed size ensures that
that gallery images are displayed in a grid.
plot2rst_plot_tag : str
When this tag is found in the example file, the current plot is saved and
@@ -68,12 +69,16 @@ import os
import shutil
import token
import tokenize
import traceback
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib import image
from skimage import io
from skimage import transform
from skimage.util.dtype import dtype_range
LITERALINCLUDE = """
@@ -160,7 +165,7 @@ def setup(app):
('../examples', 'auto_examples'), True)
app.add_config_value('plot2rst_rcparams', {}, True)
app.add_config_value('plot2rst_default_thumb', None, True)
app.add_config_value('plot2rst_thumb_scale', 0.25, True)
app.add_config_value('plot2rst_thumb_shape', (250, 300), True)
app.add_config_value('plot2rst_plot_tag', 'PLOT2RST.current_figure', True)
app.add_config_value('plot2rst_index_name', 'index', True)
@@ -243,7 +248,16 @@ def write_gallery(gallery_index, src_dir, rst_dir, cfg, depth=0):
gallery_index.write(TOCTREE_TEMPLATE % (sub_dir + '\n '.join(ex_names)))
for src_name in examples:
write_example(src_name, src_dir, rst_dir, cfg)
try:
write_example(src_name, src_dir, rst_dir, cfg)
except Exception:
print "Exception raised while running:"
print "%s in %s" % (src_name, src_dir)
print '~' * 60
traceback.print_exc()
print '~' * 60
continue
link_name = sub_dir.pjoin(src_name)
link_name = link_name.replace(os.path.sep, '_')
@@ -335,7 +349,8 @@ def write_example(src_name, src_dir, rst_dir, cfg):
thumb_path = thumb_dir.pjoin(src_name[:-3] + '.png')
first_image_file = image_dir.pjoin(figure_list[0].lstrip('/'))
if first_image_file.exists:
image.thumbnail(first_image_file, thumb_path, cfg.plot2rst_thumb_scale)
first_image = io.imread(first_image_file)
save_thumbnail(first_image, thumb_path, cfg.plot2rst_thumb_shape)
if not thumb_path.exists:
if cfg.plot2rst_default_thumb is None:
@@ -345,6 +360,28 @@ def write_example(src_name, src_dir, rst_dir, cfg):
shutil.copy(cfg.plot2rst_default_thumb, thumb_path)
def save_thumbnail(image, thumb_path, shape):
"""Save image as a thumbnail with the specified shape.
The image is first resized to fit within the specified shape and then
centered in an array of the specified shape before saving.
"""
rescale = min(float(w_1) / w_2 for w_1, w_2 in zip(shape, image.shape))
small_shape = (rescale * np.asarray(image.shape[:2])).astype(int)
small_image = transform.resize(image, small_shape)
if len(image.shape) == 3:
shape = shape + (image.shape[2],)
background_value = dtype_range[small_image.dtype.type][1]
thumb = background_value * np.ones(shape, dtype=small_image.dtype)
i = (shape[0] - small_shape[0]) // 2
j = (shape[1] - small_shape[1]) // 2
thumb[i:i+small_shape[0], j:j+small_shape[1]] = small_image
io.imsave(thumb_path, thumb)
def _plots_are_current(src_path, image_path):
first_image_file = Path(image_path.format(1))
needs_replot = (not first_image_file.exists or
+4 -4
View File
@@ -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:scikits-image/docs.git'
pages_repo = 'git@github.com:scikit-image/docs.git'
#-----------------------------------------------------------------------------
# Functions
@@ -108,7 +108,7 @@ if __name__ == '__main__':
shutil.copytree(html_dir, dest)
# copy pdf file into tree
#shutil.copy(pjoin(pdf_dir, 'scikits.image.pdf'), pjoin(dest, 'scikits.image.pdf'))
try:
cd(pages_dir)
status = sh2('git status | head -1')
@@ -117,7 +117,7 @@ if __name__ == '__main__':
e = 'On %r, git branch is %r, MUST be "gh-pages"' % (pages_dir,
branch)
raise RuntimeError(e)
sh("touch .nojekyll")
sh("touch .nojekyll")
sh('git add .nojekyll')
sh('git add index.html')
sh('git add %s' % tag)
@@ -131,4 +131,4 @@ if __name__ == '__main__':
print
print 'Now verify the build in: %r' % dest
print "If everything looks good, 'git push'"
print "If everything looks good, run 'git push' inside doc/gh-pages."
+2 -2
View File
@@ -1,11 +1,11 @@
.PHONY: logo
logo: green_orange_snake.png snake_logo.svg
inkscape --export-png=scikits_image_logo.png --export-dpi=100 \
inkscape --export-png=scikit_image_logo.png --export-dpi=100 \
--export-area-drawing --export-background-opacity=1 \
snake_logo.svg
python shrink_logo.py
green_orange_snake.png:
python scikits_image_logo.py --no-plot
python scikit_image_logo.py --no-plot
+2 -2
View File
@@ -2,7 +2,7 @@ from skimage import io, transform
s = 0.7
img = io.imread('scikits_image_logo.png')
img = io.imread('scikit_image_logo.png')
h, w, c = img.shape
print "\nScaling down logo by %.1fx..." % s
@@ -13,4 +13,4 @@ img = transform.homography(img, [[s, 0, 0],
output_shape=(int(h*s), int(w*s), 4),
order=3)
io.imsave('scikits_image_logo_small.png', img)
io.imsave('scikit_image_logo_small.png', img)
+1 -1
View File
@@ -74,7 +74,7 @@
y="278.58533"
x="261.22247"
id="tspan3152"
sodipodi:role="line">scikits-image</tspan></text>
sodipodi:role="line">scikit-image</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3154"

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

+2 -2
View File
@@ -74,9 +74,9 @@ if "%1" == "qthelp" (
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in build/qthelp, like this:
echo.^> qcollectiongenerator build\qthelp\scikitsimage.qhcp
echo.^> qcollectiongenerator build\qthelp\scikitimage.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile build\qthelp\scikitsimage.ghc
echo.^> assistant -collectionFile build\qthelp\scikitimage.ghc
goto end
)
+1 -1
View File
@@ -1,2 +1,2 @@
git log $1..HEAD --format='* %aN' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u
git log $1..HEAD --format='- %aN' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u
+69
View File
@@ -0,0 +1,69 @@
Announcement: scikits-image 0.7.0
=================================
We're happy to announce the 7th version of scikits-image!
Scikits-image is an image processing toolbox for SciPy that includes algorithms
for segmentation, geometric transformations, color space manipulation,
analysis, filtering, morphology, feature detection, and more.
For more information, examples, and documentation, please visit our website
http://skimage.org
New Features
------------
It's been only 3 months since scikits-image 0.6 was released, but in that short
time, we've managed to add plenty of new features and enhancements, including
- Geometric image transforms
- 3 new image segmentation routines (Felsenzwalb, Quickshift, SLIC)
- Local binary patterns for texture characterization
- Morphological reconstruction
- Polygon approximation
- CIE Lab color space conversion
- Image pyramids
- Multispectral support in random walker segmentation
- Slicing, concatenation, and natural sorting of image collections
- Perimeter and coordinates measurements in regionprops
- An extensible image viewer based on Qt and Matplotlib, with plugins for edge
detection, line-profiling, and viewing image collections
Plus, this release adds a number of bug fixes, new examples, and performance
enhancements.
Contributors to this release
----------------------------
This release was only possible due to the efforts of many contributors, both
new and old.
- Andreas Mueller
- Andreas Wuerl
- Andy Wilson
- Brian Holt
- Christoph Gohlke
- Dharhas Pothina
- Emmanuelle Gouillart
- Guillaume Gay
- Josh Warner
- James Bergstra
- Johannes Schonberger
- Jonathan J. Helmus
- Juan Nunez-Iglesias
- Leon Tietz
- Marianne Corvellec
- Matt McCormick
- Neil Yager
- Nicolas Pinto
- Nicolas Poilvert
- Pavel Campr
- Petter Strandmark
- Stefan van der Walt
- Tim Sheerman-Chase
- Tomas Kazmar
- Tony S Yu
- Wei Li
+71
View File
@@ -0,0 +1,71 @@
Announcement: scikits-image 0.8.0
=================================
We're happy to announce the 8th version of scikit-image!
scikit-image is an image processing toolbox for SciPy that includes algorithms
for segmentation, geometric transformations, color space manipulation,
analysis, filtering, morphology, feature detection, and more.
For more information, examples, and documentation, please visit our website:
http://scikit-image.org
New Features
------------
- New rank filter package with many new functions and a very fast underlying
local histogram algorithm, especially for large structuring elements
`skimage.filter.rank.*`
- New function for small object removal
`skimage.morphology.remove_small_objects`
- New circular hough transformation `skimage.transform.hough_circle`
- New function to draw circle perimeter `skimage.draw.circle_perimeter` and
ellipse perimeter `skimage.draw.ellipse_perimeter`
- New dense DAISY feature descriptor `skimage.feature.daisy`
- New bilateral filter `skimage.filter.denoise_bilateral`
- New faster TV denoising filter based on split-Bregman algorithm
`skimage.filter.denoise_tv_bregman`
- New linear hough peak detection `skimage.transform.hough_peaks`
- New Scharr edge detection `skimage.filter.scharr`
- New geometric image scaling as convenience function
`skimage.transform.rescale`
- New theme for documentation and website
- Faster median filter through vectorization `skimage.filter.median_filter`
- Grayscale images supported for SLIC segmentation
- Unified peak detection with more options `skimage.feature.peak_local_max`
- `imread` can read images via URL and knows more formats `skimage.io.imread`
Additionally, this release adds lots of bug fixes, new examples, and
performance enhancements.
Contributors to this release
----------------------------
This release was only possible due to the efforts of many contributors, both
new and old.
- Adam Ginsburg
- Anders Boesen Lindbo Larsen
- Andreas Mueller
- Christoph Gohlke
- Christos Psaltis
- Colin Lea
- François Boulogne
- Jan Margeta
- Johannes Schönberger
- Josh Warner (Mac)
- Juan Nunez-Iglesias
- Luis Pedro Coelho
- Marianne Corvellec
- Matt McCormick
- Nicolas Pinto
- Olivier Debeir
- Paul Ivanov
- Sergey Karayev
- Stefan van der Walt
- Steven Silvester
- Thouis (Ray) Jones
- Tony S Yu
-144
View File
@@ -1,144 +0,0 @@
/* This CSS stylesheet is no longer used. Edit agogo.css instead. */
/**
* Sphinx stylesheet -- default theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: {{ theme_bodyfont }};
font-size: 100%;
background-color: {{ theme_footerbgcolor }};
color: #000;
margin: 0;
padding: 0;
}
div.document {
background-color: {{ theme_sidebarbgcolor }};
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: {{ theme_bgcolor }};
color: {{ theme_textcolor }};
padding: 0 20px 30px 20px;
overflow: auto;
}
{%- if theme_rightsidebar|tobool %}
div.bodywrapper {
margin: 0 230px 0 0;
}
{%- endif %}
div.footer {
color: {{ theme_footertextcolor }};
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: {{ theme_footertextcolor }};
text-decoration: underline;
}
div.related {
background-color: {{ theme_relbarbgcolor }};
line-height: 30px;
color: {{ theme_relbartextcolor }};
}
div.related a {
color: {{ theme_relbarlinkcolor }};
}
div.sphinxsidebar {
{%- if theme_stickysidebar|tobool %}
top: 30px;
margin: 0;
position: fixed;
overflow: auto;
height: 100%;
{%- endif %}
{%- if theme_rightsidebar|tobool %}
float: right;
{%- if theme_stickysidebar|tobool %}
right: 0;
{%- endif %}
{%- endif %}
}
{%- if theme_stickysidebar|tobool %}
/* this is nice, but it it leads to hidden headings when jumping
to an anchor */
/*
div.related {
position: fixed;
}
div.documentwrapper {
margin-top: 30px;
}
*/
{%- endif %}
div.sphinxsidebar h3 {
font-family: {{ theme_headfont }};
color: {{ theme_sidebartextcolor }};
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar h4 {
font-family: {{ theme_headfont }};
color: {{ theme_sidebartextcolor }};
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar a {
color: {{ theme_sidebarlinkcolor }};
}
div.sphinxsidebar input {
border: 1px solid {{ theme_sidebarlinkcolor }};
font-family: sans-serif;
font-size: 1em;
}
@@ -1,7 +1,5 @@
function insert_version_links() {
var labels = ['dev', '0.6', '0.5', '0.4', '0.3'];
document.write('<ul class="versions">\n');
var labels = ['dev', '0.8.0', '0.7.0', '0.6', '0.5', '0.4', '0.3'];
for (i = 0; i < labels.length; i++){
open_list = '<li>'
@@ -14,7 +12,6 @@ function insert_version_links() {
document.write(open_list);
document.write('<a href="URL">skimage VERSION</a> </li>\n'
.replace('VERSION', labels[i])
.replace('URL', 'http://scikits-image.org/docs/' + labels[i]));
.replace('URL', 'http://scikit-image.org/docs/' + labels[i]));
}
document.write('</ul>\n');
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

-6
View File
@@ -1,6 +0,0 @@
{% extends "!layout.html" %}
{% block rootrellink %}
<li><a href={{ pathto('index') }}>scikits-image home</a> &raquo;</li>
{{ super() }}
{% endblock %}
+6 -4
View File
@@ -1,8 +1,10 @@
{% if pagename != 'index' %}
{%- if display_toc %}
<h3>Contents</h3>
{{ toc }}
{%- endif %}
{%- if display_toc %}
<h4 class="sidebar-box-heading">Contents</h4>
<div class="well sidebar-box toc">
{{ toc|replace('<ul>', '<ul class="nav nav-list">') }}
</div>
{%- endif %}
{% endif %}
+5
View File
@@ -0,0 +1,5 @@
<li><a href="/">Home</a></li>
<li><a href="/download.html">Download</a></li>
<li><a href="/docs/dev/auto_examples">Gallery</a></li>
<li><a href="/docs/dev">Documentation</a></li>
<li><a href="https://github.com/scikit-image/scikit-image">Source</a></li>
+22 -12
View File
@@ -1,12 +1,22 @@
{%- block navigation %}
{% if pagename != 'index' %}
<h3>Navigation</h3>
<p>
<a href="{{ pathto(master_doc) }}">Documentation Home</a>
</p>
<p>&nbsp;</p>
{% endif %}
{%- endblock %}
<h4 class="sidebar-box-heading">{{ _('Navigation') }}</h4>
<div class="well sidebar-box">
<ul class="nav nav-list">
<li><a href="{{ pathto(master_doc) }}">Documentation Home</a></li>
</ul>
</div>
{%- if prev %}
<h4 class="sidebar-box-heading">{{ _('Previous topic') }}</h4>
<div class="well sidebar-box">
<ul class="nav nav-list">
<li><a href="{{ prev.link|e }}" title="{{ _('previous chapter') }}">{{ prev.title }}</a></li>
</ul>
</div>
{%- endif %}
{%- if next %}
<h4 class="sidebar-box-heading">{{ _('Next topic') }}</h4>
<div class="well sidebar-box">
<ul class="nav nav-list">
<li><a href="{{ next.link|e }}" title="{{ _('next chapter') }}">{{ next.title }}</a></li>
</ul>
</div>
{%- endif %}
+9 -9
View File
@@ -1,9 +1,9 @@
{%- block versions %}
<h3>Version</h3>
<script type="text/javascript">
insert_version_links();
</script>
{%- endblock %}
<h4 class="sidebar-box-heading">{{ _('Versions') }}</h4>
<div class="well sidebar-box">
<ul class="nav nav-list">
<script src="{{ pathto('_static/', 1) }}docversions.js"></script>
<script type="text/javascript">
insert_version_links();
</script>
</ul>
</div>
+1 -1
View File
@@ -4,7 +4,7 @@ CellProfiler BSD license announcement
::
From: Vebjorn Ljosa
To: scikits-image@googlegroups.com
To: scikit-image@googlegroups.com
Date: June 3, 2010
We have changed the license of some parts of CellProfiler from GNU GPL
+18 -15
View File
@@ -26,7 +26,8 @@ sys.path.append(os.path.join(curpath, '..', 'ext'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.pngmath', 'numpydoc',
'sphinx.ext.autosummary', 'plot_directive', 'plot2rst']
'sphinx.ext.autosummary', 'plot_directive', 'plot2rst',
'sphinx.ext.intersphinx']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -42,7 +43,7 @@ master_doc = 'index'
# General information about the project.
project = u'skimage'
copyright = u'2011, the scikits-image team'
copyright = u'2011, the scikit-image team'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -102,8 +103,7 @@ pygments_style = 'sphinx'
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'agogo'
html_style = 'agogo.css'
html_theme = 'scikit-image'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -120,10 +120,6 @@ html_title = 'skimage v%s docs' % version
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = "scikits_image_logo_small.png"
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
@@ -146,9 +142,7 @@ html_static_path = ['_static']
html_sidebars = {
'**': ['navigation.html',
'localtoc.html',
'relations.html',
'versions.html',
'searchbox.html'],
'versions.html'],
}
# Additional templates that should be rendered to pages, maps page names to
@@ -182,7 +176,7 @@ html_sidebars = {
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'scikitsimagedoc'
htmlhelp_basename = 'scikitimagedoc'
# -- Options for LaTeX output --------------------------------------------------
@@ -196,7 +190,7 @@ htmlhelp_basename = 'scikitsimagedoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('contents', 'scikitsimage.tex', u'The Image Scikit Documentation',
('contents', 'scikitimage.tex', u'The Image Scikit Documentation',
u'SciPy Developers', 'manual'),
]
@@ -220,8 +214,7 @@ latex_documents = [
# -----------------------------------------------------------------------------
# Numpy extensions
# -----------------------------------------------------------------------------
# Make numpydoc to generate plots for example sections
#numpydoc_use_plots = True
numpydoc_show_class_members = False
# -----------------------------------------------------------------------------
# Plots
@@ -256,3 +249,13 @@ plot2rst_index_name = 'README'
plot2rst_rcparams = {'image.cmap' : 'gray',
'image.interpolation' : 'none'}
# -----------------------------------------------------------------------------
# intersphinx
# -----------------------------------------------------------------------------
_python_doc_base = 'http://docs.python.org/2.7'
intersphinx_mapping = {
_python_doc_base: None,
'http://docs.scipy.org/doc/numpy': None,
'http://docs.scipy.org/doc/scipy/reference': None,
'http://scikit-learn.org/stable': None
}
+9 -9
View File
@@ -4,14 +4,14 @@
Development workflow
####################
You already have your own forked copy of the scikits-image_ repository, by
You already have your own forked copy of the scikit-image_ repository, by
following :ref:`forking`. You have :ref:`set-up-fork`. You have configured
git by following :ref:`configure-git`. Now you are ready for some real work.
Workflow summary
================
In what follows we'll refer to the upstream scikits-image ``master`` branch, as
In what follows we'll refer to the upstream scikit-image ``master`` branch, as
"trunk".
* Don't use your ``master`` branch for anything. Consider deleting it.
@@ -22,9 +22,9 @@ In what follows we'll refer to the upstream scikits-image ``master`` branch, as
* Name your branch for the purpose of the changes - e.g.
``bugfix-for-issue-14`` or ``refactor-database-code``.
* If you can possibly avoid it, avoid merging trunk or any other branches into
your feature branch while you are working.
your feature branch while you are working.
* If you do find yourself merging from trunk, consider :ref:`rebase-on-trunk`
* Ask on the `scikits-image mailing list`_ if you get stuck.
* Ask on the `scikit-image mailing list`_ if you get stuck.
* Ask for code review!
This way of working helps to keep work well organized, with readable history.
@@ -81,7 +81,7 @@ what the changes in the branch are for. For example ``add-ability-to-fly``, or
git checkout my-new-feature
Generally, you will want to keep your feature branches on your public github_
fork of scikits-image_. To do this, you `git push`_ this new branch up to your
fork of scikit-image_. To do this, you `git push`_ this new branch up to your
github repo. Generally (if you followed the instructions in these pages, and by
default), git will have a link to your github repo, called ``origin``. You push
up to your own repo on github with::
@@ -150,7 +150,7 @@ Ask for your changes to be reviewed or merged
When you are ready to ask for someone to review your code and consider a merge:
#. Go to the URL of your forked repo, say
``http://github.com/your-user-name/scikits-image``.
``http://github.com/your-user-name/scikit-image``.
#. Use the 'Switch Branches' dropdown menu near the top left of the page to
select the branch with your changes:
@@ -192,10 +192,10 @@ If you want to work on some stuff with other people, where you are all
committing into the same repository, or even the same branch, then just
share it via github.
First fork scikits-image into your account, as from :ref:`forking`.
First fork scikit-image into your account, as from :ref:`forking`.
Then, go to your forked repository github page, say
``http://github.com/your-user-name/scikits-image``
``http://github.com/your-user-name/scikit-image``
Click on the 'Admin' button, and add anyone else to the repo as a
collaborator:
@@ -204,7 +204,7 @@ collaborator:
Now all those people can do::
git clone git@githhub.com:your-user-name/scikits-image.git
git clone git@githhub.com:your-user-name/scikit-image.git
Remember that links starting with ``git@`` use the ssh protocol and are
read-write; links starting with ``git://`` are read-only.
+6 -6
View File
@@ -5,12 +5,12 @@
=============================
These are the instructions if you just want to follow the latest
*scikits-image* source, but you don't need to do any development for now.
*scikit-image* source, but you don't need to do any development for now.
The steps are:
* :ref:`install-git`
* get local copy of the `scikits-image github`_ git repository
* get local copy of the `scikit-image github`_ git repository
* update local copy from time to time
Get the local copy of the code
@@ -18,19 +18,19 @@ Get the local copy of the code
From the command line::
git clone git://github.com/scikits-image/scikits-image.git
git clone git://github.com/scikit-image/scikit-image.git
You now have a copy of the code tree in the new ``scikits-image`` directory.
You now have a copy of the code tree in the new ``scikit-image`` directory.
Updating the code
=================
From time to time you may want to pull down the latest code. Do this with::
cd scikits-image
cd scikit-image
git pull
The tree in ``scikits-image`` will now have the latest changes from the initial
The tree in ``scikit-image`` will now have the latest changes from the initial
repository.
.. include:: links.inc
+5 -5
View File
@@ -1,13 +1,13 @@
.. _forking:
============================================
Making your own copy (fork) of scikits-image
Making your own copy (fork) of scikit-image
============================================
You need to do this only once. The instructions here are very similar
to the instructions at http://help.github.com/forking/ |emdash| please see
that page for more detail. We're repeating some of it here just to give the
specifics for the scikits-image_ project, and to suggest some default names.
specifics for the scikit-image_ project, and to suggest some default names.
Set up and configure a github account
======================================
@@ -17,17 +17,17 @@ If you don't have a github account, go to the github page, and make one.
You then need to configure your account to allow write access |emdash| see
the ``Generating SSH keys`` help on `github help`_.
Create your own forked copy of scikits-image_
Create your own forked copy of scikit-image_
=============================================
#. Log into your github account.
#. Go to the scikits-image_ github home at `scikits-image github`_.
#. Go to the scikit-image_ github home at `scikit-image github`_.
#. Click on the *fork* button:
.. image:: forking_button.png
Now, after a short pause and some 'Hardcore forking action', you
should find yourself at the home page for your own forked copy of scikits-image_.
should find yourself at the home page for your own forked copy of scikit-image_.
.. include:: links.inc
+2 -2
View File
@@ -2,11 +2,11 @@
Introduction
==============
These pages describe a git_ and github_ workflow for the scikits-image_
These pages describe a git_ and github_ workflow for the scikit-image_
project.
There are several different workflows here, for different ways of
working with *scikits-image*.
working with *scikit-image*.
This is not a comprehensive git reference, it's just a workflow for our
own project. It's tailored to the github hosting service. You may well
+1 -1
View File
@@ -1,6 +1,6 @@
.. _using-git:
Working with *scikits-image* source code
Working with *scikit-image* source code
========================================
Contents:
+2 -2
View File
@@ -16,7 +16,7 @@ access to the upstream repo. Being a maintainer, you've got read-write access.
It's good to have your upstream remote have a scary name, to remind you that
it's a read-write remote::
git remote add upstream-rw git@github.com:scikits-image/scikits-image.git
git remote add upstream-rw git@github.com:scikit-image/scikit-image.git
git fetch upstream-rw
*******************
@@ -29,7 +29,7 @@ Let's say you have some changes that need to go into trunk
The changes are in some branch that you are currently on. For example, you are
looking at someone's changes like this::
git remote add someone git://github.com/someone/scikits-image.git
git remote add someone git://github.com/someone/scikit-image.git
git fetch someone
git branch cool-feature --track someone/cool-feature
git checkout cool-feature
+10 -10
View File
@@ -3,7 +3,7 @@
================
You've discovered a bug or something else you want to change
in scikits-image_ .. |emdash| excellent!
in scikit-image_ .. |emdash| excellent!
You've worked out a way to fix it |emdash| even better!
@@ -29,9 +29,9 @@ Overview
git config --global user.email you@yourdomain.example.com
git config --global user.name "Your Name Comes Here"
# get the repository if you don't have it
git clone git://github.com/scikits-image/scikits-image.git
git clone git://github.com/scikit-image/scikit-image.git
# make a branch for your patching
cd scikits-image
cd scikit-image
git branch the-fix-im-thinking-of
git checkout the-fix-im-thinking-of
# hack, hack, hack
@@ -44,7 +44,7 @@ Overview
# make the patch files
git format-patch -M -C master
Then, send the generated patch files to the `scikits-image
Then, send the generated patch files to the `scikit-image
mailing list`_ |emdash| where we will thank you warmly.
In detail
@@ -57,10 +57,10 @@ In detail
git config --global user.name "Your Name Comes Here"
#. If you don't already have one, clone a copy of the
scikits-image_ repository::
scikit-image_ repository::
git clone git://github.com/scikits-image/scikits-image.git
cd scikits-image
git clone git://github.com/scikit-image/scikit-image.git
cd scikit-image
#. Make a 'feature branch'. This will be where you work on
your bug fix. It's nice and safe and leaves you with
@@ -100,7 +100,7 @@ In detail
0001-BF-added-tests-for-Funny-bug.patch
0002-BF-added-fix-for-Funny-bug.patch
Send these files to the `scikits-image mailing list`_.
Send these files to the `scikit-image mailing list`_.
When you are done, to switch back to the main copy of the
code, just return to the ``master`` branch::
@@ -115,7 +115,7 @@ more feature branches, you will probably want to switch to
development mode. You can do this with the repository you
have.
Fork the scikits-image_ repository on github |emdash| :ref:`forking`.
Fork the scikit-image_ repository on github |emdash| :ref:`forking`.
Then::
# checkout and refresh master branch from main repo
@@ -124,7 +124,7 @@ Then::
# rename pointer to main repository to 'upstream'
git remote rename origin upstream
# point your repo to default read / write to your fork on github
git remote add origin git@github.com:your-user-name/scikits-image.git
git remote add origin git@github.com:your-user-name/scikit-image.git
# push up any branches you've made and want to keep
git push origin the-fix-im-thinking-of
+13 -13
View File
@@ -11,9 +11,9 @@ Overview
::
git clone git@github.com:your-user-name/scikits-image.git
cd scikits-image
git remote add upstream git://github.com/scikits-image/scikits-image.git
git clone git@github.com:your-user-name/scikit-image.git
cd scikit-image
git remote add upstream git://github.com/scikit-image/scikit-image.git
In detail
=========
@@ -22,8 +22,8 @@ Clone your fork
---------------
#. Clone your fork to the local computer with ``git clone
git@github.com:your-user-name/scikits-image.git``
#. Investigate. Change directory to your new repo: ``cd scikits-image``. Then
git@github.com:your-user-name/scikit-image.git``
#. Investigate. Change directory to your new repo: ``cd scikit-image``. Then
``git branch -a`` to show you all branches. You'll get something
like::
@@ -35,7 +35,7 @@ Clone your fork
What remote repository is ``remote/origin``? Try ``git remote -v`` to
see the URLs for the remote. They will point to your github fork.
Now you want to connect to the upstream `scikits-image github`_ repository, so
Now you want to connect to the upstream `scikit-image github`_ repository, so
you can merge in changes from trunk.
.. _linking-to-upstream:
@@ -45,11 +45,11 @@ Linking your repository to the upstream repo
::
cd scikits-image
git remote add upstream git://github.com/scikits-image/scikits-image.git
cd scikit-image
git remote add upstream git://github.com/scikit-image/scikit-image.git
``upstream`` here is just the arbitrary name we're using to refer to the
main scikits-image_ repository at `scikits-image github`_.
main scikit-image_ repository at `scikit-image github`_.
Note that we've used ``git://`` for the URL rather than ``git@``. The
``git://`` URL is read only. This means we that we can't accidentally
@@ -59,10 +59,10 @@ use it to merge into our own code.
Just for your own satisfaction, show yourself that you now have a new
'remote', with ``git remote -v show``, giving you something like::
upstream git://github.com/scikits-image/scikits-image.git (fetch)
upstream git://github.com/scikits-image/scikits-image.git (push)
origin git@github.com:your-user-name/scikits-image.git (fetch)
origin git@github.com:your-user-name/scikits-image.git (push)
upstream git://github.com/scikit-image/scikit-image.git (fetch)
upstream git://github.com/scikit-image/scikit-image.git (push)
origin git@github.com:your-user-name/scikit-image.git (fetch)
origin git@github.com:your-user-name/scikit-image.git (push)
.. include:: links.inc
+4 -4
View File
@@ -1,5 +1,5 @@
.. scikits-image
.. _scikits-image: http://scikits-image.org
.. _`scikits-image github`: http://github.com/scikits-image/scikits-image
.. scikit-image
.. _scikit-image: http://scikit-image.org
.. _`scikit-image github`: http://github.com/scikit-image/scikit-image
.. _`scikits-image mailing list`: http://groups.google.com/group/scikits-image
.. _`scikit-image mailing list`: http://groups.google.com/group/scikit-image
+8 -10
View File
@@ -1,8 +1,6 @@
Pre-built installation
----------------------
.. !! Also update scikits-image-web !!
`Windows binaries
<http://www.lfd.uci.edu/~gohlke/pythonlibs/#scikits.image>`__
are kindly provided by Christoph Gohlke.
@@ -12,37 +10,37 @@ Distribution (EPD) <http://enthought.com/products/epd.php>`__ and `Python(x,y)
<http://code.google.com/p/pythonxy/wiki/Welcome>`__.
On systems that support setuptools, the package can be installed from the
`Python packaging index <http://pypi.python.org/pypi/scikits-image>`__ using
`Python packaging index <http://pypi.python.org/pypi/scikit-image>`__ using
::
easy_install -U scikits-image
easy_install -U scikit-image
or
::
pip -U scikits-image
pip install -U scikit-image
Installation from source
------------------------
Obtain the source from the git-repository at
`http://github.com/scikits-image/scikits-image
<http://github.com/scikits-image/scikits-image>`_.
`http://github.com/scikit-image/scikit-image
<http://github.com/scikit-image/scikit-image>`_.
by running
::
git clone http://github.com/scikits-image/scikits-image.git
git clone http://github.com/scikit-image/scikit-image.git
in a terminal (You will need to have git installed on your machine).
If you do not have git installed, you can also download a zipball from
`https://github.com/scikits-image/scikits-image/zipball/master
<https://github.com/scikits-image/scikits-image/zipball/master>`_.
`https://github.com/scikit-image/scikit-image/zipball/master
<https://github.com/scikit-image/scikit-image/zipball/master>`_.
The SciKit can be installed globally using
+4 -4
View File
@@ -1,7 +1,7 @@
Image Processing SciKit
=======================
The `scikits-image <http://scikits-image.org>`__ SciKit (toolkit for
The `scikit-image <http://scikit-image.org>`__ SciKit (toolkit for
`SciPy <http://www.scipy.org>`__) extends ``scipy.ndimage`` to provide
a versatile set of image processing routines. It is written in the
`Python <http://www.python.org>`_ language.
@@ -12,15 +12,15 @@ mailing list (address provided below).
Homepage
--------
http://scikits-image.org
http://scikit-image.org
Source, bugs and patches
------------------------
http://github.com/scikits-image/scikits-image
http://github.com/scikit-image/scikit-image
Mailing List
------------
http://groups.google.com/group/scikits-image
http://groups.google.com/group/scikit-image
Contact
-------
+2 -2
View File
@@ -32,8 +32,8 @@ gallery_div = '''\
examples = glob.glob(os.path.join(example_dir, 'plot_*.py'))
images, links = [], []
image_url = 'http://scikits-image.org/docs/dev/_images/%s.png'
link_url = 'http://scikits-image.org/docs/dev/auto_examples/%s.html'
image_url = 'http://scikit-image.org/docs/dev/_images/%s.png'
link_url = 'http://scikit-image.org/docs/dev/auto_examples/%s.html'
for e in examples:
e = os.path.basename(e)
-58
View File
@@ -1,58 +0,0 @@
{#
agogo/layout.html
~~~~~~~~~~~~~~~~~
Sphinx layout template for the agogo theme, originally written
by Andi Albrecht.
:copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{% extends "basic/layout.html" %}
{% set script_files = script_files + ['_static/docversions.js'] %}
{% block header %}
<div class="header-wrapper">
<div class="header">
{%- block headertitle %}
{%- if logo %}
<div class="logo"><a href="http://scikits-image.org">
<img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
</a></div>
{%- endif %}
{# <h1><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a></h1> #}
{%- endblock %}
</div>
</div>
{% endblock %}
{% block content %}
<div class="content-wrapper">
<div class="content">
{%- block sidebar2 %}
{# We don't want the logo here #}
{%- block sidebarlogo %} {% endblock %}
{{ sidebar() }}
{% endblock %}
<div class="document">
{%- block document %}
{{ super() }}
{%- endblock %}
</div>
<div class="clearer"></div>
</div>
</div>
{% endblock %}
{% block footer %}
<div class="footer-wrapper">
{{ super() }}
</div>
{% endblock %}
{% block relbar1 %}{% endblock %}
{% block relbar2 %}{% endblock %}
-753
View File
@@ -1,753 +0,0 @@
/*
* agogo.css_t
* ~~~~~~~~~~~
*
* Sphinx stylesheet -- agogo theme.
*
* :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
* {
margin: 0px;
padding: 0px;
}
div.header-wrapper {
border-top: 0px solid #babdb6;
padding: 1em 1em 0;
min-height: 0px;
}
body {
font-family: {{ theme_bodyfont }};
line-height: 1.4em;
color: black;
background-color: {{ theme_bgcolor }};
}
/* Page layout */
div.header, div.content, div.footer {
max-width: {{ theme_pagewidth }};
margin-left: auto;
margin-right: auto;
}
div.header-wrapper {
border-bottom: 0px solid #2e3436;
}
/* Default body styles */
a {
color: {{ theme_linkcolor }};
}
div.bodywrapper a, div.footer a {
text-decoration: underline;
}
.clearer {
clear: both;
}
.left {
float: left;
}
.right {
float: right;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
h1, h2, h3, h4 {
font-weight: normal;
color: {{ theme_headercolor2 }};
margin-bottom: .8em;
clear: left;
}
h1 {
color: {{ theme_headercolor1 }};
line-height: 1.1em;
text-align: left;
}
h2 {
padding-bottom: .5em;
color: {{ theme_headercolor1 }};
border-bottom: 1px solid {{ theme_headercolor1 }};
}
a.headerlink {
visibility: hidden;
color: #dddddd;
padding-left: .3em;
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink {
visibility: visible;
}
img {
border: 0;
}
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 2px 7px 1px 7px;
border-left: 0.2em solid black;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
dt:target, .highlighted {
background-color: #fbe54e;
}
/* Header */
div.header {}
div.header h1 {
font-family: "Trebuchet MS", Helvetica, sans-serif;
font-weight: normal;
font-size: 250%;
letter-spacing: .08em;
line-height: 70px;
margin-bottom: 0;
}
div.header h1 a {
color: white;
}
div.header h1 a:hover {
text-decoration: none;
}
div.header div.rel {
margin-top: 1em;
border-top: 1px solid #AAA;
border-bottom: 1px solid #AAA;
border-radius: 5px;
padding: 3px 1em;
}
div.header div.rel a {
color: {{ theme_linkcolor }};
letter-spacing: .05em;
font-weight: bold;
}
div.logo {}
img.logo {
border: 0;
}
/* Content */
div.content-wrapper {
background-color: white;
padding: 1em;
}
div.document {
max-width: {{ theme_documentwidth }};
}
div.body {
padding-right: 2em;
min-width: 20em;
overflow: hidden;
font-size: 90%;
text-align: {{ theme_textalign }};
}
div.document ul {
margin: 1.5em;
list-style-type: square;
}
div.document dd {
margin-left: 1.2em;
margin-top: .4em;
margin-bottom: 1em;
}
div.document .section {
margin-top: 1.7em;
}
div.document .section:first-child {
margin-top: 0px;
}
div.document div.highlight {
padding: 3px;
background-color: #eeeeec;
border-top: 2px solid #dddddd;
border-bottom: 2px solid #dddddd;
margin-top: .8em;
margin-bottom: .8em;
}
div.document h2 {
margin-top: .7em;
}
div.document p {
margin-bottom: 1.5em;
}
div.document li.toctree-l1 {
margin-bottom: 1em;
}
div.document .descname {
font-weight: bold;
}
div.document .docutils.literal {
background-color: #eeeeec;
padding: 1px;
}
div.document .docutils.xref.literal {
background-color: transparent;
padding: 0px;
}
div.document blockquote {
margin: 1em;
}
div.document ol {
margin: 1.5em;
}
/* Sidebar */
div.sphinxsidebar {
width: {{ theme_sidebarwidth }};
padding: 0 1em;
float: right;
font-size: .93em;
background-color: white;
}
div.sphinxsidebar a, div.header a {
text-decoration: none;
}
div.sphinxsidebar a:hover, div.header a:hover {
text-decoration: underline;
}
div.sphinxsidebar h3 {
color: #2e3436;
text-transform: uppercase;
font-size: 130%;
letter-spacing: .1em;
margin-bottom: .4em;
}
div.sphinxsidebar h4 {
margin-bottom: 0;
font-weight: bold;
}
div.sphinxsidebar .tile {
border: 1px solid #D1DDE2;
border-radius: 10px;
background-color: #E1E8EC;
padding-left: 0.5em;
margin: 1em 0;
}
div.sphinxsidebar ul {
margin-bottom: 1.5em;
list-style-type: none;
}
div.sphinxsidebar li.toctree-l1 a {
display: block;
padding: 1px;
border: 1px solid #dddddd;
background-color: #eeeeec;
margin-bottom: .4em;
padding-left: 3px;
color: #2e3436;
}
div.sphinxsidebar li.toctree-l2 a {
background-color: transparent;
border: none;
margin-left: 1em;
border-bottom: 1px solid #dddddd;
}
div.sphinxsidebar li.toctree-l3 a {
background-color: transparent;
border: none;
margin-left: 2em;
border-bottom: 1px solid #dddddd;
}
div.sphinxsidebar li.toctree-l2:last-child a {
border-bottom: none;
}
div.sphinxsidebar li.toctree-l1.current a {
border-right: 5px solid {{ theme_headerlinkcolor }};
}
div.sphinxsidebar li.toctree-l1.current li.toctree-l2 a {
border-right: none;
}
div.sidebarblock {
padding-bottom: .4em;
border-bottom: 1px solid #AAA;
margin-bottom: .8em;
}
ul.versions li {
color: gray;
list-style: circle inside;
}
ul.versions li#current {
list-style: disc inside;
}
/* Footer */
div.footer-wrapper {
padding-top: 10px;
padding-bottom: 10px;
}
div.footer {
border-top: 2px solid #aaa;
text-align: right;
}
div.footer, div.footer a {
color: #888a85;
}
.figure {
float: left;
margin: 1em;
}
.figure img {
display: block;
margin-left: auto;
margin-right: auto;
max-height: 150px;
}
.figure .caption {
width: 200px;
text-align: center !important;
}
/* Styles copied from basic theme */
img.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
clear: both;
text-align: center;
}
.align-right {
text-align: right;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li div.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable p.biglink {
line-height: 150%;
}
table.contentstable, table.contentstable td, table.contentstable th {
border-style: none;
}
div.body table.contentstable p {
margin: 0.5em;
text-align: left;
}
table.contentstable a {
text-decoration: none;
font-size: 120%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable dl, table.indextable dd {
margin-top: 0;
margin-bottom: 0;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
/* -- viewcode extension ---------------------------------------------------- */
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family:: {{ theme_bodyfont }};
}
div.viewcode-block:target {
margin: -1px -3px;
padding: 0 3px;
background-color: #f4debf;
border-top: 1px solid #ac9;
border-bottom: 1px solid #ac9;
}
span.strike { text-decoration: line-through; }
/* -- body styles ----------------------------------------------------------- */
a {
color: {{ theme_linkcolor }};
text-decoration: none;
}
a:visited {
color: {{ theme_visitedlinkcolor }};
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: {{ theme_headfont }};
background-color: {{ theme_headbgcolor }};
font-weight: normal;
color: {{ theme_headtextcolor }};
border-bottom: 1px solid #ccc;
margin: 20px 20px 10px 0px;
padding: 3px 0 3px 0px;
}
div.body h1 { margin-top: 0; font-size: 180%; }
div.body h2 { font-size: 150%; }
div.body h3 { font-size: 130%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: {{ theme_headlinkcolor }};
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: {{ theme_headlinkcolor }};
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.note {
background-color: #eee;
border: 1px solid #ccc;
}
div.seealso {
background-color: #ffc;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #ffe4e4;
border: 1px solid #f66;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
pre {
padding: 1em;
margin-bottom: 0.5em;
background-color: {{ theme_codebgcolor }};
color: {{ theme_codetextcolor }};
line-height: 120%;
border: 0px solid #ac9;
border-left: none;
border-right: none;
}
sup {
font-size: x-small;
line-height: 0;
}
tt {
background-color: #ecf0f3;
padding: 0 1px 0 1px;
font-size: 1em;
}
table {
border-collapse: collapse;
margin-bottom: 1em;
margin-top: 1em;
}
table, th, td {
border: 1px solid #ccc;
}
th, td {
padding: 5px;
}
th {
color: #333;
background-color: #eee;
}
#api-reference ul:first-child {
float: left;
width: 35em;
margin-top: 0;
padding-top: 0;
list-style: none;
overflow: auto;
}
#api-reference li {
float: left;
position: relative;
margin-right: 1em;
width: 17em;
padding: 0;
}
.field-list {
font-size: 80%;
}
/* ----------------- Example Gallery ----------------- */
.gallery {
height: 200px;
}
.gallery p.caption a{
text-decoration: none;
}
/* ----------------- Coverage States ----------------- */
span.missing{
color: #000;
background-color: #ff5840;
border-color: #A77272;
font-weight: bold;
}
span.partial{
color: #806600;
background-color: #ffc343;
font-weight: bold;
}
span.done{
color: #106600;
background-color: #60f030;
border-color: #4F8530;
font-weight: bold;
}
span.na{
color: #A8A8A8;
border-color: #4F8530;
}
table.coverage {
border: solid 1px;
}
td.missing-bar{
color: #ff5840;
background-color: #ff5840;
border-color: #A77272;
font-weight: normal;
font-style: normal;
}
td.partial-bar{
color: #ffc343;
background-color: #ffc343;
font-weight: normal;
font-style: normal;
}
td.done-bar{
color: #60f030;
background-color: #60f030;
border-color: #4F8530;
font-weight: normal;
font-style: normal;
}
td.na-bar{
color: #FFF;
background-color: #FFF;
border-color: #4F8530;
font-weight: normal;
font-style: normal;
}
/* Adjust doc headers such as Notes, References, etc. */
p.rubric {
font-weight: bold;
font-size: 120%;
}
/* Math */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
-19
View File
@@ -1,19 +0,0 @@
[theme]
inherit = basic
stylesheet = agogo.css
pygments_style = tango
[options]
bodyfont = "Verdana", Arial, sans-serif
pagewidth = 70em
documentwidth = 55em
sidebarwidth = 14em
bgcolor = white
headerbg = url(bgtop.png) top left repeat-x
footerbg = url(bgfooter.png) top left repeat-x
linkcolor = #FC852B
headercolor1 = #555
headercolor2 = #555
headerlinkcolor = #fcaf3e
codebgcolor = #EEE
textalign = justify
+113
View File
@@ -0,0 +1,113 @@
{#
scikit-image/layout.html
~~~~~~~~~~~~~~~~~
Sphinx layout template for the scikit-image theme, written by
Johannes Schönberger.
#}
{%- set url_root = pathto('', 1) %}
{# XXX necessary? #}
{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
{%- if not embedded and docstitle %}
{%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
{%- else %}
{%- set titlesuffix = "" %}
{%- endif %}
{%- macro script() %}
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="{{ pathto('_static/', 1) }}js/bootstrap.min.js"></script>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ url_root }}',
VERSION: '{{ release|e }}',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
HAS_SOURCE: {{ has_source|lower }}
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{%- endmacro %}
{%- macro css() %}
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
<link href="{{ pathto('_static/', 1) }}css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="{{ pathto('_static/', 1) }}css/custom.css" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Raleway" rel="stylesheet" type="text/css">
{%- for cssfile in css_files %}
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
{%- endfor %}
{%- endmacro %}
<!DOCTYPE html>
<html lang="en">
<head>
{%- block htmltitle %}
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
{%- endblock %}
{{ metatags }}
{{ css() }}
{{ script() }}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
{%- endif %}
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link rel="shortcut icon" href="{{ pathto('_static/', 1) }}favicon.ico">
{%- block extrahead %}{% endblock %}
</head>
<body class="container">
<a href="http://scikit-image.org" class="logo"><img src="{{ pathto('_static/', 1) }}img/logo.png" alt=""></a>
<div class="clearfix"></div>
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
{% include 'navbar.html' %}
</ul>
<form class="navbar-form pull-right" action="{{ pathto('search') }}" method="get">
<input type="text" class="search span3" name="q" placeholder="Search documentation ...">
<input type="hidden" name="check_keywords" value="yes" >
<input type="hidden" name="area" value="default" >
</form>
</div>
</div>
<div class="row">
<div class="span9">
{% block body %}{% endblock %}
</div>
<div class="span3">
{%- for sidebartemplate in sidebars %}
{%- include sidebartemplate %}
{%- endfor %}
</div>
</div>
<div class="well footer">
<small>
&copy; Copyright the scikit-image development team.
Created using <a href="http://twitter.github.com/bootstrap/">Bootstrap</a> and <a href="http://sphinx.pocoo.org/">Sphinx</a>.
</small>
</div>
</body>
</html>
@@ -0,0 +1,46 @@
{#
basic/search.html
~~~~~~~~~~~~~~~~~
Template for the search page.
:copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{% extends "layout.html" %}
{% set title = _('Search') %}
{% set script_files = script_files + ['_static/searchtools.js'] %}
{% set script_files = script_files + ['searchindex.js'] %}
{% block body %}
<h1 id="search-documentation">{{ _('Search') }}</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">
$('#fallback').hide();
$("input.search").focus();
</script>
<p>
{% trans %}Please activate JavaScript to enable the search
functionality.{% endtrans %}
</p>
</div>
<p>
{% trans %}From here you can search these documents. Enter your search
words into the box in the navigation bar and press "Enter". Note that the
search function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.{% endtrans %}
</p>
{% if search_performed %}
{% if not search_results %}
<p>{{ _('Your search did not match any results.') }}</p>
{% endif %}
{% endif %}
<div id="search-results">
{% if search_results %}
<ul>
{% for href, caption, context in search_results %}
<li class="well"><a href="{{ pathto(item.href) }}">{{ caption }}</a></li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,224 @@
body {
font-family: "Raleway";
}
a {
color: #CE5C00;
}
input,
button,
select,
textarea {
font-family: "Raleway";
}
pre {
font-size: 11px;
}
h1, h2, h3, h4, h5, h6 {
clear: left;
}
h1 {
font-size: 30px;
line-height: 36px;
}
h2 {
font-size: 24px;
line-height: 30px;
}
h3 {
font-size: 19px;
line-height: 21px;
}
h4 {
font-size: 17px;
line-height: 19px;
}
h5 {
font-size: 15px;
line-height: 17px;
}
h6 {
font-size: 13px;
line-height: 15px;
}
.logo {
float: left;
margin: 20px 0 20px 22px;
}
.logo img {
height: 70px;
}
.hero {
padding: 10px 25px;
}
.gallery-random {
float: right;
line-height: 180px;
}
.gallery-random img {
max-height: 180px;
}
.coins-sample {
padding: 5px;
}
.sidebar-box {
padding: 0;
}
.sidebar-box-heading {
padding-left: 15px;
}
.headerlink {
margin-left: 10px;
color: #ddd;
display: none;
}
h1:hover .headerlink,
h2:hover .headerlink,
h3:hover .headerlink,
h4:hover .headerlink,
h5:hover .headerlink,
h6:hover .headerlink {
display: inline;
}
.headerlink:hover {
color: #CE5C00;
text-decoration: none;
}
.footer {
margin-top: 30px;
padding: 5px 10px;
color: #999;
}
.footer a {
color: #999;
text-decoration: underline;
}
.ohloh-use, .gplus-use {
float: left;
margin: 0 0 10px 15px;
}
/* Documentation */
/* general table settings */
table.docutils {
margin-bottom: 10px;
border-color: #ccc;
}
table.docutils td, table.docutils th {
padding: 5px;
border-color: #ccc;
text-align: left;
}
.toc ul ul {
font-size: 13px;
margin-right: -15px;
}
/* master content table */
.contentstable.docutils, .contentstable.docutils td {
border-color: transparent;
}
.contentstable.docutils .first {
font-weight: bold;
}
.contentstable.docutils .last {
padding-left: 10px;
}
.docutils .label, .docutils .badge {
background: transparent;
text-shadow: none;
font-size: 13px;
padding: 5px;
line-height: 20px;
color: #333;
}
/* module summary table */
.longtable.docutils {
font-size: 12px;
margin-bottom: 30px;
}
.longtable.docutils, .longtable.docutils td {
border-color: #ccc;
}
/* function and class description */
dl.class, dl.function, dl.method, dl.attribute {
border-top: 1px solid #ccc;
padding-top: 10px;
}
.descclassname {
color: #aaa;
font-weight: normal;
font-family: monospace;
}
.descname {
font-family: monospace;
}
dl.class em, dl.function em, dl.class big, dl.function big {
font-weight: normal;
font-family: monospace;
}
dl.class dd, dl.function dd {
padding: 10px;
}
.docutils.field-list th {
background-color: #eee;
padding: 10px;
text-align: left;
vertical-align: top;
width: 100px;
}
.docutils.field-list td {
padding: 10px 10px 10px 20px;
text-align: left;
vertical-align: top;
}
.docutils.field-list td blockquote p {
font-size: 13px;
line-height: 18px;
}
p.rubric {
font-weight: bold;
font-size: 19px;
margin: 15px 0 10px 0;
}
p.admonition-title {
font-weight: bold;
text-decoration: underline;
}
/* example gallery */
.gallery {
height: 200px;
}
.figure {
float: left;
margin: 1em;
}
.figure img {
display: block;
margin-left: auto;
margin-right: auto;
max-height: 150px;
max-width: 200px;
}
.figure .caption {
width: 200px;
text-align: center !important;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
[theme]
inherit = basic
stylesheet = none
pygments_style = default
+1
View File
@@ -8,3 +8,4 @@ User Guide
user_guide/plugins
user_guide/tutorials
user_guide/getting_help
user_guide/viewer
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

+20 -7
View File
@@ -14,13 +14,13 @@ Data type Range
uint8 0 to 255
uint16 0 to 65535
uint32 0 to 2\ :sup:`32`
float 0 to 1
float -1 to 1
int8 -128 to 127
int16 -32768 to 32767
int32 -2\ :sup:`31` to 2\ :sup:`31` - 1
========= =================================
Note that float images are restricted to the range 0 to 1 even though the data
Note that float images are restricted to the range -1 to 1 even though the data
type itself can exceed this range; all integer dtypes, on the other hand, have
pixel intensities that can span the entire data type range. Currently, *64-bit
(u)int images are not supported*.
@@ -71,11 +71,6 @@ issued::
float64 to uint8
array([ 0, 128, 255], dtype=uint8)
Wherever possible, functions should try to handle input without explicit
conversion. For example, there is no need to force values to a specific type
for doing a convolution; a plotting function, on the other hand, needs to know
the range of the input.
Output types
============
@@ -142,6 +137,24 @@ By default, ``rescale_intensity`` stretches the values of ``in_range`` to match
the range of the dtype.
Note about negative values
==========================
People very often represent images in signed dtypes, even though they only
manipulate the positive values of the image (e.g., using only 0-127 in an int8
image). For this reason, conversion functions *only spread the positive values*
of a signed dtype over the entire range of an unsigned dtype. In other words,
negative values are clipped to 0 when converting from signed to unsigned
dtypes. (Negative values are preserved when converting between signed dtypes.)
To prevent this clipping behavior, you should rescale your image beforehand::
>>> image = exposure.rescale_intensity(img_int32, out_range=(0, 2**31 - 1))
>>> img_uint8 = img_as_ubyte(image)
This behavior is symmetric: The values in an unsigned dtype are spread over
just the positive range of a signed dtype.
References
==========
+4 -4
View File
@@ -44,13 +44,13 @@ functions include one or more examples.
Mailing-list
------------
The scikits-image mailing-list is scikits-image@googlegroups.com (users
The scikit-image mailing-list is scikit-image@googlegroups.com (users
should join the `Google Group
<http://groups.google.com/group/scikits-image>`_ before posting). This
<http://groups.google.com/group/scikit-image>`_ before posting). This
mailing-list is shared by users and developers, and it is the right
place to ask any question about ``skimage``, or in general, image
processing using Python. Posting snippets of code with minimal examples
ensures to get more relevant and focused answers.
ensures to get more relevant and focused answers.
We would love to hear from how you use ``skimage`` for your work on the
mailing-list!
mailing-list!
@@ -47,10 +47,6 @@ detection, we use the `Canny detector
As the background is very smooth, almost all edges are found at the
boundary of the coins, or inside the coins.
Now that we have contours that delineate the outer boundary of the coins,
we fill the inner part of the coins using the
``ndimage.binary_fill_holes`` function, which uses mathematical morphology
to fill the holes.
::
@@ -61,6 +57,15 @@ to fill the holes.
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Now that we have contours that delineate the outer boundary of the coins,
we fill the inner part of the coins using the
``ndimage.binary_fill_holes`` function, which uses mathematical morphology
to fill the holes.
.. image:: ../../_images/plot_coins_segmentation_4.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Most coins are well segmented out of the background. Small objects from
the background can be easily removed using the ``ndimage.label``
function to remove objects smaller than a small threshold.
@@ -78,6 +83,10 @@ has not been segmented correctly at all. The reason is that the contour
that we got from the Canny detector was not completely closed, therefore
the filling function did not fill the inner part of the coin.
.. image:: ../../_images/plot_coins_segmentation_5.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Therefore, this segmentation method is not very robust: if we miss a
single pixel of the contour of the object, we will not be able to fill
it. Of course, we could try to dilate the contours in order to
@@ -117,12 +126,29 @@ separate the coins from the background.
.. image:: data/elevation_map.jpg
:align: center
and here is the corresponding 2-D plot:
.. image:: ../../_images/plot_coins_segmentation_6.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
The next step is to find markers of the background and the coins based on the
extreme parts of the histogram of grey values::
>>> markers = np.zeros_like(coins)
>>> markers[coins < 30] = 1
>>> markers[coins > 150] = 2
.. image:: ../../_images/plot_coins_segmentation_7.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Let us now compute the watershed transform::
>>> from skimage.morphology import watershed
>>> segmentation = watershed(elevation_map, markers)
.. image:: ../../_images/plot_coins_segmentation_4.png
.. image:: ../../_images/plot_coins_segmentation_8.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
@@ -139,7 +165,7 @@ We can now label all the coins one by one using ``ndimage.label``::
>>> labeled_coins, _ = ndimage.label(segmentation)
.. image:: ../../_images/plot_coins_segmentation_5.png
.. image:: ../../_images/plot_coins_segmentation_9.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
+85
View File
@@ -0,0 +1,85 @@
Image Viewer
============
Quick Start
-----------
``skimage.viewer`` provides a matplotlib_-based canvas for displaying images and
a Qt-based GUI-toolkit, with the goal of making it easy to create interactive
image editors. You can simply use it to display an image:
.. code-block:: python
from skimage import data
from skimage.viewer import ImageViewer
image = data.coins()
viewer = ImageViewer(image)
viewer.show()
Of course, you could just as easily use ``imshow`` from matplotlib_ (or
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:
.. code-block:: python
from skimage.viewer.plugins import Canny
viewer = ImageViewer(image)
viewer += Canny(view)
viewer.show()
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``:
.. code-block:: python
from skimage.filter import tv_denoise
from skimage.viewer.plugins.base import Plugin
denoise_plugin = Plugin(image_filter=tv_denoise)
.. note::
The ``Plugin`` assumes the first argument given to the image filter is the
image from the image viewer. In the future, this should be changed so you
can pass the image to a different argument of the filter function.
To actually interact with the filter, you have to add widgets that adjust the
parameters of the function. Typically, that means adding a slider widget and
connecting it to the filter parameter and the minimum and maximum values of the
slider:
.. code-block:: python
from skimage.viewer.widgets import Slider
from skimage.viewer.widgets.history import SaveButtons
denoise_plugin += Slider('weight', 0.01, 0.5, update_on='release')
denoise_plugin += SaveButtons()
Here, we connect a slider widget to the filter's 'weight' argument. We also
added some buttons for saving the image to file or to the ``scikit-image``
image stack (see ``skimage.io.push`` and ``skimage.io.pop``).
All that's left is to create an image viewer and add the plugin to that viewer.
.. code-block:: python
viewer = ImageViewer(image)
viewer += denoise_plugin
viewer.show()
.. image:: data/denoise_viewer_window.png
.. image:: data/denoise_plugin_window.png
.. _matplotlib: http://matplotlib.sourceforge.net/
+1 -40
View File
@@ -269,10 +269,6 @@ class ApiDocWriter(object):
ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n'
chap_title = uri_short
#ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title)
# + '\n\n')
# Set the chapter title to read 'module' for all modules except for the
# main packages
if '.' in uri:
@@ -281,21 +277,8 @@ class ApiDocWriter(object):
title = ':mod:`' + uri_short + '`'
ad += title + '\n' + self.rst_section_levels[1] * len(title)
if len(classes):
ad += '\nInheritance diagram for ``%s``:\n\n' % uri
ad += '.. inheritance-diagram:: %s \n' % uri
ad += ' :parts: 3\n'
ad += '\n.. automodule:: ' + uri + '\n'
ad += '\n.. currentmodule:: ' + uri + '\n'
# multi_class = len(classes) > 1
# multi_fx = len(functions) > 1
# if multi_class:
# ad += '\n' + 'Classes' + '\n' + \
# self.rst_section_levels[2] * 7 + '\n'
# elif len(classes) and multi_fx:
# ad += '\n' + 'Class' + '\n' + \
# self.rst_section_levels[2] * 5 + '\n'
for c in classes:
ad += '\n:class:`' + c + '`\n' \
+ self.rst_section_levels[2] * \
@@ -305,15 +288,8 @@ class ApiDocWriter(object):
ad += ' :members:\n' \
' :undoc-members:\n' \
' :show-inheritance:\n' \
' :inherited-members:\n' \
'\n' \
' .. automethod:: __init__\n'
# if multi_fx:
# ad += '\n' + 'Functions' + '\n' + \
# self.rst_section_levels[2] * 9 + '\n\n'
# elif len(functions) and multi_class:
# ad += '\n' + 'Function' + '\n' + \
# self.rst_section_levels[2] * 8 + '\n\n'
ad += '.. autosummary::\n\n'
for f in functions:
ad += ' ' + uri + '.' + f + '\n'
@@ -405,16 +381,9 @@ class ApiDocWriter(object):
modules.append(package_uri)
else:
dirnames.remove(dirname)
# Check filenames for modules
for filename in filenames:
module_name = filename[:-3]
module_uri = '.'.join((root_uri, module_name))
if (self._uri2path(module_uri) and
self._survives_exclude(module_uri, 'module')):
modules.append(module_uri)
return sorted(modules)
def write_modules_api(self, modules,outdir):
def write_modules_api(self, modules, outdir):
# write the list
written_modules = []
for m in modules:
@@ -451,14 +420,6 @@ class ApiDocWriter(object):
os.mkdir(outdir)
# compose list of modules
modules = self.discover_modules()
# group modules so we have one less level
module_depth = max([len(item.split('.')) for item in modules])
# modifying modules in-place, so make a copy
for item in modules[:]:
# Do not treat the .py files all as separate modules.
# Like this, only the objects exported in __all__ get picked up.
if not (len(item.split('.')) < module_depth):
modules.remove(item)
self.write_modules_api(modules,outdir)
def write_index(self, outdir, froot='gen', relative_to=None):
+6 -3
View File
@@ -23,14 +23,17 @@ releases = OrderedDict([
#('0.1', u'2009-10-07 13:52:19 +0200'),
#('0.2', u'2009-11-12 14:48:45 +0200'),
('0.3', u'2011-10-10 03:28:47 -0700'),
('0.4', u'2011-12-03 14:31:32 -0800')])
('0.4', u'2011-12-03 14:31:32 -0800'),
('0.5', u'2012-02-26 21:00:51 -0800'),
('0.6', u'2012-06-24 21:37:05 -0700')])
month_duration = 16
month_duration = 24
for r in releases:
releases[r] = dateutil.parser.parse(releases[r])
def fetch_PRs(user='scikits-image', repo='scikits-image', state='open'):
def fetch_PRs(user='scikit-image', repo='scikit-image', state='open'):
params = {'state': state,
'per_page': 100,
'page': 1}
+74 -27
View File
@@ -1,25 +1,32 @@
#! /usr/bin/env python
descr = """Image Processing SciKit
descr = """Image Processing SciKit
Image processing algorithms for SciPy, including IO, morphology, filtering,
warping, color manipulation, object detection, etc.
Please refer to the online documentation at
http://scikits-image.org/
http://scikit-image.org/
"""
DISTNAME = 'scikits-image'
DISTNAME = 'scikit-image'
DESCRIPTION = 'Image processing routines for SciPy'
LONG_DESCRIPTION = descr
MAINTAINER = 'Stefan van der Walt'
MAINTAINER_EMAIL = 'stefan@sun.ac.za'
URL = 'http://scikits-image.org'
URL = 'http://scikit-image.org'
LICENSE = 'Modified BSD'
DOWNLOAD_URL = 'http://github.com/scikits-image/scikits-image'
VERSION = '0.6.1'
DOWNLOAD_URL = 'http://github.com/scikit-image/scikit-image'
VERSION = '0.8.0'
PYTHON_VERSION = (2, 5)
DEPENDENCIES = {
'numpy': (1, 6),
'Cython': (0, 15),
}
import os
import sys
import re
import setuptools
from numpy.distutils.core import setup
try:
@@ -27,6 +34,7 @@ try:
except ImportError:
from distutils.command.build_py import build_py
def configuration(parent_package='', top_path=None):
if os.path.exists('MANIFEST'): os.remove('MANIFEST')
@@ -44,6 +52,7 @@ def configuration(parent_package='', top_path=None):
return config
def write_version_py(filename='skimage/version.py'):
template = """# THIS FILE IS GENERATED FROM THE SKIMAGE SETUP.PY
version='%s'
@@ -57,7 +66,46 @@ version='%s'
finally:
vfile.close()
def get_package_version(package):
version = []
for version_attr in ('version', 'VERSION', '__version__'):
if hasattr(package, version_attr) \
and isinstance(getattr(package, version_attr), str):
version_info = getattr(package, version_attr, '')
for part in re.split('\D+', version_info):
try:
version.append(int(part))
except ValueError:
pass
return tuple(version)
def check_requirements():
if sys.version_info < PYTHON_VERSION:
raise SystemExit('You need Python version %d.%d or later.' \
% PYTHON_VERSION)
for package_name, min_version in DEPENDENCIES.items():
dep_error = False
try:
package = __import__(package_name)
except ImportError:
dep_error = True
else:
package_version = get_package_version(package)
if min_version > package_version:
dep_error = True
if dep_error:
raise ImportError('You need `%s` version %d.%d or later.' \
% ((package_name, ) + min_version))
if __name__ == "__main__":
check_requirements()
write_version_py()
setup(
@@ -71,32 +119,31 @@ if __name__ == "__main__":
download_url=DOWNLOAD_URL,
version=VERSION,
classifiers =
[ 'Development Status :: 4 - Beta',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: BSD License',
'Programming Language :: C',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Scientific/Engineering',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: MacOS',
],
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'License :: OSI Approved :: BSD License',
'Programming Language :: C',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Scientific/Engineering',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: MacOS',
],
configuration=configuration,
install_requires=[],
packages=setuptools.find_packages(),
packages=setuptools.find_packages(exclude=['doc']),
include_package_data=True,
zip_safe=False, # the package can run out of an .egg file
entry_points={
'console_scripts': [
'skivi = skimage.scripts.skivi:main']
},
'console_scripts': ['skivi = skimage.scripts.skivi:main'],
},
cmdclass={'build_py': build_py},
)
)
+32 -35
View File
@@ -1,6 +1,6 @@
"""Image Processing SciKit (Toolbox for SciPy)
``scikits-image`` (a.k.a. ``skimage``) is a collection of algorithms for image
``scikit-image`` (a.k.a. ``skimage``) is a collection of algorithms for image
processing and computer vision.
The main package of ``skimage`` only provides a few utilities for converting
@@ -52,6 +52,8 @@ img_as_ubyte
"""
import os.path as _osp
import imp as _imp
import functools as _functools
pkg_dir = _osp.abspath(_osp.dirname(__file__))
data_dir = _osp.join(pkg_dir, 'data')
@@ -61,37 +63,30 @@ try:
except ImportError:
__version__ = "unbuilt-dev"
def _setup_test(verbose=False):
import gzip
import functools
args = ['', '--exe', '-w', pkg_dir]
if verbose:
args.extend(['-v', '-s'])
try:
_imp.find_module('nose')
except ImportError:
def _test(verbose=False):
"""This would invoke the skimage test suite, but nose couldn't be
imported so the test suite can not run.
"""
raise ImportError("Could not load nose. Unit tests not available.")
else:
def _test(verbose=False):
"""Invoke the skimage test suite."""
import nose
args = ['', pkg_dir, '--exe']
if verbose:
args.extend(['-v', '-s'])
nose.run('skimage', argv=args)
try:
import nose as _nose
except ImportError:
print("Could not load nose. Unit tests not available.")
return None
else:
f = functools.partial(_nose.run, 'skimage', argv=args)
f.__doc__ = 'Invoke the skimage test suite.'
return f
# 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__
test = _setup_test()
if test is None:
try:
del test
except NameError:
pass
test_verbose = _setup_test(verbose=True)
if test_verbose is None:
try:
del test
except NameError:
pass
def get_log(name=None):
"""Return a console logger.
@@ -120,26 +115,28 @@ def get_log(name=None):
log = logging.getLogger(name)
return log
def _setup_log():
"""Configure root logger.
"""
import logging, sys
import logging
import sys
log = logging.getLogger()
formatter = logging.Formatter(
'%(name)s: %(levelname)s: %(message)s'
)
try:
handler = logging.StreamHandler(stream=sys.stdout)
except TypeError:
handler = logging.StreamHandler(strm=sys.stdout)
formatter = logging.Formatter(
'%(name)s: %(levelname)s: %(message)s'
)
handler.setFormatter(formatter)
log = get_log()
log.addHandler(handler)
log.setLevel(logging.WARNING)
log.propagate = False
_setup_log()
+12 -4
View File
@@ -1,9 +1,15 @@
import sys
import os
import shutil
import hashlib
import subprocess
import platform
# WindowsError is not defined on unix systems
try:
WindowsError
except NameError:
WindowsError = None
def cython(pyx_files, working_path=''):
"""Use Cython to convert the given files to C.
@@ -39,17 +45,18 @@ def cython(pyx_files, working_path=''):
print(cmd)
try:
status = subprocess.call(['cython', '-o', c_file, pyxfile])
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.
status = subprocess.call(
subprocess.call(
[sys.executable,
os.path.join(os.path.dirname(sys.executable),
'Scripts', 'cython.py'),
'-o', c_file, pyxfile],
shell=True)
def _md5sum(f):
m = hashlib.new('md5')
while True:
@@ -60,6 +67,7 @@ def _md5sum(f):
m.update(d)
return m.hexdigest()
def _changed(filename):
"""Compare the hash of a Cython file to the cached hash value on disk.

Some files were not shown because too many files have changed in this diff Show More