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
  ...
This commit is contained in:
Yaroslav Halchenko
2012-12-01 22:02:33 -05:00
271 changed files with 11301 additions and 4172 deletions
+28
View File
@@ -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
+16 -6
View File
@@ -2,9 +2,9 @@
Project coordination
- Nicolas Pinto
Colour spaces and filters.
Colour spaces and filters, and image resizing.
Shape views: ``util.shape.view_as_windows`` and ``util.shape.view_as_blocks``
Montage helpers: ``util.montage``
Montage helpers: ``util.montage``.
- Damian Eads
Morphological operators
@@ -73,7 +73,8 @@
From whom we borrowed the example generation tools.
- Andreas Mueller
Example data set loader.
Example data set loader. Nosetest compatibility functions.
Quickshift image segmentation, Felzenszwalbs fast graph based segmentation.
- Yaroslav Halchenko
For sharing his expert advice on Debian packaging.
@@ -102,8 +103,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.
+5 -1
View File
@@ -4,10 +4,13 @@ Build Requirements
* `Numpy >= 1.6 <http://numpy.scipy.org/>`__
* `Cython >= 0.15 <http://www.cython.org/>`__
`Matplotlib >= 1.0 <http://matplotlib.sf.net>`__ is needed to generate the
examples in the documentation.
Runtime requirements
--------------------
* `SciPy >= 0.10 <http://scipy.org>`__
Known build errors
------------------
On Windows, the error ``Error:unable to find vcvarsall.bat`` means that
@@ -34,3 +37,4 @@ functionality is only available with the following installed:
`FreeImage <http://freeimage.sf.net>`__
The ``freeimage`` plugin provides support for reading various types of
image file formats, including multi-page TIFFs.
+50 -15
View File
@@ -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 -1
View File
@@ -1,7 +1,7 @@
Unless otherwise specified by LICENSE.txt files in individual
directories, all code is
Copyright (C) 2011, the scikits-image team
Copyright (C) 2011, the scikit-image team
All rights reserved.
Redistribution and use in source and binary forms, with or without
+2 -2
View File
@@ -3,11 +3,11 @@ Image Processing SciKit
Source
------
https://github.com/scikits-image/scikits-image
https://github.com/scikit-image/scikit-image
Mailing List
------------
http://groups.google.com/group/scikits-image
http://groups.google.com/group/scikit-image
Installation from source
------------------------
+71 -12
View File
@@ -2,30 +2,89 @@ How to make a new release of ``skimage``
========================================
- Update release notes.
- Update the version number in setup.py and bento.info and commit
- To show a list contributors, run ``doc/release/contributors.sh <commit>``,
where ``<commit>`` is the first commit since the previous release.
- Update the version number in ``setup.py`` and ``bento.info`` and commit
- Update the docs:
- Edit ``doc/source/themes/agogo/static/docversions.js`` and commit
- Build a clean version of the docs. Run "make" in the root dir, then
- 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 = .*
+3 -99
View File
@@ -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
+35 -14
View File
@@ -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
+96
View File
@@ -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)
+9 -9
View File
@@ -77,17 +77,17 @@ qthelp:
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in build/qthelp, like this:"
@echo "# qcollectiongenerator build/qthelp/scikitsimage.qhcp"
@echo "# qcollectiongenerator build/qthelp/scikitimage.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile build/qthelp/scikitsimage.qhc"
@echo "# assistant -collectionFile build/qthelp/scikitimage.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(DEST)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/scikitsimage"
@echo "# ln -s build/devhelp $$HOME/.local/share/devhelp/scikitsimage"
@echo "# mkdir -p $$HOME/.local/share/devhelp/scikitimage"
@echo "# ln -s build/devhelp $$HOME/.local/share/devhelp/scikitimage"
@echo "# devhelp"
latex:
@@ -123,9 +123,9 @@ gh-pages:
python gh-pages.py
gitwash:
python tools/gitwash/gitwash_dumper.py source scikits-image \
--project-url=http://scikits-image.org \
--project-ml-url=http://groups.google.com/group/scikits-image \
--repo-name=scikits-image \
--github-user=scikits-image \
python tools/gitwash/gitwash_dumper.py source scikit-image \
--project-url=http://scikit-image.org \
--project-ml-url=http://groups.google.com/group/scikit-image \
--repo-name=scikit-image \
--github-user=scikit-image \
--source-suffix=.txt
+132
View File
@@ -0,0 +1,132 @@
"""
===============================
Using geometric transformations
===============================
In this example, we will see how to use geometric transformations in the context
of image processing.
"""
import math
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage import transform as tf
margins = dict(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
"""
Basics
======
Several different geometric transformation types are supported: similarity,
affine, projective and polynomial.
Geometric transformations can either be created using the explicit parameters
(e.g. scale, shear, rotation and translation) or the transformation matrix:
First we create a transformation using explicit parameters:
"""
tform = tf.SimilarityTransform(scale=1, rotation=math.pi / 2,
translation=(0, 1))
print tform._matrix
"""
Alternatively you can define a transformation by the transformation matrix
itself:
"""
matrix = tform._matrix.copy()
matrix[1, 2] = 2
tform2 = tf.SimilarityTransform(matrix)
"""
These transformation objects can then be used to apply forward and inverse
coordinate transformations between the source and destination coordinate
systems:
"""
coord = [1, 0]
print tform2(coord)
print tform2.inverse(tform(coord))
"""
Image warping
=============
Geometric transformations can also be used to warp images:
"""
text = data.text()
tform = tf.SimilarityTransform(scale=1, rotation=math.pi / 4,
translation=(text.shape[0] / 2, -100))
rotated = tf.warp(text, tform)
back_rotated = tf.warp(rotated, tform.inverse)
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 3))
fig.subplots_adjust(**margins)
plt.gray()
ax1.imshow(text)
ax1.axis('off')
ax2.imshow(rotated)
ax2.axis('off')
ax3.imshow(back_rotated)
ax3.axis('off')
"""
.. image:: PLOT2RST.current_figure
Parameter estimation
====================
In addition to the basic functionality mentioned above you can also estimate the
parameters of a geometric transformation using the least-squares method.
This can amongst other things be used for image registration or rectification,
where you have a set of control points or homologous/corresponding points in two
images.
Let's assume we want to recognize letters on a photograph which was not taken
from the front but at a certain angle. In the simplest case of a plane paper
surface the letters are projectively distorted. Simple matching algorithms would
not be able to match such symbols. One solution to this problem would be to warp
the image so that the distortion is removed and then apply a matching algorithm:
"""
text = data.text()
src = np.array((
(0, 0),
(0, 50),
(300, 50),
(300, 0)
))
dst = np.array((
(155, 15),
(65, 40),
(260, 130),
(360, 95)
))
tform3 = tf.ProjectiveTransform()
tform3.estimate(src, dst)
warped = tf.warp(text, tform3, output_shape=(50, 300))
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(8, 3))
fig.subplots_adjust(**margins)
plt.gray()
ax1.imshow(text)
ax1.plot(dst[:, 0], dst[:, 1], '.r')
ax1.axis('off')
ax2.imshow(warped)
ax2.axis('off')
"""
.. image:: PLOT2RST.current_figure
"""
plt.show()
+86
View File
@@ -0,0 +1,86 @@
"""
===============================
Filling holes and finding peaks
===============================
In this example, we fill holes (i.e. isolated, dark spots) in an image using
morphological reconstruction by erosion. Erosion expands the minimal values of
the seed image until it encounters a mask image. Thus, the seed image and mask
image represent the maximum and minimum possible values of the reconstructed
image.
We start with an image containing both peaks and holes:
"""
import matplotlib.pyplot as plt
from skimage import data
from skimage.exposure import rescale_intensity
image = data.moon()
# Rescale image intensity so that we can see dim features.
image = rescale_intensity(image, in_range=(50, 200))
# convenience function for plotting images
def imshow(image, **kwargs):
plt.figure(figsize=(5, 4))
plt.imshow(image, **kwargs)
plt.axis('off')
imshow(image)
plt.title('original image')
"""
.. image:: PLOT2RST.current_figure
Now we need to create the seed image, where the minima represent the starting
points for erosion. To fill holes, we initialize the seed image to the maximum
value of the original image. Along the borders, however, we use the original
values of the image. These border pixels will be the starting points for the
erosion process. We then limit the erosion by setting the mask to the values
of the original image.
"""
import numpy as np
from skimage.morphology import reconstruction
seed = np.copy(image)
seed[1:-1, 1:-1] = image.max()
mask = image
filled = reconstruction(seed, mask, method='erosion')
imshow(filled, vmin=image.min(), vmax=image.max())
plt.title('after filling holes')
"""
.. image:: PLOT2RST.current_figure
As shown above, eroding inward from the edges removes holes, since (by
definition) holes are surrounded by pixels of brighter value. Finally, we can
isolate the dark regions by subtracting the reconstructed image from the
original image.
"""
imshow(image - filled)
plt.title('holes')
"""
.. image:: PLOT2RST.current_figure
Alternatively, we can find bright spots in an image using morphological
reconstruction by dilation. Dilation is the inverse of erosion and expands the
*maximal* values of the seed image until it encounters a mask image. Since this
is an inverse operation, we initialize the seed image to the minimum image
intensity instead of the maximum. The remainder of the process is the same.
"""
seed = np.copy(image)
seed[1:-1, 1:-1] = image.min()
rec = reconstruction(seed, mask, method='dilation')
imshow(image - rec)
plt.title('peaks')
plt.show()
"""
.. image:: PLOT2RST.current_figure
"""
+1 -1
View File
@@ -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)
+57
View File
@@ -0,0 +1,57 @@
"""
===================
Label image regions
===================
This example shows how to segment an image with image labelling. The following
steps are applied:
1. Thresholding with automatic Otsu method
2. Close small holes with binary closing
3. Remove artifacts touching image border
4. Measure image regions to filter small objects
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage import data
from skimage.filter import threshold_otsu
from skimage.segmentation import clear_border
from skimage.morphology import label, closing, square
from skimage.measure import regionprops
image = data.coins()[50:-50, 50:-50]
# apply threshold
thresh = threshold_otsu(image)
bw = closing(image > thresh, square(3))
# remove artifacts connected to image border
cleared = bw.copy()
clear_border(cleared)
# label image regions
label_image = label(cleared)
borders = np.logical_xor(bw, cleared)
label_image[borders] = -1
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
ax.imshow(label_image, cmap='jet')
for region in regionprops(label_image, ['Area', 'BoundingBox']):
# skip small images
if region['Area'] < 100:
continue
# draw rectangle around segmented coins
minr, minc, maxr, maxc = region['BoundingBox']
rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
fill=False, edgecolor='red', linewidth=2)
ax.add_patch(rect)
plt.show()
+87
View File
@@ -0,0 +1,87 @@
"""
===============================================
Local Binary Pattern for texture classification
===============================================
In this example, we will see how to classify textures based on LBP (Local
Binary Pattern). The histogram of the LBP result is a good measure to classify
textures. For simplicity the histogram distributions are then tested against
each other using the Kullback-Leibler-Divergence.
"""
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import scipy.ndimage as nd
import skimage.feature as ft
from skimage import data
# settings for LBP
METHOD = 'uniform'
P = 16
R = 2
matplotlib.rcParams['font.size'] = 9
def kullback_leibler_divergence(p, q):
p = np.asarray(p)
q = np.asarray(q)
filt = np.logical_and(p != 0, q != 0)
return np.sum(p[filt] * np.log2(p[filt] / q[filt]))
def match(refs, img):
best_score = 10
best_name = None
lbp = ft.local_binary_pattern(img, P, R, METHOD)
hist, _ = np.histogram(lbp, normed=True, bins=P + 2, range=(0, P + 2))
for name, ref in refs.items():
ref_hist, _ = np.histogram(ref, normed=True, bins=P + 2,
range=(0, P + 2))
score = kullback_leibler_divergence(hist, ref_hist)
if score < best_score:
best_score = score
best_name = name
return best_name
brick = data.load('brick.png')
grass = data.load('grass.png')
wall = data.load('rough-wall.png')
refs = {
'brick': ft.local_binary_pattern(brick, P, R, METHOD),
'grass': ft.local_binary_pattern(grass, P, R, METHOD),
'wall': ft.local_binary_pattern(wall, P, R, METHOD)
}
# classify rotated textures
print 'Rotated images matched against references using LBP:'
print 'original: brick, rotated: 30deg, match result:',
print match(refs, nd.rotate(brick, angle=30, reshape=False))
print 'original: brick, rotated: 70deg, match result:',
print match(refs, nd.rotate(brick, angle=70, reshape=False))
print 'original: grass, rotated: 145deg, match result:',
print match(refs, nd.rotate(grass, angle=145, reshape=False))
# plot histograms of LBP of textures
fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(nrows=2, ncols=3,
figsize=(9, 6))
plt.gray()
ax1.imshow(brick)
ax1.axis('off')
ax4.hist(refs['brick'].ravel(), normed=True, bins=P + 2, range=(0, P + 2))
ax4.set_ylabel('Percentage')
ax2.imshow(grass)
ax2.axis('off')
ax5.hist(refs['grass'].ravel(), normed=True, bins=P + 2, range=(0, P + 2))
ax5.set_xlabel('Uniform LBP values')
ax3.imshow(wall)
ax3.axis('off')
ax6.hist(refs['wall'].ravel(), normed=True, bins=P + 2, range=(0, P + 2))
plt.show()
+41
View File
@@ -0,0 +1,41 @@
"""
===============================
Piecewise Affine Transformation
===============================
This example shows how to use the Piecewise Affine Transformation.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage.transform import PiecewiseAffineTransform, warp
from skimage import data
image = data.lena()
rows, cols = image.shape[0], image.shape[1]
src_cols = np.linspace(0, cols, 20)
src_rows = np.linspace(0, rows, 10)
src_rows, src_cols = np.meshgrid(src_rows, src_cols)
src = np.dstack([src_cols.flat, src_rows.flat])[0]
# add sinusoidal oscillation to row coordinates
dst_rows = src[:, 1] - np.sin(np.linspace(0, 3 * np.pi, src.shape[0])) * 50
dst_cols = src[:, 0]
dst_rows *= 1.5
dst_rows -= 1.5 * 50
dst = np.vstack([dst_cols, dst_rows]).T
tform = PiecewiseAffineTransform()
tform.estimate(src, dst)
out_rows = image.shape[0] - 1.5 * 50
out_cols = cols
out = warp(image, tform, output_shape=(out_rows, out_cols))
plt.imshow(out)
plt.plot(tform.inverse(src)[:, 0], tform.inverse(src)[:, 1], '.b')
plt.axis((0, out_cols, out_rows, 0))
plt.show()
+77
View File
@@ -0,0 +1,77 @@
"""
==================================
Approximate and subdivide polygons
==================================
This example shows how to approximate (Douglas-Peucker algorithm) and subdivide
(B-Splines) polygonal chains.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage.draw import ellipse
from skimage.measure import find_contours, approximate_polygon, \
subdivide_polygon
hand = np.array([[1.64516129, 1.16145833],
[1.64516129, 1.59375 ],
[1.35080645, 1.921875 ],
[1.375 , 2.18229167],
[1.68548387, 1.9375 ],
[1.60887097, 2.55208333],
[1.68548387, 2.69791667],
[1.76209677, 2.56770833],
[1.83064516, 1.97395833],
[1.89516129, 2.75 ],
[1.9516129 , 2.84895833],
[2.01209677, 2.76041667],
[1.99193548, 1.99479167],
[2.11290323, 2.63020833],
[2.2016129 , 2.734375 ],
[2.25403226, 2.60416667],
[2.14919355, 1.953125 ],
[2.30645161, 2.36979167],
[2.39112903, 2.36979167],
[2.41532258, 2.1875 ],
[2.1733871 , 1.703125 ],
[2.07782258, 1.16666667]])
# subdivide polygon using 2nd degree B-Splines
new_hand = hand.copy()
for _ in range(5):
new_hand = subdivide_polygon(new_hand, degree=2, preserve_ends=True)
# approximate subdivided polygon with Douglas-Peucker algorithm
appr_hand = approximate_polygon(new_hand, tolerance=0.02)
print "Number of coordinates:", len(hand), len(new_hand), len(appr_hand)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(9, 4))
ax1.plot(hand[:, 0], hand[:, 1])
ax1.plot(new_hand[:, 0], new_hand[:, 1])
ax1.plot(appr_hand[:, 0], appr_hand[:, 1])
# create two ellipses in image
img = np.zeros((800, 800), 'int32')
rr, cc = ellipse(250, 250, 180, 230, img.shape)
img[rr, cc] = 1
rr, cc = ellipse(600, 600, 150, 90, img.shape)
img[rr, cc] = 1
plt.gray()
ax2.imshow(img)
# approximate / simplify coordinates of the two ellipses
for contour in find_contours(img, 0):
coords = approximate_polygon(contour, tolerance=2.5)
ax2.plot(coords[:, 1], coords[:, 0], '-r', linewidth=2)
coords2 = approximate_polygon(contour, tolerance=39.5)
ax2.plot(coords2[:, 1], coords2[:, 0], '-g', linewidth=2)
print "Number of coordinates:", len(contour), len(coords), len(coords2)
ax2.axis((0, 800, 0, 800))
plt.show()
+35
View File
@@ -0,0 +1,35 @@
"""
====================
Build image pyramids
====================
The `pyramid_gaussian` function takes an image and yields successive images
shrunk by a constant scale factor. Image pyramids are often used, e.g., to
implement algorithms for denoising, texture discrimination, and scale- invariant
detection.
"""
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.transform import pyramid_gaussian
image = data.lena()
rows, cols, dim = image.shape
pyramid = tuple(pyramid_gaussian(image, downscale=2))
composite_image = np.zeros((rows, cols + cols / 2, 3), dtype=np.double)
composite_image[:rows, :cols, :] = pyramid[0]
i_row = 0
for p in pyramid[1:]:
n_rows, n_cols = p.shape[:2]
composite_image[i_row:i_row + n_rows, cols:cols + n_cols] = p
i_row += n_rows
plt.imshow(composite_image)
plt.show()
+113
View File
@@ -0,0 +1,113 @@
"""
=========================
Filtering regional maxima
=========================
Here, we use morphological reconstruction to create a background image, which
we can subtract from the original image to isolate bright features (regional
maxima).
First we try reconstruction by dilation starting at the edges of the image. We
initialize a seed image to the minimum intensity of the image, and set its
border to be the pixel values in the original image. These maximal pixels will
get dilated in order to reconstruct the background image.
"""
import numpy as np
from skimage import data
from skimage import img_as_float
from skimage.morphology import reconstruction
from scipy.ndimage import gaussian_filter
import matplotlib.pyplot as plt
# Convert to float: Important for subtraction later which won't work with uint8
image = img_as_float(data.coins())
image = gaussian_filter(image, 1)
seed = np.copy(image)
seed[1:-1, 1:-1] = image.min()
mask = image
dilated = reconstruction(seed, mask, method='dilation')
"""
Subtracting the dilated image leaves an image with just the coins and a flat,
black background, as shown below.
"""
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 2.5))
ax1.imshow(image)
ax1.set_title('original image')
ax1.axis('off')
ax2.imshow(dilated, vmin=image.min(), vmax=image.max())
ax2.set_title('dilated')
ax2.axis('off')
ax3.imshow(image - dilated)
ax3.set_title('image - dilated')
ax3.axis('off')
plt.tight_layout()
"""
.. image:: PLOT2RST.current_figure
Although the features (i.e. the coins) are clearly isolated, the coins
surrounded by a bright background in the original image are dimmer in the
subtracted image. We can attempt to correct this using a different seed image.
Instead of creating a seed image with maxima along the image border, we can use
the features of the image itself to seed the reconstruction process. Here, the
seed image is the original image minus a fixed value, ``h``.
"""
h = 0.4
seed = image - h
dilated = reconstruction(seed, mask, method='dilation')
hdome = image - dilated
"""
To get a feel for the reconstruction process, we plot the intensity of the
mask, seed, and dilated images along a slice of the image (indicated by red
line).
"""
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 2.5))
yslice = 197
ax1.plot(mask[yslice], '0.5', label='mask')
ax1.plot(seed[yslice], 'k', label='seed')
ax1.plot(dilated[yslice], 'r', label='dilated')
ax1.set_ylim(-0.2, 2)
ax1.set_title('image slice')
ax1.set_xticks([])
ax1.legend()
ax2.imshow(dilated, vmin=image.min(), vmax=image.max())
ax2.axhline(yslice, color='r', alpha=0.4)
ax2.set_title('dilated')
ax2.axis('off')
ax3.imshow(hdome)
ax3.axhline(yslice, color='r', alpha=0.4)
ax3.set_title('image - dilated')
ax3.axis('off')
plt.tight_layout()
plt.show()
"""
.. image:: PLOT2RST.current_figure
As you can see in the image slice, each coin is given a different baseline
intensity in the reconstructed image; this is because we used the local
intensity (shifted by ``h``) as a seed value. As a result, the coins in the
subtracted image have similar pixel intensities. The final result is known as
the h-dome of an image since this tends to isolate regional maxima of height
``h``. This operation is particularly useful when your images are unevenly
illuminated.
"""
+92
View File
@@ -0,0 +1,92 @@
"""
====================================================
Comparison of segmentation and superpixel algorithms
====================================================
This example compares three popular low-level image segmentation methods. As
it is difficult to obtain good segmentations, and the definition of "good"
often depends on the application, these methods are usually used for obtaining
an oversegmentation, also known as superpixels. These superpixels then serve as
a basis for more sophisticated algorithms such as conditional random fields
(CRF).
Felzenszwalb's efficient graph based segmentation
-------------------------------------------------
This fast 2D image segmentation algorithm, proposed in [1]_ is popular in the
computer vision community.
The algorithm has a single ``scale`` parameter that influences the segment
size. The actual size and number of segments can vary greatly, depending on
local contrast.
.. [1] Efficient graph-based image segmentation, Felzenszwalb, P.F. and
Huttenlocher, D.P. International Journal of Computer Vision, 2004
Quickshift image segmentation
-----------------------------
Quickshift is a relatively recent 2D image segmentation algorithm, based on an
approximation of kernelized mean-shift. Therefore it belongs to the family of
local mode-seeking algorithms and is applied to the 5D space consisting of
color information and image location [2]_.
One of the benefits of quickshift is that it actually computes a
hierarchical segmentation on multiple scales simultaneously.
Quickshift has two main parameters: ``sigma`` controls the scale of the local
density approximation, ``max_dist`` selects a level in the hierarchical
segmentation that is produced. There is also a trade-off between distance in
color-space and distance in image-space, given by ``ratio``.
.. [2] Quick shift and kernel methods for mode seeking,
Vedaldi, A. and Soatto, S.
European Conference on Computer Vision, 2008
SLIC - K-Means based image segmentation
---------------------------------------
This algorithm simply performs K-means in the 5d space of color information
and image location and is therefore closely related to quickshift. As the
clustering method is simpler, it is very efficient. It is essential for this
algorithm to work in Lab color space to obtain good results. The algorithm
quickly gained momentum and is now widely used. See [3] for details. The
``ratio`` parameter trades off color-similarity and proximity, as in the case
of Quickshift, while ``n_segments`` chooses the number of centers for kmeans.
.. [3] Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi,
Pascal Fua, and Sabine Suesstrunk, SLIC Superpixels Compared to
State-of-the-art Superpixel Methods, TPAMI, May 2012.
"""
import matplotlib.pyplot as plt
import numpy as np
from skimage.data import lena
from skimage.segmentation import felzenszwalb, \
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()
+4 -4
View File
@@ -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
+1 -1
View File
@@ -16,7 +16,7 @@ In the case of boolean, 'True' indicates foreground, and for integer arrays,
the foreground is 1's.
"""
from skimage.morphology import skeletonize
from skimage.draw import draw
from skimage import draw
import numpy as np
import matplotlib.pyplot as plt
+34 -7
View File
@@ -9,7 +9,7 @@ To generate your own examples, add this extension to the list of
example directory(ies) in `plot2rst_paths` (see below) points to a directory
with examples named `plot_*.py` and include an `index.rst` file.
This code was adapted from scikits-image, which took it from scikits-learn.
This code was adapted from scikit-image, which took it from scikit-learn.
Options
-------
@@ -27,9 +27,10 @@ plot2rst_rcparams : dict
plot2rst_default_thumb : str
Path (relative to doc root) of default thumbnail image.
plot2rst_thumb_scale : float
Scale factor for thumbnail (e.g., 0.2 to scale plot to 1/5th the
original size).
plot2rst_thumb_shape : float
Shape of thumbnail in pixels. The image is resized to fit within this shape
and the excess is filled with white pixels. This fixed size ensures that
that gallery images are displayed in a grid.
plot2rst_plot_tag : str
When this tag is found in the example file, the current plot is saved and
@@ -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
+4 -4
View File
@@ -30,7 +30,7 @@ from subprocess import Popen, PIPE, CalledProcessError, check_call
pages_dir = 'gh-pages'
html_dir = 'build/html'
pdf_dir = 'build/latex'
pages_repo = 'git@github.com:scikits-image/docs.git'
pages_repo = 'git@github.com:scikit-image/docs.git'
#-----------------------------------------------------------------------------
# Functions
@@ -108,7 +108,7 @@ if __name__ == '__main__':
shutil.copytree(html_dir, dest)
# copy pdf file into tree
#shutil.copy(pjoin(pdf_dir, 'scikits.image.pdf'), pjoin(dest, 'scikits.image.pdf'))
try:
cd(pages_dir)
status = sh2('git status | head -1')
@@ -117,7 +117,7 @@ if __name__ == '__main__':
e = 'On %r, git branch is %r, MUST be "gh-pages"' % (pages_dir,
branch)
raise RuntimeError(e)
sh("touch .nojekyll")
sh("touch .nojekyll")
sh('git add .nojekyll')
sh('git add index.html')
sh('git add %s' % tag)
@@ -131,4 +131,4 @@ if __name__ == '__main__':
print
print 'Now verify the build in: %r' % dest
print "If everything looks good, 'git push'"
print "If everything looks good, run 'git push' inside doc/gh-pages."
+2 -2
View File
@@ -1,11 +1,11 @@
.PHONY: logo
logo: green_orange_snake.png snake_logo.svg
inkscape --export-png=scikits_image_logo.png --export-dpi=100 \
inkscape --export-png=scikit_image_logo.png --export-dpi=100 \
--export-area-drawing --export-background-opacity=1 \
snake_logo.svg
python shrink_logo.py
green_orange_snake.png:
python scikits_image_logo.py --no-plot
python scikit_image_logo.py --no-plot
+2 -2
View File
@@ -2,7 +2,7 @@ from skimage import io, transform
s = 0.7
img = io.imread('scikits_image_logo.png')
img = io.imread('scikit_image_logo.png')
h, w, c = img.shape
print "\nScaling down logo by %.1fx..." % s
@@ -13,4 +13,4 @@ img = transform.homography(img, [[s, 0, 0],
output_shape=(int(h*s), int(w*s), 4),
order=3)
io.imsave('scikits_image_logo_small.png', img)
io.imsave('scikit_image_logo_small.png', img)
+1 -1
View File
@@ -74,7 +74,7 @@
y="278.58533"
x="261.22247"
id="tspan3152"
sodipodi:role="line">scikits-image</tspan></text>
sodipodi:role="line">scikit-image</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3154"

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

+2 -2
View File
@@ -74,9 +74,9 @@ if "%1" == "qthelp" (
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in build/qthelp, like this:
echo.^> qcollectiongenerator build\qthelp\scikitsimage.qhcp
echo.^> qcollectiongenerator build\qthelp\scikitimage.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile build\qthelp\scikitsimage.ghc
echo.^> assistant -collectionFile build\qthelp\scikitimage.ghc
goto end
)
+1 -1
View File
@@ -1,2 +1,2 @@
git log $1..HEAD --format='* %aN' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u
git log $1..HEAD --format='- %aN' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u
+69
View File
@@ -0,0 +1,69 @@
Announcement: scikits-image 0.7.0
=================================
We're happy to announce the 7th version of scikits-image!
Scikits-image is an image processing toolbox for SciPy that includes algorithms
for segmentation, geometric transformations, color space manipulation,
analysis, filtering, morphology, feature detection, and more.
For more information, examples, and documentation, please visit our website
http://skimage.org
New Features
------------
It's been only 3 months since scikits-image 0.6 was released, but in that short
time, we've managed to add plenty of new features and enhancements, including
- Geometric image transforms
- 3 new image segmentation routines (Felsenzwalb, Quickshift, SLIC)
- Local binary patterns for texture characterization
- Morphological reconstruction
- Polygon approximation
- CIE Lab color space conversion
- Image pyramids
- Multispectral support in random walker segmentation
- Slicing, concatenation, and natural sorting of image collections
- Perimeter and coordinates measurements in regionprops
- An extensible image viewer based on Qt and Matplotlib, with plugins for edge
detection, line-profiling, and viewing image collections
Plus, this release adds a number of bug fixes, new examples, and performance
enhancements.
Contributors to this release
----------------------------
This release was only possible due to the efforts of many contributors, both
new and old.
- Andreas Mueller
- Andreas Wuerl
- Andy Wilson
- Brian Holt
- Christoph Gohlke
- Dharhas Pothina
- Emmanuelle Gouillart
- Guillaume Gay
- Josh Warner
- James Bergstra
- Johannes Schonberger
- Jonathan J. Helmus
- Juan Nunez-Iglesias
- Leon Tietz
- Marianne Corvellec
- Matt McCormick
- Neil Yager
- Nicolas Pinto
- Nicolas Poilvert
- Pavel Campr
- Petter Strandmark
- Stefan van der Walt
- Tim Sheerman-Chase
- Tomas Kazmar
- Tony S Yu
- Wei Li
-144
View File
@@ -1,144 +0,0 @@
/* This CSS stylesheet is no longer used. Edit agogo.css instead. */
/**
* Sphinx stylesheet -- default theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: {{ theme_bodyfont }};
font-size: 100%;
background-color: {{ theme_footerbgcolor }};
color: #000;
margin: 0;
padding: 0;
}
div.document {
background-color: {{ theme_sidebarbgcolor }};
}
div.documentwrapper {
float: left;
width: 100%;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: {{ theme_bgcolor }};
color: {{ theme_textcolor }};
padding: 0 20px 30px 20px;
overflow: auto;
}
{%- if theme_rightsidebar|tobool %}
div.bodywrapper {
margin: 0 230px 0 0;
}
{%- endif %}
div.footer {
color: {{ theme_footertextcolor }};
width: 100%;
padding: 9px 0 9px 0;
text-align: center;
font-size: 75%;
}
div.footer a {
color: {{ theme_footertextcolor }};
text-decoration: underline;
}
div.related {
background-color: {{ theme_relbarbgcolor }};
line-height: 30px;
color: {{ theme_relbartextcolor }};
}
div.related a {
color: {{ theme_relbarlinkcolor }};
}
div.sphinxsidebar {
{%- if theme_stickysidebar|tobool %}
top: 30px;
margin: 0;
position: fixed;
overflow: auto;
height: 100%;
{%- endif %}
{%- if theme_rightsidebar|tobool %}
float: right;
{%- if theme_stickysidebar|tobool %}
right: 0;
{%- endif %}
{%- endif %}
}
{%- if theme_stickysidebar|tobool %}
/* this is nice, but it it leads to hidden headings when jumping
to an anchor */
/*
div.related {
position: fixed;
}
div.documentwrapper {
margin-top: 30px;
}
*/
{%- endif %}
div.sphinxsidebar h3 {
font-family: {{ theme_headfont }};
color: {{ theme_sidebartextcolor }};
font-size: 1.4em;
font-weight: normal;
margin: 0;
padding: 0;
}
div.sphinxsidebar h3 a {
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar h4 {
font-family: {{ theme_headfont }};
color: {{ theme_sidebartextcolor }};
font-size: 1.3em;
font-weight: normal;
margin: 5px 0 0 0;
padding: 0;
}
div.sphinxsidebar p {
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar p.topless {
margin: 5px 10px 10px 10px;
}
div.sphinxsidebar ul {
margin: 10px;
padding: 0;
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar a {
color: {{ theme_sidebarlinkcolor }};
}
div.sphinxsidebar input {
border: 1px solid {{ theme_sidebarlinkcolor }};
font-family: sans-serif;
font-size: 1em;
}
@@ -1,7 +1,5 @@
function insert_version_links() {
var labels = ['dev', '0.6', '0.5', '0.4', '0.3'];
document.write('<ul class="versions">\n');
var labels = ['dev', '0.7.0', '0.6', '0.5', '0.4', '0.3'];
for (i = 0; i < labels.length; i++){
open_list = '<li>'
@@ -14,7 +12,6 @@ function insert_version_links() {
document.write(open_list);
document.write('<a href="URL">skimage VERSION</a> </li>\n'
.replace('VERSION', labels[i])
.replace('URL', 'http://scikits-image.org/docs/' + labels[i]));
.replace('URL', 'http://scikit-image.org/docs/' + labels[i]));
}
document.write('</ul>\n');
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

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

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

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

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

+20 -2
View File
@@ -14,13 +14,13 @@ Data type Range
uint8 0 to 255
uint16 0 to 65535
uint32 0 to 2\ :sup:`32`
float 0 to 1
float -1 to 1
int8 -128 to 127
int16 -32768 to 32767
int32 -2\ :sup:`31` to 2\ :sup:`31` - 1
========= =================================
Note that float images are restricted to the range 0 to 1 even though the data
Note that float images are restricted to the range -1 to 1 even though the data
type itself can exceed this range; all integer dtypes, on the other hand, have
pixel intensities that can span the entire data type range. Currently, *64-bit
(u)int images are not supported*.
@@ -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
==========
+4 -4
View File
@@ -44,13 +44,13 @@ functions include one or more examples.
Mailing-list
------------
The scikits-image mailing-list is scikits-image@googlegroups.com (users
The scikit-image mailing-list is scikit-image@googlegroups.com (users
should join the `Google Group
<http://groups.google.com/group/scikits-image>`_ before posting). This
<http://groups.google.com/group/scikit-image>`_ before posting). This
mailing-list is shared by users and developers, and it is the right
place to ask any question about ``skimage``, or in general, image
processing using Python. Posting snippets of code with minimal examples
ensures to get more relevant and focused answers.
ensures to get more relevant and focused answers.
We would love to hear from how you use ``skimage`` for your work on the
mailing-list!
mailing-list!
@@ -47,10 +47,6 @@ detection, we use the `Canny detector
As the background is very smooth, almost all edges are found at the
boundary of the coins, or inside the coins.
Now that we have contours that delineate the outer boundary of the coins,
we fill the inner part of the coins using the
``ndimage.binary_fill_holes`` function, which uses mathematical morphology
to fill the holes.
::
@@ -61,6 +57,15 @@ to fill the holes.
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Now that we have contours that delineate the outer boundary of the coins,
we fill the inner part of the coins using the
``ndimage.binary_fill_holes`` function, which uses mathematical morphology
to fill the holes.
.. image:: ../../_images/plot_coins_segmentation_4.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Most coins are well segmented out of the background. Small objects from
the background can be easily removed using the ``ndimage.label``
function to remove objects smaller than a small threshold.
@@ -78,6 +83,10 @@ has not been segmented correctly at all. The reason is that the contour
that we got from the Canny detector was not completely closed, therefore
the filling function did not fill the inner part of the coin.
.. image:: ../../_images/plot_coins_segmentation_5.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Therefore, this segmentation method is not very robust: if we miss a
single pixel of the contour of the object, we will not be able to fill
it. Of course, we could try to dilate the contours in order to
@@ -117,12 +126,29 @@ separate the coins from the background.
.. image:: data/elevation_map.jpg
:align: center
and here is the corresponding 2-D plot:
.. image:: ../../_images/plot_coins_segmentation_6.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
The next step is to find markers of the background and the coins based on the
extreme parts of the histogram of grey values::
>>> markers = np.zeros_like(coins)
>>> markers[coins < 30] = 1
>>> markers[coins > 150] = 2
.. image:: ../../_images/plot_coins_segmentation_7.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
Let us now compute the watershed transform::
>>> from skimage.morphology import watershed
>>> segmentation = watershed(elevation_map, markers)
.. image:: ../../_images/plot_coins_segmentation_4.png
.. image:: ../../_images/plot_coins_segmentation_8.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
@@ -139,7 +165,7 @@ We can now label all the coins one by one using ``ndimage.label``::
>>> labeled_coins, _ = ndimage.label(segmentation)
.. image:: ../../_images/plot_coins_segmentation_5.png
.. image:: ../../_images/plot_coins_segmentation_9.png
:target: ../auto_examples/applications/plot_coins_segmentation.html
:align: center
+85
View File
@@ -0,0 +1,85 @@
Image Viewer
============
Quick Start
-----------
``skimage.viewer`` provides a matplotlib_-based canvas for displaying images and
a Qt-based GUI-toolkit, with the goal of making it easy to create interactive
image editors. You can simply use it to display an image:
.. code-block:: python
from skimage import data
from skimage.viewer import ImageViewer
image = data.coins()
viewer = ImageViewer(image)
viewer.show()
Of course, you could just as easily use ``imshow`` from matplotlib_ (or
alternatively, ``skimage.io.imshow`` which adds support for multiple
io-plugins) to display images. The advantage of ``ImageViewer`` is that you can
easily add plugins for manipulating images. Currently, only a few plugins are
implemented, but it is easy to write your own. Before going into the details,
let's see an example of how a plugin is added to the viewer:
.. code-block:: python
from skimage.viewer.plugins import Canny
viewer = ImageViewer(image)
viewer += Canny(view)
viewer.show()
At the moment, there aren't very many plugins pre-defined, but there's a really
simple interface for creating your own plugin. First, let's create a plugin to
call the total-variation denoising function, ``tv_denoise``:
.. code-block:: python
from skimage.filter import tv_denoise
from skimage.viewer.plugins.base import Plugin
denoise_plugin = Plugin(image_filter=tv_denoise)
.. note::
The ``Plugin`` assumes the first argument given to the image filter is the
image from the image viewer. In the future, this should be changed so you
can pass the image to a different argument of the filter function.
To actually interact with the filter, you have to add widgets that adjust the
parameters of the function. Typically, that means adding a slider widget and
connecting it to the filter parameter and the minimum and maximum values of the
slider:
.. code-block:: python
from skimage.viewer.widgets import Slider
from skimage.viewer.widgets.history import SaveButtons
denoise_plugin += Slider('weight', 0.01, 0.5, update_on='release')
denoise_plugin += SaveButtons()
Here, we connect a slider widget to the filter's 'weight' argument. We also
added some buttons for saving the image to file or to the ``scikit-image``
image stack (see ``skimage.io.push`` and ``skimage.io.pop``).
All that's left is to create an image viewer and add the plugin to that viewer.
.. code-block:: python
viewer = ImageViewer(image)
viewer += denoise_plugin
viewer.show()
.. image:: data/denoise_viewer_window.png
.. image:: data/denoise_plugin_window.png
.. _matplotlib: http://matplotlib.sourceforge.net/
+1 -40
View File
@@ -269,10 +269,6 @@ class ApiDocWriter(object):
ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n'
chap_title = uri_short
#ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title)
# + '\n\n')
# Set the chapter title to read 'module' for all modules except for the
# main packages
if '.' in uri:
@@ -281,21 +277,8 @@ class ApiDocWriter(object):
title = ':mod:`' + uri_short + '`'
ad += title + '\n' + self.rst_section_levels[1] * len(title)
if len(classes):
ad += '\nInheritance diagram for ``%s``:\n\n' % uri
ad += '.. inheritance-diagram:: %s \n' % uri
ad += ' :parts: 3\n'
ad += '\n.. automodule:: ' + uri + '\n'
ad += '\n.. currentmodule:: ' + uri + '\n'
# multi_class = len(classes) > 1
# multi_fx = len(functions) > 1
# if multi_class:
# ad += '\n' + 'Classes' + '\n' + \
# self.rst_section_levels[2] * 7 + '\n'
# elif len(classes) and multi_fx:
# ad += '\n' + 'Class' + '\n' + \
# self.rst_section_levels[2] * 5 + '\n'
for c in classes:
ad += '\n:class:`' + c + '`\n' \
+ self.rst_section_levels[2] * \
@@ -305,15 +288,8 @@ class ApiDocWriter(object):
ad += ' :members:\n' \
' :undoc-members:\n' \
' :show-inheritance:\n' \
' :inherited-members:\n' \
'\n' \
' .. automethod:: __init__\n'
# if multi_fx:
# ad += '\n' + 'Functions' + '\n' + \
# self.rst_section_levels[2] * 9 + '\n\n'
# elif len(functions) and multi_class:
# ad += '\n' + 'Function' + '\n' + \
# self.rst_section_levels[2] * 8 + '\n\n'
ad += '.. autosummary::\n\n'
for f in functions:
ad += ' ' + uri + '.' + f + '\n'
@@ -405,16 +381,9 @@ class ApiDocWriter(object):
modules.append(package_uri)
else:
dirnames.remove(dirname)
# Check filenames for modules
for filename in filenames:
module_name = filename[:-3]
module_uri = '.'.join((root_uri, module_name))
if (self._uri2path(module_uri) and
self._survives_exclude(module_uri, 'module')):
modules.append(module_uri)
return sorted(modules)
def write_modules_api(self, modules,outdir):
def write_modules_api(self, modules, outdir):
# write the list
written_modules = []
for m in modules:
@@ -451,14 +420,6 @@ class ApiDocWriter(object):
os.mkdir(outdir)
# compose list of modules
modules = self.discover_modules()
# group modules so we have one less level
module_depth = max([len(item.split('.')) for item in modules])
# modifying modules in-place, so make a copy
for item in modules[:]:
# Do not treat the .py files all as separate modules.
# Like this, only the objects exported in __all__ get picked up.
if not (len(item.split('.')) < module_depth):
modules.remove(item)
self.write_modules_api(modules,outdir)
def write_index(self, outdir, froot='gen', relative_to=None):
+6 -3
View File
@@ -23,14 +23,17 @@ releases = OrderedDict([
#('0.1', u'2009-10-07 13:52:19 +0200'),
#('0.2', u'2009-11-12 14:48:45 +0200'),
('0.3', u'2011-10-10 03:28:47 -0700'),
('0.4', u'2011-12-03 14:31:32 -0800')])
('0.4', u'2011-12-03 14:31:32 -0800'),
('0.5', u'2012-02-26 21:00:51 -0800'),
('0.6', u'2012-06-24 21:37:05 -0700')])
month_duration = 16
month_duration = 24
for r in releases:
releases[r] = dateutil.parser.parse(releases[r])
def fetch_PRs(user='scikits-image', repo='scikits-image', state='open'):
def fetch_PRs(user='scikit-image', repo='scikit-image', state='open'):
params = {'state': state,
'per_page': 100,
'page': 1}
+73 -26
View File
@@ -1,25 +1,32 @@
#! /usr/bin/env python
descr = """Image Processing SciKit
descr = """Image Processing SciKit
Image processing algorithms for SciPy, including IO, morphology, filtering,
warping, color manipulation, object detection, etc.
Please refer to the online documentation at
http://scikits-image.org/
http://scikit-image.org/
"""
DISTNAME = 'scikits-image'
DISTNAME = 'scikit-image'
DESCRIPTION = 'Image processing routines for SciPy'
LONG_DESCRIPTION = descr
MAINTAINER = 'Stefan van der Walt'
MAINTAINER_EMAIL = 'stefan@sun.ac.za'
URL = 'http://scikits-image.org'
URL = 'http://scikit-image.org'
LICENSE = 'Modified BSD'
DOWNLOAD_URL = 'http://github.com/scikits-image/scikits-image'
VERSION = '0.6'
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},
)
)
+19 -22
View File
@@ -1,6 +1,6 @@
"""Image Processing SciKit (Toolbox for SciPy)
``scikits-image`` (a.k.a. ``skimage``) is a collection of algorithms for image
``scikit-image`` (a.k.a. ``skimage``) is a collection of algorithms for image
processing and computer vision.
The main package of ``skimage`` only provides a few utilities for converting
@@ -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()
+5 -4
View File
@@ -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.
View File
+6
View File
@@ -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)
+54
View File
@@ -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])
+24
View File
@@ -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)
+297
View File
@@ -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
+38
View File
@@ -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())
)
+26
View File
@@ -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
+5
View File
@@ -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)
+44
View File
@@ -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
+189 -45
View File
@@ -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))
+45 -18
View File
@@ -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()
+13 -4
View File
@@ -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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

+22 -5
View File
@@ -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()
+2 -1
View File
@@ -1 +1,2 @@
from .draw import *
from ._draw import line, polygon, ellipse, circle
bresenham = line
+12 -13
View File
@@ -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``.
"""
-7
View File
@@ -1,7 +0,0 @@
"""
Methods to draw on arrays.
"""
from ._draw import line, polygon, ellipse, circle
bresenham = line

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