Merge tag 'v0.7.2' into debian
* tag 'v0.7.2': (648 commits) PKG: Temporarily disable failing gradient check. PKG: Set version to 0.7.2. Fix reference links in doc strings Fix failing perimeter test caused by bug in scipy Add missing empty lines between test functions Split tests for different channel numbers into separate functions Add note about random test failure for some systems Change Exception type for wrong input dims Remove redundant dtype conversion Remove obsolete license note as code has been refactored Improve test coverage of find_contours Full test coverage for structural similarity Full test coverage for regionprops Full test coverage for polygon approximation and subdivision Fix polygon approximation for 0 or less tolerance Improve test coverage of LPI filter Fix callable test in LPI filter Improve test coverage for ctmf Full test coverage for canny filter Full test coveragem for data package ...
@@ -0,0 +1,28 @@
|
||||
# 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=''
|
||||
# - PYTHON=python3 PYSUF=3 : python3-numpy not currently available
|
||||
install:
|
||||
# - sudo apt-get build-dep $PYTHON-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 apt-get 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 --exe -v --cover-package=skimage skimage
|
||||
|
||||
@@ -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,17 @@
|
||||
|
||||
- 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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -4,44 +4,79 @@ Development process
|
||||
:doc:`Read this overview <gitwash/index>` of how to use Git with
|
||||
``skimage``. 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.
|
||||
|
||||
.. 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 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))
|
||||
|
||||
Test coverage
|
||||
`````````````
|
||||
Tests for a module should ideally cover all code in that module,
|
||||
@@ -64,4 +99,4 @@ 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,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
|
||||
|
||||
@@ -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
|
||||
------------------------
|
||||
|
||||
@@ -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
|
||||
- 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"
|
||||
- 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 = .*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.. role:: strike
|
||||
|
||||
|
||||
.. _howto_contribute:
|
||||
|
||||
How to contribute to ``skimage``
|
||||
@@ -15,111 +16,14 @@ How to contribute to ``skimage``
|
||||
|
||||
|
||||
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
|
||||
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 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>`__.
|
||||
|
||||
.. 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
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
Name: scikits-image
|
||||
Version: 0.6
|
||||
Name: scikit-image
|
||||
Version: 0.7.2
|
||||
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
|
||||
@@ -76,15 +73,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 +85,36 @@ Library:
|
||||
Extension: skimage.graph.heap
|
||||
Sources:
|
||||
skimage/graph/heap.pyx
|
||||
Extension: skimage.morphology._greyreconstruct
|
||||
Sources:
|
||||
skimage/morphology/_greyreconstruct.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
|
||||
|
||||
Executable: skivi
|
||||
Module: skimage.scripts.skivi
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
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]+)['\"]")
|
||||
|
||||
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 and name 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, cy_file
|
||||
|
||||
|
||||
def each_cy_in_bento(bento_file='bento.info'):
|
||||
"""Yield path and name 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:'):
|
||||
parts = line.split('.')
|
||||
ext_name = parts[-1]
|
||||
path = line.lstrip('Extension:').strip()
|
||||
yield path, ext_name
|
||||
|
||||
|
||||
def remove_common_extensions(cy_bento, cy_setup):
|
||||
for ext_name in cy_bento.keys():
|
||||
if ext_name in cy_setup:
|
||||
spath = cy_setup.pop(ext_name)
|
||||
bpath = cy_bento.pop(ext_name)
|
||||
if not spath.replace(os.path.sep, '.') == bpath:
|
||||
print "Mismatched paths:"
|
||||
print " setup.py: ", spath
|
||||
print " bento.info:", bpath
|
||||
|
||||
def print_results(cy_bento, cy_setup):
|
||||
def info(text):
|
||||
print
|
||||
print(text)
|
||||
print('-' * len(text))
|
||||
|
||||
print "Bento errors:"
|
||||
print "-------------"
|
||||
|
||||
if cy_bento:
|
||||
info("The following extensions in 'bento.info' were not found:")
|
||||
print('\n'.join(cy_bento.keys()))
|
||||
|
||||
|
||||
if cy_setup:
|
||||
info("The following cython files exist but were not in 'bento.info':")
|
||||
print('\n'.join(cy_setup))
|
||||
info("Consider adding the following to the 'bento.info' Library:")
|
||||
for ext_name, dir_path in cy_setup.iteritems():
|
||||
print BENTO_TEMPLATE.format(module_path=dir_path.replace('/', '.'),
|
||||
dir_path=dir_path)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# All cython extensions defined in 'setup.py' files.
|
||||
cy_setup = dict((ext, path) for path, ext in each_cy_in_setup('skimage'))
|
||||
|
||||
# All cython extensions defined 'bento.info' file.
|
||||
cy_bento = dict((ext, path) for path, ext in each_cy_in_bento())
|
||||
|
||||
remove_common_extensions(cy_bento, cy_setup)
|
||||
print_results(cy_bento, cy_setup)
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
"""
|
||||
@@ -109,7 +109,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)
|
||||
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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.
|
||||
"""
|
||||
@@ -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, \
|
||||
visualize_boundaries, slic, quickshift
|
||||
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(visualize_boundaries(img, segments_fz))
|
||||
ax[0].set_title("Felzenszwalbs's method")
|
||||
ax[1].imshow(visualize_boundaries(img, segments_slic))
|
||||
ax[1].set_title("SLIC")
|
||||
ax[2].imshow(visualize_boundaries(img, segments_quick))
|
||||
ax[2].set_title("Quickshift")
|
||||
for a in ax:
|
||||
a.set_xticks(())
|
||||
a.set_yticks(())
|
||||
plt.show()
|
||||
@@ -19,11 +19,11 @@ 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,11 +34,11 @@ 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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -73,7 +74,10 @@ 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 +164,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)
|
||||
|
||||
@@ -335,7 +339,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 +350,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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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 |
@@ -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,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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.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');
|
||||
}
|
||||
|
Before Width: | Height: | Size: 32 KiB |
@@ -1,6 +0,0 @@
|
||||
{% extends "!layout.html" %}
|
||||
{% block rootrellink %}
|
||||
<li><a href={{ pathto('index') }}>scikits-image home</a> »</li>
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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>
|
||||
@@ -1,12 +1,22 @@
|
||||
{%- block navigation %}
|
||||
|
||||
{% if pagename != 'index' %}
|
||||
<h3>Navigation</h3>
|
||||
<p>
|
||||
<a href="{{ pathto(master_doc) }}">Documentation Home</a>
|
||||
</p>
|
||||
<p> </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 %}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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,6 +1,6 @@
|
||||
.. _using-git:
|
||||
|
||||
Working with *scikits-image* source code
|
||||
Working with *scikit-image* source code
|
||||
========================================
|
||||
|
||||
Contents:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
-------
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 = " — "|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>
|
||||
© 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 %}
|
||||
@@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 44 KiB |
@@ -0,0 +1,4 @@
|
||||
[theme]
|
||||
inherit = basic
|
||||
stylesheet = none
|
||||
pygments_style = default
|
||||
@@ -8,3 +8,4 @@ User Guide
|
||||
user_guide/plugins
|
||||
user_guide/tutorials
|
||||
user_guide/getting_help
|
||||
user_guide/viewer
|
||||
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 90 KiB |
@@ -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*.
|
||||
@@ -142,6 +142,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
|
||||
==========
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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'
|
||||
DOWNLOAD_URL = 'http://github.com/scikit-image/scikit-image'
|
||||
VERSION = '0.7.2'
|
||||
PYTHON_VERSION = (2, 5)
|
||||
DEPENDENCIES = {
|
||||
'numpy': (1, 6),
|
||||
'Cython': (0, 15),
|
||||
}
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
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 version_info.split('.'):
|
||||
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(),
|
||||
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},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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
|
||||
@@ -61,37 +61,32 @@ try:
|
||||
except ImportError:
|
||||
__version__ = "unbuilt-dev"
|
||||
|
||||
|
||||
def _setup_test(verbose=False):
|
||||
import gzip
|
||||
import functools
|
||||
|
||||
args = ['', '--exe', '-w', pkg_dir]
|
||||
args = ['', pkg_dir, '--exe']
|
||||
if verbose:
|
||||
args.extend(['-v', '-s'])
|
||||
|
||||
try:
|
||||
import nose as _nose
|
||||
except ImportError:
|
||||
print("Could not load nose. Unit tests not available.")
|
||||
return None
|
||||
def broken_test_func():
|
||||
"""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.")
|
||||
return broken_test_func
|
||||
else:
|
||||
f = functools.partial(_nose.run, 'skimage', argv=args)
|
||||
f.__doc__ = 'Invoke the skimage test suite.'
|
||||
return f
|
||||
|
||||
test = _setup_test()
|
||||
if test is None:
|
||||
try:
|
||||
del test
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
test = _setup_test()
|
||||
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()
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import hashlib
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
|
||||
def cython(pyx_files, working_path=''):
|
||||
"""Use Cython to convert the given files to C.
|
||||
@@ -39,17 +38,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 +60,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.
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
cdef unsigned char point_in_polygon(int nr_verts, double *xp, double *yp,
|
||||
double x, double y)
|
||||
|
||||
cdef void points_in_polygon(int nr_verts, double *xp, double *yp,
|
||||
int nr_points, double *x, double *y,
|
||||
unsigned char *result)
|
||||
@@ -0,0 +1,54 @@
|
||||
#cython: cdivision=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
|
||||
|
||||
cdef inline unsigned char point_in_polygon(int nr_verts, double *xp, double *yp,
|
||||
double x, double y):
|
||||
"""Test whether point lies inside a polygon.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nr_verts : int
|
||||
Number of vertices of polygon.
|
||||
xp, yp : double array
|
||||
Coordinates of polygon with length nr_verts.
|
||||
x, y : double
|
||||
Coordinates of point.
|
||||
"""
|
||||
cdef int i
|
||||
cdef unsigned char c = 0
|
||||
cdef int j = nr_verts - 1
|
||||
for i in range(nr_verts):
|
||||
if (
|
||||
(((yp[i] <= y) and (y < yp[j])) or
|
||||
((yp[j] <= y) and (y < yp[i])))
|
||||
and (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])
|
||||
):
|
||||
c = not c
|
||||
j = i
|
||||
return c
|
||||
|
||||
|
||||
cdef void points_in_polygon(int nr_verts, double *xp, double *yp,
|
||||
int nr_points, double *x, double *y,
|
||||
unsigned char *result):
|
||||
"""Test whether points lie inside a polygon.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
nr_verts : int
|
||||
Number of vertices of polygon.
|
||||
xp, yp : double array
|
||||
Coordinates of polygon with length nr_verts.
|
||||
nr_points : int
|
||||
Number of points to test.
|
||||
x, y : double array
|
||||
Coordinates of points.
|
||||
result : unsigned char array
|
||||
Test results for each point.
|
||||
"""
|
||||
cdef int n
|
||||
for n in range(nr_points):
|
||||
result[n] = point_in_polygon(nr_verts, xp, yp, x[n], y[n])
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
cdef double nearest_neighbour_interpolation(double* image, int rows,
|
||||
int cols, double r,
|
||||
double c, char mode,
|
||||
double cval)
|
||||
|
||||
cdef double bilinear_interpolation(double* image, int rows, int cols,
|
||||
double r, double c, char mode,
|
||||
double cval)
|
||||
|
||||
cdef double quadratic_interpolation(double x, double[3] f)
|
||||
cdef double biquadratic_interpolation(double* image, int rows, int cols,
|
||||
double r, double c, char mode,
|
||||
double cval)
|
||||
|
||||
cdef double cubic_interpolation(double x, double[4] f)
|
||||
cdef double bicubic_interpolation(double* image, int rows, int cols,
|
||||
double r, double c, char mode,
|
||||
double cval)
|
||||
|
||||
cdef double get_pixel(double* image, int rows, int cols, int r, int c,
|
||||
char mode, double cval)
|
||||
|
||||
cdef int coord_map(int dim, int coord, char mode)
|
||||
@@ -0,0 +1,297 @@
|
||||
#cython: cdivision=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
from libc.math cimport ceil, floor
|
||||
|
||||
|
||||
cdef inline int round(double r):
|
||||
return <int>((r + 0.5) if (r > 0.0) else (r - 0.5))
|
||||
|
||||
|
||||
cdef inline double nearest_neighbour_interpolation(double* image, int rows,
|
||||
int cols, double r,
|
||||
double c, char mode,
|
||||
double cval):
|
||||
"""Nearest neighbour interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
return get_pixel(image, rows, cols, <int>round(r), <int>round(c),
|
||||
mode, cval)
|
||||
|
||||
|
||||
cdef inline double bilinear_interpolation(double* image, int rows, int cols,
|
||||
double r, double c, char mode,
|
||||
double cval):
|
||||
"""Bilinear interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
cdef double dr, dc
|
||||
cdef int minr, minc, maxr, maxc
|
||||
|
||||
minr = <int>floor(r)
|
||||
minc = <int>floor(c)
|
||||
maxr = <int>ceil(r)
|
||||
maxc = <int>ceil(c)
|
||||
dr = r - minr
|
||||
dc = c - minc
|
||||
top = (1 - dc) * get_pixel(image, rows, cols, minr, minc, mode, cval) \
|
||||
+ dc * get_pixel(image, rows, cols, minr, maxc, mode, cval)
|
||||
bottom = (1 - dc) * get_pixel(image, rows, cols, maxr, minc, mode, cval) \
|
||||
+ dc * get_pixel(image, rows, cols, maxr, maxc, mode, cval)
|
||||
return (1 - dr) * top + dr * bottom
|
||||
|
||||
|
||||
cdef inline double quadratic_interpolation(double x, double[3] f):
|
||||
"""Quadratic interpolation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : double
|
||||
Position in the interval [-1, 1].
|
||||
f : double[4]
|
||||
Function values at positions [-1, 0, 1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
return f[1] - 0.25 * (f[0] - f[2]) * x
|
||||
|
||||
|
||||
cdef inline double biquadratic_interpolation(double* image, int rows, int cols,
|
||||
double r, double c, char mode,
|
||||
double cval):
|
||||
"""Biquadratic interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
cdef int r0 = <int>round(r)
|
||||
cdef int c0 = <int>round(c)
|
||||
if r < 0:
|
||||
r0 -= 1
|
||||
if c < 0:
|
||||
c0 -= 1
|
||||
# scale position to range [-1, 1]
|
||||
cdef double xr = (r - r0) - 1
|
||||
cdef double xc = (c - c0) - 1
|
||||
if r == r0:
|
||||
xr += 1
|
||||
if c == c0:
|
||||
xc += 1
|
||||
|
||||
cdef double fc[3], fr[3]
|
||||
|
||||
cdef int pr, pc
|
||||
|
||||
# row-wise cubic interpolation
|
||||
for pr in range(r0, r0 + 3):
|
||||
for pc in range(c0, c0 + 3):
|
||||
fc[pc - c0] = get_pixel(image, rows, cols, pr, pc, mode, cval)
|
||||
fr[pr - r0] = quadratic_interpolation(xc, fc)
|
||||
|
||||
# cubic interpolation for interpolated values of each row
|
||||
return quadratic_interpolation(xr, fr)
|
||||
|
||||
|
||||
cdef inline double cubic_interpolation(double x, double[4] f):
|
||||
"""Cubic interpolation.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : double
|
||||
Position in the interval [0, 1].
|
||||
f : double[4]
|
||||
Function values at positions [0, 1/3, 2/3, 1].
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
return \
|
||||
f[1] + 0.5 * x * \
|
||||
(f[2] - f[0] + x * \
|
||||
(2.0 * f[0] - 5.0 * f[1] + 4.0 * f[2] - f[3] + x * \
|
||||
(3.0 * (f[1] - f[2]) + f[3] - f[0])))
|
||||
|
||||
|
||||
cdef inline double bicubic_interpolation(double* image, int rows, int cols,
|
||||
double r, double c, char mode,
|
||||
double cval):
|
||||
"""Bicubic interpolation at a given position in the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : double
|
||||
Position at which to interpolate.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Interpolated value.
|
||||
|
||||
"""
|
||||
|
||||
cdef int r0 = <int>r - 1
|
||||
cdef int c0 = <int>c - 1
|
||||
if r < 0:
|
||||
r0 -= 1
|
||||
if c < 0:
|
||||
c0 -= 1
|
||||
# scale position to range [0, 1]
|
||||
cdef double xr = (r - r0) / 3
|
||||
cdef double xc = (c - c0) / 3
|
||||
|
||||
cdef double fc[4], fr[4]
|
||||
|
||||
cdef int pr, pc
|
||||
|
||||
# row-wise cubic interpolation
|
||||
for pr in range(r0, r0 + 4):
|
||||
for pc in range(c0, c0 + 4):
|
||||
fc[pc - c0] = get_pixel(image, rows, cols, pr, pc, mode, cval)
|
||||
fr[pr - r0] = cubic_interpolation(xc, fc)
|
||||
|
||||
# cubic interpolation for interpolated values of each row
|
||||
return cubic_interpolation(xr, fr)
|
||||
|
||||
|
||||
cdef inline double get_pixel(double* image, int rows, int cols, int r, int c,
|
||||
char mode, double cval):
|
||||
"""Get a pixel from the image, taking wrapping mode into consideration.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
image : double array
|
||||
Input image.
|
||||
rows, cols : int
|
||||
Shape of image.
|
||||
r, c : int
|
||||
Position at which to get the pixel.
|
||||
mode : {'C', 'W', 'R', 'N'}
|
||||
Wrapping mode. Constant, Wrap, Reflect or Nearest.
|
||||
cval : double
|
||||
Constant value to use for constant mode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
value : double
|
||||
Pixel value at given position.
|
||||
|
||||
"""
|
||||
if mode == 'C':
|
||||
if (r < 0) or (r > rows - 1) or (c < 0) or (c > cols - 1):
|
||||
return cval
|
||||
else:
|
||||
return image[r * cols + c]
|
||||
else:
|
||||
return image[coord_map(rows, r, mode) * cols + coord_map(cols, c, mode)]
|
||||
|
||||
|
||||
cdef inline int coord_map(int dim, int coord, char mode):
|
||||
"""
|
||||
Wrap a coordinate, according to a given mode.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dim : int
|
||||
Maximum coordinate.
|
||||
coord : int
|
||||
Coord provided by user. May be < 0 or > dim.
|
||||
mode : {'W', 'R', 'N'}
|
||||
Whether to wrap or reflect the coordinate if it
|
||||
falls outside [0, dim).
|
||||
|
||||
"""
|
||||
dim = dim - 1
|
||||
if mode == 'R': # reflect
|
||||
if coord < 0:
|
||||
# How many times times does the coordinate wrap?
|
||||
if <int>(-coord / dim) % 2 != 0:
|
||||
return dim - <int>(-coord % dim)
|
||||
else:
|
||||
return <int>(-coord % dim)
|
||||
elif coord > dim:
|
||||
if <int>(coord / dim) % 2 != 0:
|
||||
return <int>(dim - (coord % dim))
|
||||
else:
|
||||
return <int>(coord % dim)
|
||||
elif mode == 'W': # wrap
|
||||
if coord < 0:
|
||||
return <int>(dim - (-coord % dim))
|
||||
elif coord > dim:
|
||||
return <int>(coord % dim)
|
||||
elif mode == 'N': # nearest
|
||||
if coord < 0:
|
||||
return 0
|
||||
elif coord > dim:
|
||||
return dim
|
||||
|
||||
return coord
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
|
||||
from skimage._build import cython
|
||||
|
||||
base_path = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def configuration(parent_package='', top_path=None):
|
||||
from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs
|
||||
|
||||
config = Configuration('_shared', parent_package, top_path)
|
||||
config.add_data_dir('tests')
|
||||
|
||||
cython(['geometry.pyx'], working_path=base_path)
|
||||
cython(['interpolation.pyx'], working_path=base_path)
|
||||
cython(['transform.pyx'], working_path=base_path)
|
||||
|
||||
config.add_extension('geometry', sources=['geometry.c'])
|
||||
config.add_extension('interpolation', sources=['interpolation.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
config.add_extension('transform', sources=['transform.c'],
|
||||
include_dirs=[get_numpy_include_dirs()])
|
||||
|
||||
return config
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from numpy.distutils.core import setup
|
||||
setup(maintainer='scikit-image Developers',
|
||||
author='scikit-image Developers',
|
||||
maintainer_email='scikit-image@googlegroups.com',
|
||||
description='Transforms',
|
||||
url='https://github.com/scikit-image/scikit-image',
|
||||
license='SciPy License (BSD Style)',
|
||||
**(configuration(top_path='').todict())
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
"""Testing utilities."""
|
||||
|
||||
|
||||
def _assert_less(a, b, msg=None):
|
||||
message = "%r is not lower than %r" % (a, b)
|
||||
if msg is not None:
|
||||
message += ": " + msg
|
||||
assert a < b, message
|
||||
|
||||
|
||||
def _assert_greater(a, b, msg=None):
|
||||
message = "%r is not greater than %r" % (a, b)
|
||||
if msg is not None:
|
||||
message += ": " + msg
|
||||
assert a > b, message
|
||||
|
||||
|
||||
try:
|
||||
from nose.tools import assert_less
|
||||
except ImportError:
|
||||
assert_less = _assert_less
|
||||
|
||||
try:
|
||||
from nose.tools import assert_greater
|
||||
except ImportError:
|
||||
assert_greater = _assert_greater
|
||||
@@ -0,0 +1,5 @@
|
||||
cimport numpy as cnp
|
||||
|
||||
|
||||
cdef float integrate(cnp.ndarray[float, ndim=2, mode="c"] sat,
|
||||
int r0, int c0, int r1, int c1)
|
||||
@@ -0,0 +1,44 @@
|
||||
#cython: cdivision=True
|
||||
#cython: boundscheck=False
|
||||
#cython: nonecheck=False
|
||||
#cython: wraparound=False
|
||||
cimport numpy as cnp
|
||||
|
||||
|
||||
cdef float integrate(cnp.ndarray[float, ndim=2, mode="c"] sat,
|
||||
int r0, int c0, int r1, int c1):
|
||||
"""
|
||||
Using a summed area table / integral image, calculate the sum
|
||||
over a given window.
|
||||
|
||||
This function is the same as the `integrate` function in
|
||||
`skimage.transform.integrate`, but this Cython version significantly
|
||||
speeds up the code.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
sat : ndarray of float
|
||||
Summed area table / integral image.
|
||||
r0, c0 : int
|
||||
Top-left corner of block to be summed.
|
||||
r1, c1 : int
|
||||
Bottom-right corner of block to be summed.
|
||||
|
||||
Returns
|
||||
-------
|
||||
S : int
|
||||
Sum over the given window.
|
||||
"""
|
||||
cdef float S = 0
|
||||
|
||||
S += sat[r1, c1]
|
||||
|
||||
if (r0 - 1 >= 0) and (c0 - 1 >= 0):
|
||||
S += sat[r0 - 1, c0 - 1]
|
||||
|
||||
if (r0 - 1 >= 0):
|
||||
S -= sat[r0 - 1, c1]
|
||||
|
||||
if (c0 - 1 >= 0):
|
||||
S -= sat[r1, c0 - 1]
|
||||
return S
|
||||
@@ -44,7 +44,9 @@ References
|
||||
from __future__ import division
|
||||
|
||||
__all__ = ['convert_colorspace', 'rgb2hsv', 'hsv2rgb', 'rgb2xyz', 'xyz2rgb',
|
||||
'rgb2rgbcie', 'rgbcie2rgb', 'rgb2grey', 'rgb2gray', 'gray2rgb']
|
||||
'rgb2rgbcie', 'rgbcie2rgb', 'rgb2grey', 'rgb2gray', 'gray2rgb',
|
||||
'xyz2lab', 'lab2xyz', 'lab2rgb', 'rgb2lab'
|
||||
]
|
||||
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
@@ -81,11 +83,8 @@ def convert_colorspace(arr, fromspace, tospace):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> from skimage import data
|
||||
>>> lena = data.lena()
|
||||
>>> lena_hsv = convert_colorspace(lena, 'RGB', 'HSV')
|
||||
"""
|
||||
fromdict = {'RGB': lambda im: im, 'HSV': hsv2rgb, 'RGB CIE': rgbcie2rgb,
|
||||
@@ -149,11 +148,9 @@ def rgb2hsv(rgb):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> from skimage import color
|
||||
>>> from skimage import data
|
||||
>>> lena = data.lena()
|
||||
>>> lena_hsv = color.rgb2hsv(lena)
|
||||
"""
|
||||
arr = _prepare_colorarray(rgb)
|
||||
@@ -164,8 +161,10 @@ def rgb2hsv(rgb):
|
||||
|
||||
# -- S channel
|
||||
delta = arr.ptp(-1)
|
||||
# Ignore warning for zero divided by zero
|
||||
old_settings = np.seterr(invalid='ignore')
|
||||
out_s = delta / out_v
|
||||
out_s[delta == 0] = 0
|
||||
out_s[delta == 0.] = 0.
|
||||
|
||||
# -- H channel
|
||||
# red is max
|
||||
@@ -180,6 +179,9 @@ def rgb2hsv(rgb):
|
||||
idx = (arr[:, :, 2] == out_v)
|
||||
out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx]
|
||||
out_h = (out[:, :, 0] / 6.) % 1.
|
||||
out_h[delta == 0.] = 0.
|
||||
|
||||
np.seterr(**old_settings)
|
||||
|
||||
# -- output
|
||||
out[:, :, 0] = out_h
|
||||
@@ -224,11 +226,8 @@ def hsv2rgb(hsv):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> from skimage import data
|
||||
>>> lena = data.lena()
|
||||
>>> lena_hsv = rgb2hsv(lena)
|
||||
>>> lena_rgb = hsv2rgb(lena_hsv)
|
||||
"""
|
||||
@@ -286,6 +285,9 @@ grey_from_rgb = np.array([[0.2125, 0.7154, 0.0721],
|
||||
[0, 0, 0],
|
||||
[0, 0, 0]])
|
||||
|
||||
# CIE LAB constants for Observer= 2A, Illuminant= D65
|
||||
lab_ref_white = np.array([0.95047, 1., 1.08883])
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# The conversion functions that make use of the matrices above
|
||||
#-------------------------------------------------------------
|
||||
@@ -346,14 +348,11 @@ def xyz2rgb(xyz):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
>>> from skimage import data
|
||||
>>> from skimage.color import rgb2xyz, xyz2rgb
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> lena = data.lena()
|
||||
>>> lena_xyz = rgb2xyz(lena)
|
||||
>>> lena_rgb = xyz2rgb(lena_hsv)
|
||||
>>> lena_rgb = xyz2rgb(lena_xyz)
|
||||
"""
|
||||
return _convert(rgb_from_xyz, xyz)
|
||||
|
||||
@@ -387,11 +386,8 @@ def rgb2xyz(rgb):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> from skimage import data
|
||||
>>> lena = data.lena()
|
||||
>>> lena_xyz = rgb2xyz(lena)
|
||||
"""
|
||||
return _convert(xyz_from_rgb, rgb)
|
||||
@@ -421,12 +417,9 @@ def rgb2rgbcie(rgb):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
>>> from skimage import data
|
||||
>>> from skimage.color import rgb2rgbcie
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> lena = data.lena()
|
||||
>>> lena_rgbcie = rgb2rgbcie(lena)
|
||||
"""
|
||||
return _convert(rgbcie_from_rgb, rgb)
|
||||
@@ -456,14 +449,11 @@ def rgbcie2rgb(rgbcie):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
>>> from skimage import data
|
||||
>>> from skimage.color import rgb2rgbcie, rgbcie2rgb
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> lena = data.lena()
|
||||
>>> lena_rgbcie = rgb2rgbcie(lena)
|
||||
>>> lena_rgb = rgbcie2rgb(lena_hsv)
|
||||
>>> lena_rgb = rgbcie2rgb(lena_rgbcie)
|
||||
"""
|
||||
return _convert(rgb_from_rgbcie, rgbcie)
|
||||
|
||||
@@ -485,7 +475,7 @@ def rgb2grey(rgb):
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb2grey` is not a 3-D array of shape (.., .., 3) or
|
||||
If `rgb2grey` is not a 3-D array of shape (.., .., 3) or
|
||||
(.., .., 4).
|
||||
|
||||
References
|
||||
@@ -503,14 +493,14 @@ def rgb2grey(rgb):
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import os
|
||||
>>> from skimage import data_dir
|
||||
>>> from skimage.io import imread
|
||||
>>> from skimage.color import rgb2grey
|
||||
|
||||
>>> lena = imread(os.path.join(data_dir, 'lena.png'))
|
||||
>>> from skimage import data
|
||||
>>> lena = data.lena()
|
||||
>>> lena_grey = rgb2grey(lena)
|
||||
"""
|
||||
if rgb.ndim == 2:
|
||||
return rgb
|
||||
|
||||
return _convert(grey_from_rgb, rgb[:, :, :3])[..., 0]
|
||||
|
||||
rgb2gray = rgb2grey
|
||||
@@ -540,3 +530,157 @@ def gray2rgb(image):
|
||||
|
||||
M, N = image.shape
|
||||
return np.dstack((image, image, image))
|
||||
|
||||
|
||||
def xyz2lab(xyz):
|
||||
"""XYZ to CIE-LAB color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
xyz : array_like
|
||||
The image in XYZ format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in CIE-LAB format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `xyz` is not a 3-D array of shape (.., .., 3).
|
||||
|
||||
Notes
|
||||
-----
|
||||
Observer= 2A, Illuminant= D65
|
||||
CIE XYZ tristimulus values x_ref = 95.047, y_ref = 100., z_ref = 108.883
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] http://www.easyrgb.com/index.php?X=MATH&H=07#text7
|
||||
.. [2] http://en.wikipedia.org/wiki/Lab_color_space
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from skimage import data
|
||||
>>> from skimage.color import rgb2xyz, xyz2lab
|
||||
>>> lena = data.lena()
|
||||
>>> lena_xyz = rgb2xyz(lena)
|
||||
>>> lena_lab = xyz2lab(lena_xyz)
|
||||
"""
|
||||
arr = _prepare_colorarray(xyz)
|
||||
|
||||
# scale by CIE XYZ tristimulus values of the reference white point
|
||||
arr = arr / lab_ref_white
|
||||
|
||||
# Nonlinear distortion and linear transformation
|
||||
mask = arr > 0.008856
|
||||
arr[mask] = np.power(arr[mask], 1. / 3.)
|
||||
arr[~mask] = 7.787 * arr[~mask] + 16. / 116.
|
||||
|
||||
x, y, z = arr[:, :, 0], arr[:, :, 1], arr[:, :, 2]
|
||||
|
||||
# Vector scaling
|
||||
L = (116. * y) - 16.
|
||||
a = 500.0 * (x - y)
|
||||
b = 200.0 * (y - z)
|
||||
|
||||
return np.dstack([L, a, b])
|
||||
|
||||
|
||||
def lab2xyz(lab):
|
||||
"""CIE-LAB to XYZcolor space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
lab : array_like
|
||||
The image in lab format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in XYZ format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `lab` is not a 3-D array of shape (.., .., 3).
|
||||
|
||||
Notes
|
||||
-----
|
||||
Observer= 2A, Illuminant= D65
|
||||
CIE XYZ tristimulus values x_ref = 95.047, y_ref = 100., z_ref = 108.883
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] http://www.easyrgb.com/index.php?X=MATH&H=07#text7
|
||||
.. [2] http://en.wikipedia.org/wiki/Lab_color_space
|
||||
|
||||
"""
|
||||
|
||||
arr = _prepare_colorarray(lab).copy()
|
||||
|
||||
L, a, b = arr[:, :, 0], arr[:, :, 1], arr[:, :, 2]
|
||||
y = (L + 16.) / 116.
|
||||
x = (a / 500.) + y
|
||||
z = y - (b / 200.)
|
||||
|
||||
out = np.dstack([x, y, z])
|
||||
|
||||
mask = out > 0.2068966
|
||||
out[mask] = np.power(out[mask], 3.)
|
||||
out[~mask] = (out[~mask] - 16.0 / 116.) / 7.787
|
||||
|
||||
# rescale Observer= 2 deg, Illuminant= D65
|
||||
out *= lab_ref_white
|
||||
return out
|
||||
|
||||
|
||||
def rgb2lab(rgb):
|
||||
"""RGB to lab color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in Lab format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `rgb` is not a 3-D array of shape (.., .., 3).
|
||||
|
||||
Notes
|
||||
-----
|
||||
This function uses rgb2xyz and xyz2lab.
|
||||
"""
|
||||
return xyz2lab(rgb2xyz(rgb))
|
||||
|
||||
|
||||
def lab2rgb(lab):
|
||||
"""Lab to RGB color space conversion.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
rgb : array_like
|
||||
The image in Lab format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
The image in RGB format, in a 3-D array of shape (.., .., 3).
|
||||
|
||||
Raises
|
||||
------
|
||||
ValueError
|
||||
If `lab` is not a 3-D array of shape (.., .., 3).
|
||||
|
||||
Notes
|
||||
-----
|
||||
This function uses lab2xyz and xyz2rgb.
|
||||
"""
|
||||
return xyz2rgb(lab2xyz(lab))
|
||||
|
||||
@@ -23,7 +23,9 @@ from skimage.color import (
|
||||
rgb2xyz, xyz2rgb,
|
||||
rgb2rgbcie, rgbcie2rgb,
|
||||
convert_colorspace,
|
||||
rgb2grey, gray2rgb
|
||||
rgb2grey, gray2rgb,
|
||||
xyz2lab, lab2xyz,
|
||||
lab2rgb, rgb2lab
|
||||
)
|
||||
|
||||
from skimage import data_dir
|
||||
@@ -43,6 +45,19 @@ class TestColorconv(TestCase):
|
||||
colbars_point75 = colbars * 0.75
|
||||
colbars_point75_array = np.swapaxes(colbars_point75.reshape(3, 4, 2), 0, 2)
|
||||
|
||||
xyz_array = np.array([[[0.4124, 0.21260, 0.01930]], # red
|
||||
[[0, 0, 0]], # black
|
||||
[[.9505, 1., 1.089]], # white
|
||||
[[.1805, .0722, .9505]], # blue
|
||||
[[.07719, .15438, .02573]], # green
|
||||
])
|
||||
lab_array = np.array([[[53.233, 80.109, 67.220]], # red
|
||||
[[0., 0., 0.]], # black
|
||||
[[100.0, 0.005, -0.010]], # white
|
||||
[[32.303, 79.197, -107.864]], # blue
|
||||
[[46.229, -51.7, 49.898]], # green
|
||||
])
|
||||
|
||||
# RGB to HSV
|
||||
def test_rgb2hsv_conversion(self):
|
||||
rgb = img_as_float(self.img_rgb)[::16, ::16]
|
||||
@@ -57,8 +72,7 @@ class TestColorconv(TestCase):
|
||||
self.assertRaises(ValueError, rgb2hsv, self.img_grayscale)
|
||||
|
||||
def test_rgb2hsv_error_one_element(self):
|
||||
self.assertRaises(ValueError, rgb2hsv, self.img_rgb[0,0])
|
||||
|
||||
self.assertRaises(ValueError, rgb2hsv, self.img_rgb[0, 0])
|
||||
|
||||
# HSV to RGB
|
||||
def test_hsv2rgb_conversion(self):
|
||||
@@ -74,19 +88,18 @@ class TestColorconv(TestCase):
|
||||
self.assertRaises(ValueError, hsv2rgb, self.img_grayscale)
|
||||
|
||||
def test_hsv2rgb_error_one_element(self):
|
||||
self.assertRaises(ValueError, hsv2rgb, self.img_rgb[0,0])
|
||||
|
||||
self.assertRaises(ValueError, hsv2rgb, self.img_rgb[0, 0])
|
||||
|
||||
# RGB to XYZ
|
||||
def test_rgb2xyz_conversion(self):
|
||||
gt = np.array([[[ 0.950456, 1. , 1.088754],
|
||||
[ 0.538003, 0.787329, 1.06942 ],
|
||||
[ 0.592876, 0.28484 , 0.969561],
|
||||
[ 0.180423, 0.072169, 0.950227]],
|
||||
[[ 0.770033, 0.927831, 0.138527],
|
||||
[ 0.35758 , 0.71516 , 0.119193],
|
||||
[ 0.412453, 0.212671, 0.019334],
|
||||
[ 0. , 0. , 0. ]]])
|
||||
gt = np.array([[[0.950456, 1. , 1.088754],
|
||||
[0.538003, 0.787329, 1.06942 ],
|
||||
[0.592876, 0.28484 , 0.969561],
|
||||
[0.180423, 0.072169, 0.950227]],
|
||||
[[0.770033, 0.927831, 0.138527],
|
||||
[0.35758 , 0.71516 , 0.119193],
|
||||
[0.412453, 0.212671, 0.019334],
|
||||
[0. , 0. , 0. ]]])
|
||||
assert_almost_equal(rgb2xyz(self.colbars_array), gt)
|
||||
|
||||
# stop repeating the "raises" checks for all other functions that are
|
||||
@@ -95,8 +108,7 @@ class TestColorconv(TestCase):
|
||||
self.assertRaises(ValueError, rgb2xyz, self.img_grayscale)
|
||||
|
||||
def test_rgb2xyz_error_one_element(self):
|
||||
self.assertRaises(ValueError, rgb2xyz, self.img_rgb[0,0])
|
||||
|
||||
self.assertRaises(ValueError, rgb2xyz, self.img_rgb[0, 0])
|
||||
|
||||
# XYZ to RGB
|
||||
def test_xyz2rgb_conversion(self):
|
||||
@@ -104,7 +116,6 @@ class TestColorconv(TestCase):
|
||||
assert_almost_equal(xyz2rgb(rgb2xyz(self.colbars_array)),
|
||||
self.colbars_array)
|
||||
|
||||
|
||||
# RGB to RGB CIE
|
||||
def test_rgb2rgbcie_conversion(self):
|
||||
gt = np.array([[[ 0.1488856 , 0.18288098, 0.19277574],
|
||||
@@ -117,7 +128,6 @@ class TestColorconv(TestCase):
|
||||
[ 0. , 0. , 0. ]]])
|
||||
assert_almost_equal(rgb2rgbcie(self.colbars_array), gt)
|
||||
|
||||
|
||||
# RGB CIE to RGB
|
||||
def test_rgbcie2rgb_conversion(self):
|
||||
# only roundtrip test, we checked rgb2rgbcie above already
|
||||
@@ -151,6 +161,24 @@ class TestColorconv(TestCase):
|
||||
|
||||
assert_equal(g.shape, (1, 1))
|
||||
|
||||
def test_rgb2grey_on_grey(self):
|
||||
rgb2grey(np.random.random((5, 5)))
|
||||
|
||||
# test matrices for xyz2lab and lab2xyz generated using http://www.easyrgb.com/index.php?X=CALC
|
||||
# Note: easyrgb website displays xyz*100
|
||||
def test_xyz2lab(self):
|
||||
assert_array_almost_equal(xyz2lab(self.xyz_array),
|
||||
self.lab_array, decimal=3)
|
||||
|
||||
def test_lab2xyz(self):
|
||||
assert_array_almost_equal(lab2xyz(self.lab_array),
|
||||
self.xyz_array, decimal=3)
|
||||
|
||||
def test_lab_rgb_roundtrip(self):
|
||||
img_rgb = img_as_float(self.img_rgb)
|
||||
assert_array_almost_equal(lab2rgb(rgb2lab(img_rgb)), img_rgb)
|
||||
|
||||
|
||||
def test_gray2rgb():
|
||||
x = np.array([0, 0.5, 1])
|
||||
assert_raises(ValueError, gray2rgb, x)
|
||||
@@ -170,4 +198,3 @@ def test_gray2rgb():
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_module_suite()
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import os as _os
|
||||
from ..io import imread
|
||||
from skimage import data_dir
|
||||
|
||||
|
||||
def load(f):
|
||||
"""Load an image file located in the data directory.
|
||||
|
||||
@@ -26,13 +27,16 @@ def load(f):
|
||||
"""
|
||||
return imread(_os.path.join(data_dir, f))
|
||||
|
||||
|
||||
def camera():
|
||||
"""Gray-level "camera" image, often used for segmentation
|
||||
and denoising examples.
|
||||
"""Gray-level "camera" image.
|
||||
|
||||
Often used for segmentation and denoising examples.
|
||||
|
||||
"""
|
||||
return load("camera.png")
|
||||
|
||||
|
||||
def lena():
|
||||
"""Colour "Lena" image.
|
||||
|
||||
@@ -44,8 +48,9 @@ def lena():
|
||||
"""
|
||||
return load("lena.png")
|
||||
|
||||
|
||||
def text():
|
||||
""" Gray-level "text" image used for corner detection.
|
||||
"""Gray-level "text" image used for corner detection.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -56,7 +61,8 @@ def text():
|
||||
|
||||
"""
|
||||
|
||||
return load("text.png")
|
||||
return load("text.png")
|
||||
|
||||
|
||||
def checkerboard():
|
||||
"""Checkerboard image.
|
||||
@@ -68,6 +74,7 @@ def checkerboard():
|
||||
"""
|
||||
return load("chessboard_GRAY.png")
|
||||
|
||||
|
||||
def coins():
|
||||
"""Greek coins from Pompeii.
|
||||
|
||||
@@ -88,6 +95,7 @@ def coins():
|
||||
"""
|
||||
return load("coins.png")
|
||||
|
||||
|
||||
def moon():
|
||||
"""Surface of the moon.
|
||||
|
||||
@@ -97,6 +105,7 @@ def moon():
|
||||
"""
|
||||
return load("moon.png")
|
||||
|
||||
|
||||
def page():
|
||||
"""Scanned page.
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 170 KiB |
|
After Width: | Height: | Size: 199 KiB |
|
After Width: | Height: | Size: 193 KiB |
@@ -1,22 +1,39 @@
|
||||
import skimage.data as data
|
||||
from numpy.testing import assert_equal, assert_array_equal
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal
|
||||
|
||||
|
||||
def test_lena():
|
||||
""" Test that "Lena" image can be loaded. """
|
||||
lena = data.lena()
|
||||
assert_equal(lena.shape, (512, 512, 3))
|
||||
|
||||
|
||||
def test_camera():
|
||||
""" Test that "camera" image can be loaded. """
|
||||
cameraman = data.camera()
|
||||
assert_equal(cameraman.ndim, 2)
|
||||
|
||||
|
||||
def test_checkerboard():
|
||||
""" Test that checkerboard image can be loaded. """
|
||||
checkerboard = data.checkerboard()
|
||||
""" Test that "checkerboard" image can be loaded. """
|
||||
data.checkerboard()
|
||||
|
||||
|
||||
def test_text():
|
||||
""" Test that "text" image can be loaded. """
|
||||
data.text()
|
||||
|
||||
|
||||
def test_moon():
|
||||
""" Test that "moon" image can be loaded. """
|
||||
data.moon()
|
||||
|
||||
|
||||
def test_page():
|
||||
""" Test that "page" image can be loaded. """
|
||||
data.page()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from numpy.testing import run_module_suite
|
||||
run_module_suite()
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
from .draw import *
|
||||
from ._draw import line, polygon, ellipse, circle
|
||||
bresenham = line
|
||||
|
||||
@@ -3,11 +3,7 @@ import math
|
||||
from libc.math cimport sqrt
|
||||
cimport numpy as np
|
||||
cimport cython
|
||||
|
||||
|
||||
cdef extern from "../morphology/_pnpoly.h":
|
||||
int pnpoly(int nr_verts, double *xp, double *yp,
|
||||
double x, double y)
|
||||
from skimage._shared.geometry cimport point_in_polygon
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@@ -69,6 +65,7 @@ def line(int y, int x, int y2, int x2):
|
||||
|
||||
return rr, cc
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@cython.wraparound(False)
|
||||
@cython.nonecheck(False)
|
||||
@@ -78,9 +75,9 @@ def polygon(y, x, shape=None):
|
||||
Parameters
|
||||
----------
|
||||
y : (N,) ndarray
|
||||
y coordinates of vertices of polygon
|
||||
Y-coordinates of vertices of polygon.
|
||||
x : (N,) ndarray
|
||||
x coordinates of vertices of polygon
|
||||
X-coordinates of vertices of polygon.
|
||||
shape : tuple, optional
|
||||
image shape which is used to determine maximum extents of output pixel
|
||||
coordinates. This is useful for polygons which exceed the image size.
|
||||
@@ -119,12 +116,13 @@ def polygon(y, x, shape=None):
|
||||
|
||||
for r in range(minr, maxr+1):
|
||||
for c in range(minc, maxc+1):
|
||||
if pnpoly(nr_verts, cptr, rptr, c, r):
|
||||
if point_in_polygon(nr_verts, cptr, rptr, c, r):
|
||||
rr.append(r)
|
||||
cc.append(c)
|
||||
|
||||
return np.array(rr), np.array(cc)
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
@cython.wraparound(False)
|
||||
@cython.nonecheck(False)
|
||||
@@ -135,9 +133,9 @@ def ellipse(double cy, double cx, double b, double a, shape=None):
|
||||
Parameters
|
||||
----------
|
||||
cy, cx : double
|
||||
centre coordinate of ellipse
|
||||
Centre coordinate of ellipse.
|
||||
b, a: double
|
||||
minor and major semi-axes. (x/a)**2 + (y/b)**2 = 1
|
||||
Minor and major semi-axes. ``(x/a)**2 + (y/b)**2 = 1``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -170,20 +168,21 @@ def ellipse(double cy, double cx, double b, double a, shape=None):
|
||||
|
||||
return np.array(rr), np.array(cc)
|
||||
|
||||
|
||||
def circle(double cy, double cx, double radius, shape=None):
|
||||
"""Generate coordinates of pixels within circle.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cy, cx : double
|
||||
centre coordinate of circle
|
||||
Centre coordinate of circle.
|
||||
radius: double
|
||||
radius of circle
|
||||
Radius of circle.
|
||||
|
||||
Returns
|
||||
-------
|
||||
rr, cc : ndarray of int
|
||||
Pixel coordinates of ellipse.
|
||||
Pixel coordinates of circle.
|
||||
May be used to directly index into an array, e.g.
|
||||
``img[rr, cc] = 1``.
|
||||
"""
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
"""
|
||||
Methods to draw on arrays.
|
||||
|
||||
"""
|
||||
|
||||
from ._draw import line, polygon, ellipse, circle
|
||||
bresenham = line
|
||||