mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-19 11:27:45 +08:00
Merge branch 'master' of git://github.com/scikit-image/scikit-image
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
K.-Michael Aye <michaelaye@users.noreply.github.com> <kmichael.aye@gmail.com>
|
||||
Nelson Brown <nelson.brown@gmail.com> <nelson.a.brown@nasa.gov>
|
||||
Luis Pedro Coelho <luis@luispedro.org> <lpc@cmu.edu>
|
||||
Marianne Corvellec <marianne.corvellec@ens-lyon.org> <mcorvellec@april.org>
|
||||
Riaan van den Dool <riaanvddool@gmail.com> <rvddool@csir.co.za>
|
||||
Emmanuelle Gouillart <emmanuelle.gouillart@normalesup.org> <emma@aleph.(none)> <gouillar@epsilon.(none)> <emmanuelle.gouillart@nsup.org> <gouillar@aleph.(none)>
|
||||
Thouis (Ray) Jones <thouis@gmail.com> <thouis@seas.harvard.edu>
|
||||
Gregory R. Lee <gregory.lee@cchmc.org> <grlee77@gmail.com>
|
||||
Andreas Mueller <amueller@ais.uni-bonn.de> <andreas@wuerl.net>
|
||||
Juan Nunez-Iglesias <juan.n@unimelb.edu.au> <jni.soma@gmail.com> <jni@janelia.hhmi.org>
|
||||
Nicolas Pinto <pinto@alum.mit.edu> <nicolas.pinto@gmail.com>
|
||||
Johannes Schönberger <jsch@demuc.de> <ahojnnes@users.noreply.github.com> <hannesschoenberger@gmail.com> <jschoenberger@demuc.de>
|
||||
Tim Sheerman-Chase <tim2009@sheerman-chase.org.uk> <t.sheerman-chase@surrey.ac.uk>
|
||||
Matthew Trentacoste <trentaco@adobe.com> <web@matttrent.com>
|
||||
James Turner <jturner@gemini.edu> <jehturner@yahoo.co.uk>
|
||||
Stefan van der Walt <stefanv@berkeley.edu> <stefan@sun.ac.za> <github@mentat.za.net> <sjvdwalt@gmail.com>
|
||||
John Wiggins <jwiggins@enthought.com> <john.wiggins@xfel.eu>
|
||||
Tony S Yu <tyu@tony-yus-macbook.local> <tsyu80@gmail.com>
|
||||
@@ -225,6 +225,73 @@ Every time Travis is triggered, it also calls on `Coveralls
|
||||
<http://coveralls.io>`_ to inspect the current test overage.
|
||||
|
||||
|
||||
Building docs
|
||||
-------------
|
||||
|
||||
To build docs, run ``make`` from the ``docs`` directory. ``make help`` lists
|
||||
all targets.
|
||||
|
||||
Requirements
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Sphinx (>= 1.3) and Latex is needed to build doc.
|
||||
|
||||
**Sphinx:**
|
||||
|
||||
.. code:: sh
|
||||
|
||||
pip install sphinx
|
||||
|
||||
**Latex Ubuntu:**
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo apt-get install -qq texlive texlive-latex-extra dvipng
|
||||
|
||||
**Latex Mac:**
|
||||
|
||||
Install the full `MacTex <http://www.tug.org/mactex/>`__ installation or
|
||||
install the smaller
|
||||
`BasicTex <http://www.tug.org/mactex/morepackages.html>`__ and add *ucs*
|
||||
and *dvipng* packages:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo tlmgr install ucs dvipng
|
||||
|
||||
Fixing Warnings
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
- "citation not found: R###" There is probably an underscore after a
|
||||
reference in the first line of a docstring (e.g. [1]\_). Use this
|
||||
method to find the source file: $ cd doc/build; grep -rin R####
|
||||
|
||||
- "Duplicate citation R###, other instance in..."" There is probably a
|
||||
[2] without a [1] in one of the docstrings
|
||||
|
||||
- Make sure to use pre-sphinxification paths to images (not the
|
||||
\_images directory)
|
||||
|
||||
Auto-generating dev docs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This set of instructions was used to create
|
||||
scikit-image/tools/deploy-docs.sh
|
||||
|
||||
- Go to Github account settings -> personal access tokens
|
||||
- Create a new token with access rights ``public_repo`` and
|
||||
``user:email only``
|
||||
- Install the travis command line tool: ``gem install travis``. On OSX,
|
||||
you can get gem via ``brew install ruby``.
|
||||
- Take then token generated by Github and run
|
||||
``travis encrypt GH_TOKEN=<token>`` from inside a scikit-image repo
|
||||
- Paste the output into the secure: field of ``.travis.yml``.
|
||||
- The decrypted GH\_TOKEN env var will be available for travis scripts
|
||||
|
||||
https://help.github.com/articles/creating-an-access-token-for-command-line-use/
|
||||
http://docs.travis-ci.com/user/encryption-keys/
|
||||
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
|
||||
@@ -56,3 +56,10 @@ Testing requirements
|
||||
A Python Unit Testing Framework
|
||||
* `Coverage.py <http://nedbatchelder.com/code/coverage/>`__
|
||||
A tool that generates a unit test code coverage report
|
||||
|
||||
|
||||
Documentation requirements
|
||||
--------------------------
|
||||
|
||||
`sphinx >= 1.3 <http://sphinx-doc.org/>`_ is required to build the
|
||||
documentation.
|
||||
|
||||
@@ -12,10 +12,13 @@ Version 0.14
|
||||
add an alias LineModel = LineModelND. While the deprecated LineModel has for
|
||||
parameters `(dist, theta)`, LineModelND has the more general parameters
|
||||
`(origin, direction)`.
|
||||
* Remove deprecated old syntax support for ``skimage.transform.integrate``.
|
||||
|
||||
|
||||
Version 0.13
|
||||
------------
|
||||
* Require Python 2.7+, remove warning in `__init__.py` and 2.6 hack in
|
||||
`doc/release/contribs.py`.
|
||||
* Remove deprecated `None` defaults for `skimage.exposure.rescale_intensity`
|
||||
* Remove deprecated `skimage.filters.canny` import in `filters/__init__.py`
|
||||
file (canny is now in `skimage.feature.canny`).
|
||||
@@ -36,8 +39,6 @@ Version 0.12
|
||||
------------
|
||||
* Change `label` to mark background as 0, not -1, which is consistent with
|
||||
SciPy's labelling.
|
||||
* Remove `skimage.morphology.label` from `skimage.morphology.__init__`--it now
|
||||
lives in `skimage.measure.label`.
|
||||
* Remove deprecated `reverse_map` parameter of `skimage.transform.warp`
|
||||
* Change deprecated `enforce_connectivity=False` on skimage.segmentation.slic
|
||||
and set it to True as default
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# Building docs #
|
||||
To build docs, run `make` in this directory. `make help` lists all targets.
|
||||
|
||||
## Requirements ##
|
||||
Sphinx and Latex is needed to build doc.
|
||||
|
||||
**Sphinx:**
|
||||
```sh
|
||||
pip install sphinx
|
||||
```
|
||||
|
||||
**Latex Ubuntu:**
|
||||
```sh
|
||||
sudo apt-get install -qq texlive texlive-latex-extra dvipng
|
||||
```
|
||||
|
||||
**Latex Mac:**
|
||||
|
||||
Install the full [MacTex](http://www.tug.org/mactex/) installation or install the smaller [BasicTex](http://www.tug.org/mactex/morepackages.html) and add *ucs* and *dvipng* packages:
|
||||
```sh
|
||||
sudo tlmgr install ucs dvipng
|
||||
```
|
||||
|
||||
|
||||
## Fixing Warnings ##
|
||||
|
||||
- "citation not found: R###"
|
||||
There is probably an underscore after a reference
|
||||
in the first line of a docstring (e.g. [1]_).
|
||||
Use this method to find the source file:
|
||||
$ cd doc/build; grep -rin R####
|
||||
|
||||
- "Duplicate citation R###, other instance in...""
|
||||
There is probably a [2] without a [1] in one of
|
||||
the docstrings
|
||||
|
||||
- Make sure to use pre-sphinxification paths to images
|
||||
(not the _images directory)
|
||||
|
||||
|
||||
## Auto-generating dev docs ##
|
||||
|
||||
This set of instructions was used to create scikit-image/tools/deploy-docs.sh
|
||||
|
||||
- Go to Github account settings -> personal access tokens
|
||||
- Create a new token with access rights `public_repo` and `user:email only`
|
||||
- Install the travis command line tool: `gem install travis`. On OSX, you can get gem via `brew install ruby`.
|
||||
- Take then token generated by Github and run `travis encrypt GH_TOKEN=<token>` from inside a scikit-image repo
|
||||
- Paste the output into the secure: field of `.travis.yml`.
|
||||
- The decrypted GH_TOKEN env var will be available for travis scripts
|
||||
|
||||
https://help.github.com/articles/creating-an-access-token-for-command-line-use/
|
||||
http://docs.travis-ci.com/user/encryption-keys/
|
||||
@@ -0,0 +1,2 @@
|
||||
Manipulating exposure and color channels
|
||||
----------------------------------------
|
||||
@@ -99,5 +99,5 @@ ax_cdf.set_ylabel('Fraction of total intensity')
|
||||
ax_cdf.set_yticks(np.linspace(0, 1, 5))
|
||||
|
||||
# prevent overlap of y-axis labels
|
||||
fig.subplots_adjust(wspace=0.4)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
+3
-2
@@ -26,7 +26,8 @@ from skimage.color import rgb2hed
|
||||
ihc_rgb = data.immunohistochemistry()
|
||||
ihc_hed = rgb2hed(ihc_rgb)
|
||||
|
||||
fig, axes = plt.subplots(2, 2, figsize=(7, 6), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, axes = plt.subplots(2, 2, figsize=(7, 6), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax0, ax1, ax2, ax3 = axes.ravel()
|
||||
|
||||
ax0.imshow(ihc_rgb)
|
||||
@@ -44,7 +45,7 @@ ax3.set_title("DAB")
|
||||
for ax in axes.ravel():
|
||||
ax.axis('off')
|
||||
|
||||
fig.subplots_adjust(hspace=0.3)
|
||||
fig.tight_layout()
|
||||
|
||||
|
||||
"""
|
||||
+9
-7
@@ -74,12 +74,14 @@ img_eq = rank.equalize(img, selem=selem)
|
||||
# Display results
|
||||
fig = plt.figure(figsize=(8, 5))
|
||||
axes = np.zeros((2, 3), dtype=np.object)
|
||||
axes[0,0] = plt.subplot(2, 3, 1, adjustable='box-forced')
|
||||
axes[0,1] = plt.subplot(2, 3, 2, sharex=axes[0,0], sharey=axes[0,0], adjustable='box-forced')
|
||||
axes[0,2] = plt.subplot(2, 3, 3, sharex=axes[0,0], sharey=axes[0,0], adjustable='box-forced')
|
||||
axes[1,0] = plt.subplot(2, 3, 4)
|
||||
axes[1,1] = plt.subplot(2, 3, 5)
|
||||
axes[1,2] = plt.subplot(2, 3, 6)
|
||||
axes[0, 0] = plt.subplot(2, 3, 1, adjustable='box-forced')
|
||||
axes[0, 1] = plt.subplot(2, 3, 2, sharex=axes[0, 0], sharey=axes[0, 0],
|
||||
adjustable='box-forced')
|
||||
axes[0, 2] = plt.subplot(2, 3, 3, sharex=axes[0, 0], sharey=axes[0, 0],
|
||||
adjustable='box-forced')
|
||||
axes[1, 0] = plt.subplot(2, 3, 4)
|
||||
axes[1, 1] = plt.subplot(2, 3, 5)
|
||||
axes[1, 2] = plt.subplot(2, 3, 6)
|
||||
|
||||
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
|
||||
ax_img.set_title('Low contrast image')
|
||||
@@ -94,5 +96,5 @@ ax_cdf.set_ylabel('Fraction of total intensity')
|
||||
|
||||
|
||||
# prevent overlap of y-axis labels
|
||||
fig.subplots_adjust(wspace=0.4)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -55,10 +55,12 @@ logarithmic_corrected = exposure.adjust_log(img, 1)
|
||||
|
||||
# Display results
|
||||
fig = plt.figure(figsize=(8, 5))
|
||||
axes = np.zeros((2,3), dtype=np.object)
|
||||
axes = np.zeros((2, 3), dtype=np.object)
|
||||
axes[0, 0] = plt.subplot(2, 3, 1, adjustable='box-forced')
|
||||
axes[0, 1] = plt.subplot(2, 3, 2, sharex=axes[0, 0], sharey=axes[0, 0], adjustable='box-forced')
|
||||
axes[0, 2] = plt.subplot(2, 3, 3, sharex=axes[0, 0], sharey=axes[0, 0], adjustable='box-forced')
|
||||
axes[0, 1] = plt.subplot(2, 3, 2, sharex=axes[0, 0], sharey=axes[0, 0],
|
||||
adjustable='box-forced')
|
||||
axes[0, 2] = plt.subplot(2, 3, 3, sharex=axes[0, 0], sharey=axes[0, 0],
|
||||
adjustable='box-forced')
|
||||
axes[1, 0] = plt.subplot(2, 3, 4)
|
||||
axes[1, 1] = plt.subplot(2, 3, 5)
|
||||
axes[1, 2] = plt.subplot(2, 3, 6)
|
||||
@@ -80,5 +82,5 @@ ax_cdf.set_ylabel('Fraction of total intensity')
|
||||
ax_cdf.set_yticks(np.linspace(0, 1, 5))
|
||||
|
||||
# prevent overlap of y-axis labels
|
||||
fig.subplots_adjust(wspace=0.4)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -0,0 +1,2 @@
|
||||
Edges and lines
|
||||
---------------
|
||||
@@ -0,0 +1,99 @@
|
||||
"""
|
||||
====================
|
||||
Active Contour Model
|
||||
====================
|
||||
|
||||
The active contour model is a method to fit open or closed splines to lines or
|
||||
edges in an image. It works by minimising an energy that is in part defined by
|
||||
the image and part by the spline's shape: length and smoothness. The
|
||||
minimization is done implicitly in the shape energy and explicitly in the
|
||||
image energy.
|
||||
|
||||
In the following two examples the active contour model is used (1) to segment
|
||||
the face of a person from the rest of an image by fitting a closed curve
|
||||
to the edges of the face and (2) to find the darkest curve between two fixed
|
||||
points while obeying smoothness considerations. Typically it is a good idea to
|
||||
smooth images a bit before analyzing, as done in the following examples.
|
||||
|
||||
.. [1] *Snakes: Active contour models*. Kass, M.; Witkin, A.; Terzopoulos, D.
|
||||
International Journal of Computer Vision 1 (4): 321 (1988).
|
||||
|
||||
We initialize a circle around the astronaut's face and use the default boundary
|
||||
condition ``bc='periodic'`` to fit a closed curve. The default parameters
|
||||
``w_line=0, w_edge=1`` will make the curve search towards edges, such as the
|
||||
boundaries of the face.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from skimage.color import rgb2gray
|
||||
from skimage import data
|
||||
from skimage.filters import gaussian_filter
|
||||
from skimage.segmentation import active_contour
|
||||
|
||||
# Test scipy version, since active contour is only possible
|
||||
# with recent scipy version
|
||||
import scipy
|
||||
scipy_version = list(map(int, scipy.__version__.split('.')))
|
||||
new_scipy = scipy_version[0] > 0 or \
|
||||
(scipy_version[0] == 0 and scipy_version[1] >= 14)
|
||||
|
||||
img = data.astronaut()
|
||||
img = rgb2gray(img)
|
||||
|
||||
s = np.linspace(0, 2*np.pi, 400)
|
||||
x = 220 + 100*np.cos(s)
|
||||
y = 100 + 100*np.sin(s)
|
||||
init = np.array([x, y]).T
|
||||
|
||||
if not new_scipy:
|
||||
print('You are using an old version of scipy. '
|
||||
'Active contours is implemented for scipy versions '
|
||||
'0.14.0 and above.')
|
||||
|
||||
if new_scipy:
|
||||
snake = active_contour(gaussian_filter(img, 3),
|
||||
init, alpha=0.015, beta=10, gamma=0.001)
|
||||
|
||||
fig = plt.figure(figsize=(7, 7))
|
||||
ax = fig.add_subplot(111)
|
||||
plt.gray()
|
||||
ax.imshow(img)
|
||||
ax.plot(init[:, 0], init[:, 1], '--r', lw=3)
|
||||
ax.plot(snake[:, 0], snake[:, 1], '-b', lw=3)
|
||||
ax.set_xticks([]), ax.set_yticks([])
|
||||
ax.axis([0, img.shape[1], img.shape[0], 0])
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
|
||||
Here we initialize a straight line between two points, `(5, 136)` and
|
||||
`(424, 50)`, and require that the spline has its end points there by giving
|
||||
the boundary condition `bc='fixed'`. We furthermore make the algorithm search
|
||||
for dark lines by giving a negative `w_line` value.
|
||||
"""
|
||||
|
||||
img = data.text()
|
||||
|
||||
x = np.linspace(5, 424, 100)
|
||||
y = np.linspace(136, 50, 100)
|
||||
init = np.array([x, y]).T
|
||||
|
||||
if new_scipy:
|
||||
snake = active_contour(gaussian_filter(img, 1), init, bc='fixed',
|
||||
alpha=0.1, beta=1.0, w_line=-5, w_edge=0, gamma=0.1)
|
||||
|
||||
fig = plt.figure(figsize=(9, 5))
|
||||
ax = fig.add_subplot(111)
|
||||
plt.gray()
|
||||
ax.imshow(img)
|
||||
ax.plot(init[:, 0], init[:, 1], '--r', lw=3)
|
||||
ax.plot(snake[:, 0], snake[:, 1], '-b', lw=3)
|
||||
ax.set_xticks([]), ax.set_yticks([])
|
||||
ax.axis([0, img.shape[1], img.shape[0], 0])
|
||||
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
.. image:: PLOT2RST.current_figure
|
||||
"""
|
||||
@@ -35,7 +35,8 @@ edges1 = feature.canny(im)
|
||||
edges2 = feature.canny(im, sigma=3)
|
||||
|
||||
# display results
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 3), sharex=True, sharey=True)
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 3),
|
||||
sharex=True, sharey=True)
|
||||
|
||||
ax1.imshow(im, cmap=plt.cm.jet)
|
||||
ax1.axis('off')
|
||||
@@ -49,7 +50,6 @@ ax3.imshow(edges2, cmap=plt.cm.gray)
|
||||
ax3.axis('off')
|
||||
ax3.set_title('Canny filter, $\sigma=3$', fontsize=20)
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9,
|
||||
bottom=0.02, left=0.02, right=0.98)
|
||||
fig.tight_layout()
|
||||
|
||||
plt.show()
|
||||
+45
-44
@@ -1,4 +1,4 @@
|
||||
r"""
|
||||
"""
|
||||
=============================
|
||||
Straight line Hough transform
|
||||
=============================
|
||||
@@ -6,7 +6,7 @@ Straight line Hough transform
|
||||
The Hough transform in its simplest form is a `method to detect straight lines
|
||||
<http://en.wikipedia.org/wiki/Hough_transform>`__.
|
||||
|
||||
In the following example, we construct an image with a line intersection. We
|
||||
In the following example, we construct an image with a line intersection. We
|
||||
then use the Hough transform to explore a parameter space for straight lines
|
||||
that may run through the image.
|
||||
|
||||
@@ -53,9 +53,9 @@ References
|
||||
.. [2] Duda, R. O. and P. E. Hart, "Use of the Hough Transformation to
|
||||
Detect Lines and Curves in Pictures," Comm. ACM, Vol. 15,
|
||||
pp. 11-15 (January, 1972)
|
||||
|
||||
"""
|
||||
|
||||
from matplotlib import cm
|
||||
from skimage.transform import (hough_line, hough_line_peaks,
|
||||
probabilistic_hough_line)
|
||||
from skimage.feature import canny
|
||||
@@ -64,70 +64,71 @@ from skimage import data
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Construct test image
|
||||
|
||||
# Constructing test image.
|
||||
image = np.zeros((100, 100))
|
||||
|
||||
|
||||
# Classic straight-line Hough transform
|
||||
|
||||
idx = np.arange(25, 75)
|
||||
image[idx[::-1], idx] = 255
|
||||
image[idx, idx] = 255
|
||||
|
||||
# Classic straight-line Hough transform.
|
||||
h, theta, d = hough_line(image)
|
||||
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4))
|
||||
# Generating figure 1.
|
||||
fig, (ax0, ax1, ax2) = plt.subplots(1, 3, figsize=(12, 6))
|
||||
plt.tight_layout()
|
||||
|
||||
ax1.imshow(image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Input image')
|
||||
ax1.set_axis_off()
|
||||
ax0.imshow(image, cmap=cm.gray)
|
||||
ax0.set_title('Input image')
|
||||
ax0.set_axis_off()
|
||||
|
||||
ax2.imshow(np.log(1 + h),
|
||||
extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
|
||||
d[-1], d[0]],
|
||||
cmap=plt.cm.gray, aspect=1/1.5)
|
||||
ax2.set_title('Hough transform')
|
||||
ax2.set_xlabel('Angles (degrees)')
|
||||
ax2.set_ylabel('Distance (pixels)')
|
||||
ax2.axis('image')
|
||||
ax1.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
|
||||
d[-1], d[0]], cmap=cm.gray, aspect=1/1.5)
|
||||
ax1.set_title('Hough transform')
|
||||
ax1.set_xlabel('Angles (degrees)')
|
||||
ax1.set_ylabel('Distance (pixels)')
|
||||
ax1.axis('image')
|
||||
|
||||
ax3.imshow(image, cmap=plt.cm.gray)
|
||||
rows, cols = image.shape
|
||||
ax2.imshow(image, cmap=cm.gray)
|
||||
row1, col1 = image.shape
|
||||
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
|
||||
y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
|
||||
y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
|
||||
ax3.plot((0, cols), (y0, y1), '-r')
|
||||
ax3.axis((0, cols, rows, 0))
|
||||
ax3.set_title('Detected lines')
|
||||
ax3.set_axis_off()
|
||||
|
||||
# Line finding, using the Probabilistic Hough Transform
|
||||
y1 = (dist - col1 * np.cos(angle)) / np.sin(angle)
|
||||
ax2.plot((0, col1), (y0, y1), '-r')
|
||||
ax2.axis((0, col1, row1, 0))
|
||||
ax2.set_title('Detected lines')
|
||||
ax2.set_axis_off()
|
||||
|
||||
# Line finding using the Probabilistic Hough Transform.
|
||||
image = data.camera()
|
||||
edges = canny(image, 2, 1, 25)
|
||||
lines = probabilistic_hough_line(edges, threshold=10, line_length=5,
|
||||
line_gap=3)
|
||||
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True)
|
||||
# Generating figure 2.
|
||||
fig, (ax0, ax1, ax2) = plt.subplots(1, 3, figsize=(16, 6), sharex=True,
|
||||
sharey=True)
|
||||
plt.tight_layout()
|
||||
|
||||
ax1.imshow(image, cmap=plt.cm.gray)
|
||||
ax1.set_title('Input image')
|
||||
ax0.imshow(image, cmap=cm.gray)
|
||||
ax0.set_title('Input image')
|
||||
ax0.set_axis_off()
|
||||
ax0.set_adjustable('box-forced')
|
||||
|
||||
ax1.imshow(edges, cmap=cm.gray)
|
||||
ax1.set_title('Canny edges')
|
||||
ax1.set_axis_off()
|
||||
ax1.set_adjustable('box-forced')
|
||||
|
||||
ax2.imshow(edges, cmap=plt.cm.gray)
|
||||
ax2.set_title('Canny edges')
|
||||
ax2.imshow(edges * 0)
|
||||
for line in lines:
|
||||
p0, p1 = line
|
||||
ax2.plot((p0[0], p1[0]), (p0[1], p1[1]))
|
||||
|
||||
row2, col2 = image.shape
|
||||
ax2.axis((0, col2, row2, 0))
|
||||
|
||||
ax2.set_title('Probabilistic Hough')
|
||||
ax2.set_axis_off()
|
||||
ax2.set_adjustable('box-forced')
|
||||
|
||||
ax3.imshow(edges * 0)
|
||||
|
||||
for line in lines:
|
||||
p0, p1 = line
|
||||
ax3.plot((p0[0], p1[0]), (p0[1], p1[1]))
|
||||
|
||||
ax3.set_title('Probabilistic Hough')
|
||||
ax3.set_axis_off()
|
||||
ax3.set_adjustable('box-forced')
|
||||
plt.show()
|
||||
@@ -54,12 +54,13 @@ skel, distance = medial_axis(data, return_distance=True)
|
||||
# Distance to the background for pixels of the skeleton
|
||||
dist_on_skel = distance * skel
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax1.imshow(data, cmap=plt.cm.gray, interpolation='nearest')
|
||||
ax1.axis('off')
|
||||
ax2.imshow(dist_on_skel, cmap=plt.cm.spectral, interpolation='nearest')
|
||||
ax2.contour(data, [0.5], colors='w')
|
||||
ax2.axis('off')
|
||||
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -5,16 +5,16 @@ Shapes
|
||||
|
||||
This example shows how to draw several different shapes:
|
||||
|
||||
- line
|
||||
- Bezier curve
|
||||
- polygon
|
||||
- circle
|
||||
- ellipse
|
||||
- line
|
||||
- Bezier curve
|
||||
- polygon
|
||||
- circle
|
||||
- ellipse
|
||||
|
||||
Anti-aliased drawing for:
|
||||
|
||||
- line
|
||||
- circle
|
||||
- line
|
||||
- circle
|
||||
|
||||
"""
|
||||
import math
|
||||
@@ -47,7 +47,9 @@ image[circle2] = 0
|
||||
skeleton = skeletonize(image)
|
||||
|
||||
# display results
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4.5),
|
||||
sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
|
||||
ax1.imshow(image, cmap=plt.cm.gray)
|
||||
ax1.axis('off')
|
||||
@@ -57,7 +59,6 @@ ax2.imshow(skeleton, cmap=plt.cm.gray)
|
||||
ax2.axis('off')
|
||||
ax2.set_title('skeleton', fontsize=20)
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.98,
|
||||
bottom=0.02, left=0.02, right=0.98)
|
||||
fig.tight_layout()
|
||||
|
||||
plt.show()
|
||||
@@ -0,0 +1,2 @@
|
||||
Detection of features and objects
|
||||
---------------------------------
|
||||
@@ -34,19 +34,20 @@ independent of the size of blobs as internally the implementation uses
|
||||
box filters instead of convolutions. Bright on dark as well as dark on
|
||||
bright blobs are detected. The downside is that small blobs (<3px) are not
|
||||
detected accurately. See :py:meth:`skimage.feature.blob_doh` for usage.
|
||||
|
||||
"""
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
from skimage import data
|
||||
from skimage.feature import blob_dog, blob_log, blob_doh
|
||||
from math import sqrt
|
||||
from skimage.color import rgb2gray
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
image = data.hubble_deep_field()[0:500, 0:500]
|
||||
image_gray = rgb2gray(image)
|
||||
|
||||
blobs_log = blob_log(image_gray, max_sigma=30, num_sigma=10, threshold=.1)
|
||||
|
||||
# Compute radii in the 3rd column.
|
||||
blobs_log[:, 2] = blobs_log[:, 2] * sqrt(2)
|
||||
|
||||
@@ -61,14 +62,17 @@ titles = ['Laplacian of Gaussian', 'Difference of Gaussian',
|
||||
'Determinant of Hessian']
|
||||
sequence = zip(blobs_list, colors, titles)
|
||||
|
||||
fig, axes = plt.subplots(1, 3, figsize=(14, 4), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
plt.tight_layout()
|
||||
|
||||
fig,axes = plt.subplots(1, 3, sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
axes = axes.ravel()
|
||||
for blobs, color, title in sequence:
|
||||
ax = axes[0]
|
||||
axes = axes[1:]
|
||||
ax.set_title(title)
|
||||
ax.imshow(image, interpolation='nearest')
|
||||
ax.set_axis_off()
|
||||
for blob in blobs:
|
||||
y, x, r = blob
|
||||
c = plt.Circle((x, y), r, color=color, linewidth=2, fill=False)
|
||||
+1
-1
@@ -87,5 +87,5 @@ ax3.set_title("K-means filterbank (codebook)\non LGN-like DoG image")
|
||||
for ax in axes.ravel():
|
||||
ax.axis('off')
|
||||
|
||||
fig.subplots_adjust(hspace=0.3)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -15,11 +15,11 @@ Algorithm overview
|
||||
|
||||
Compute a Histogram of Oriented Gradients (HOG) by
|
||||
|
||||
1. (optional) global image normalisation
|
||||
2. computing the gradient image in x and y
|
||||
3. computing gradient histograms
|
||||
4. normalising across blocks
|
||||
5. flattening into a feature vector
|
||||
1. (optional) global image normalisation
|
||||
2. computing the gradient image in x and y
|
||||
3. computing gradient histograms
|
||||
4. normalising across blocks
|
||||
5. flattening into a feature vector
|
||||
|
||||
The first stage applies an optional global image normalisation
|
||||
equalisation that is designed to reduce the influence of illumination
|
||||
@@ -0,0 +1,2 @@
|
||||
Filtering and restoration
|
||||
-------------------------
|
||||
@@ -38,7 +38,8 @@ astro = astro[220:300, 220:320]
|
||||
noisy = astro + 0.6 * astro.std() * np.random.random(astro.shape)
|
||||
noisy = np.clip(noisy, 0, 1)
|
||||
|
||||
fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(8, 5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, ax = plt.subplots(nrows=2, ncols=3, figsize=(8, 5), sharex=True,
|
||||
sharey=True, subplot_kw={'adjustable': 'box-forced'})
|
||||
|
||||
plt.gray()
|
||||
|
||||
@@ -62,7 +63,6 @@ ax[1, 2].imshow(astro)
|
||||
ax[1, 2].axis('off')
|
||||
ax[1, 2].set_title('original')
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.2,
|
||||
top=0.9, bottom=0.05, left=0, right=1)
|
||||
fig.tight_layout()
|
||||
|
||||
plt.show()
|
||||
@@ -26,7 +26,8 @@ noisy = np.clip(noisy, 0, 1)
|
||||
|
||||
denoise = denoise_nl_means(noisy, 7, 9, 0.08)
|
||||
|
||||
fig, ax = plt.subplots(ncols=2, figsize=(8, 4), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, ax = plt.subplots(ncols=2, figsize=(8, 4), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
|
||||
ax[0].imshow(noisy)
|
||||
ax[0].axis('off')
|
||||
@@ -35,7 +36,6 @@ ax[1].imshow(denoise)
|
||||
ax[1].axis('off')
|
||||
ax[1].set_title('non-local means')
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.2,
|
||||
top=0.9, bottom=0.05, left=0, right=1)
|
||||
fig.tight_layout()
|
||||
|
||||
plt.show()
|
||||
@@ -5,12 +5,12 @@ Mean filters
|
||||
|
||||
This example compares the following mean filters of the rank filter package:
|
||||
|
||||
* **local mean**: all pixels belonging to the structuring element to compute
|
||||
average gray level.
|
||||
* **percentile mean**: only use values between percentiles p0 and p1
|
||||
(here 10% and 90%).
|
||||
* **bilateral mean**: only use pixels of the structuring element having a gray
|
||||
level situated inside g-s0 and g+s1 (here g-500 and g+500)
|
||||
* **local mean**: all pixels belonging to the structuring element to compute
|
||||
average gray level.
|
||||
* **percentile mean**: only use values between percentiles p0 and p1
|
||||
(here 10% and 90%).
|
||||
* **bilateral mean**: only use pixels of the structuring element having a gray
|
||||
level situated inside g-s0 and g+s1 (here g-500 and g+500)
|
||||
|
||||
Percentile and usual mean give here similar results, these filters smooth the
|
||||
complete image (background and details). Bilateral mean exhibits a high
|
||||
@@ -34,7 +34,8 @@ bilateral_result = rank.mean_bilateral(image, selem=selem, s0=500, s1=500)
|
||||
normal_result = rank.mean(image, selem=selem)
|
||||
|
||||
|
||||
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 10), sharex=True, sharey=True)
|
||||
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 10),
|
||||
sharex=True, sharey=True)
|
||||
ax = axes.ravel()
|
||||
|
||||
titles = ['Original', 'Percentile mean', 'Bilateral mean', 'Local mean']
|
||||
@@ -42,7 +42,9 @@ astro += 0.1 * astro.std() * np.random.standard_normal(astro.shape)
|
||||
|
||||
deconvolved, _ = restoration.unsupervised_wiener(astro, psf)
|
||||
|
||||
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 5),
|
||||
sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
|
||||
plt.gray()
|
||||
|
||||
@@ -54,7 +56,6 @@ ax[1].imshow(deconvolved)
|
||||
ax[1].axis('off')
|
||||
ax[1].set_title('Self tuned restoration')
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.2,
|
||||
top=0.9, bottom=0.05, left=0, right=1)
|
||||
fig.tight_layout()
|
||||
|
||||
plt.show()
|
||||
@@ -0,0 +1,2 @@
|
||||
Operations on NumPy arrays
|
||||
--------------------------
|
||||
+4
-3
@@ -49,8 +49,9 @@ ax0, ax1, ax2, ax3 = axes.ravel()
|
||||
|
||||
ax0.set_title("Original rescaled with\n spline interpolation (order=3)")
|
||||
l_resized = ndi.zoom(l, 2, order=3)
|
||||
#ax0.imshow(l_resized, cmap=cm.Greys_r)
|
||||
ax0.imshow(l_resized, extent=(0, 128, 128, 0), interpolation='nearest', cmap=cm.Greys_r)
|
||||
|
||||
ax0.imshow(l_resized, extent=(0, 128, 128, 0), interpolation='nearest',
|
||||
cmap=cm.Greys_r)
|
||||
ax0.set_axis_off()
|
||||
|
||||
ax1.set_title("Block view with\n local mean pooling")
|
||||
@@ -65,5 +66,5 @@ ax3.set_title("Block view with\n local median pooling")
|
||||
ax3.imshow(median_view, interpolation='nearest', cmap=cm.Greys_r)
|
||||
ax3.set_axis_off()
|
||||
|
||||
fig.subplots_adjust(hspace=0.4, wspace=0.4)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -0,0 +1,2 @@
|
||||
Segmentation of objects
|
||||
-----------------------
|
||||
+3
-2
@@ -40,7 +40,8 @@ seg2 = slic(coins, n_segments=117, max_iter=160, sigma=1, compactness=0.75,
|
||||
segj = join_segmentations(seg1, seg2)
|
||||
|
||||
# show the segmentations
|
||||
fig, axes = plt.subplots(ncols=4, figsize=(9, 2.5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, axes = plt.subplots(ncols=4, figsize=(9, 2.5), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
axes[0].imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
|
||||
axes[0].set_title('Image')
|
||||
|
||||
@@ -58,5 +59,5 @@ axes[3].set_title('Join')
|
||||
|
||||
for ax in axes:
|
||||
ax.axis('off')
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -10,23 +10,21 @@ structuring element.
|
||||
|
||||
The example compares the local threshold with the global threshold.
|
||||
|
||||
.. note: local is much slower than global thresholding
|
||||
.. Note: local is much slower than global thresholding
|
||||
|
||||
.. [1] http://en.wikipedia.org/wiki/Otsu's_method
|
||||
|
||||
"""
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import data
|
||||
from skimage.morphology import disk
|
||||
from skimage.filters import threshold_otsu, rank
|
||||
from skimage.util import img_as_ubyte
|
||||
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
|
||||
img = img_as_ubyte(data.page())
|
||||
|
||||
radius = 15
|
||||
@@ -36,26 +34,26 @@ local_otsu = rank.otsu(img, selem)
|
||||
threshold_global_otsu = threshold_otsu(img)
|
||||
global_otsu = img >= threshold_global_otsu
|
||||
|
||||
fig, ax = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax0, ax1, ax2, ax3 = ax.ravel()
|
||||
|
||||
fig, ax = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
fig.colorbar(ax0.imshow(img, cmap=plt.cm.gray),
|
||||
ax=ax0, orientation='horizontal')
|
||||
ax0.set_title('Original')
|
||||
ax0.axis('off')
|
||||
|
||||
fig.colorbar(ax1.imshow(img, cmap=plt.cm.gray),
|
||||
fig.colorbar(ax1.imshow(local_otsu, cmap=plt.cm.gray),
|
||||
ax=ax1, orientation='horizontal')
|
||||
ax1.set_title('Original')
|
||||
ax1.set_title('Local Otsu (radius=%d)' % radius)
|
||||
ax1.axis('off')
|
||||
|
||||
fig.colorbar(ax2.imshow(local_otsu, cmap=plt.cm.gray),
|
||||
ax=ax2, orientation='horizontal')
|
||||
ax2.set_title('Local Otsu (radius=%d)' % radius)
|
||||
ax2.imshow(img >= local_otsu, cmap=plt.cm.gray)
|
||||
ax2.set_title('Original >= Local Otsu' % threshold_global_otsu)
|
||||
ax2.axis('off')
|
||||
|
||||
ax3.imshow(img >= local_otsu, cmap=plt.cm.gray)
|
||||
ax3.set_title('Original >= Local Otsu' % threshold_global_otsu)
|
||||
ax3.imshow(global_otsu, cmap=plt.cm.gray)
|
||||
ax3.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu)
|
||||
ax3.axis('off')
|
||||
|
||||
ax4.imshow(global_otsu, cmap=plt.cm.gray)
|
||||
ax4.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu)
|
||||
ax4.axis('off')
|
||||
|
||||
plt.show()
|
||||
+3
-3
@@ -25,7 +25,8 @@ image_max = ndi.maximum_filter(im, size=20, mode='constant')
|
||||
coordinates = peak_local_max(im, min_distance=20)
|
||||
|
||||
# display results
|
||||
fig, ax = plt.subplots(1, 3, figsize=(8, 3), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, ax = plt.subplots(1, 3, figsize=(8, 3), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax1, ax2, ax3 = ax.ravel()
|
||||
ax1.imshow(im, cmap=plt.cm.gray)
|
||||
ax1.axis('off')
|
||||
@@ -41,7 +42,6 @@ ax3.plot(coordinates[:, 1], coordinates[:, 0], 'r.')
|
||||
ax3.axis('off')
|
||||
ax3.set_title('Peak local max')
|
||||
|
||||
fig.subplots_adjust(wspace=0.02, hspace=0.02, top=0.9,
|
||||
bottom=0.02, left=0.02, right=0.98)
|
||||
fig.tight_layout()
|
||||
|
||||
plt.show()
|
||||
+3
-3
@@ -38,7 +38,8 @@ markers[data > 1.3] = 2
|
||||
labels = random_walker(data, markers, beta=10, mode='bf')
|
||||
|
||||
# Plot results
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 3.2), sharex=True, sharey=True)
|
||||
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 3.2),
|
||||
sharex=True, sharey=True)
|
||||
ax1.imshow(data, cmap='gray', interpolation='nearest')
|
||||
ax1.axis('off')
|
||||
ax1.set_adjustable('box-forced')
|
||||
@@ -52,6 +53,5 @@ ax3.axis('off')
|
||||
ax3.set_adjustable('box-forced')
|
||||
ax3.set_title('Segmentation')
|
||||
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0,
|
||||
right=1)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
+3
-2
@@ -79,9 +79,10 @@ 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, sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, ax = plt.subplots(1, 3, sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
fig.set_size_inches(8, 3, forward=True)
|
||||
fig.subplots_adjust(0.05, 0.05, 0.95, 0.95, 0.05, 0.05)
|
||||
fig.tight_layout()
|
||||
|
||||
ax[0].imshow(mark_boundaries(img, segments_fz))
|
||||
ax[0].set_title("Felzenszwalbs's method")
|
||||
@@ -48,7 +48,8 @@ local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)),
|
||||
markers = ndi.label(local_maxi)[0]
|
||||
labels = watershed(-distance, markers, mask=image)
|
||||
|
||||
fig, axes = plt.subplots(ncols=3, figsize=(8, 2.7), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, axes = plt.subplots(ncols=3, figsize=(8, 2.7), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax0, ax1, ax2 = axes
|
||||
|
||||
ax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
|
||||
@@ -61,6 +62,5 @@ ax2.set_title('Separated objects')
|
||||
for ax in axes:
|
||||
ax.axis('off')
|
||||
|
||||
fig.subplots_adjust(hspace=0.01, wspace=0.01, top=0.9, bottom=0, left=0,
|
||||
right=1)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
@@ -0,0 +1,2 @@
|
||||
Geometrical transformations and registration
|
||||
--------------------------------------------
|
||||
@@ -7,10 +7,10 @@ This example illustrates the different edge modes available during
|
||||
interpolation in routines such as `skimage.transform.rescale` and
|
||||
`skimage.transform.resize`.
|
||||
"""
|
||||
from skimage._shared.interpolation import extend_image
|
||||
import skimage.data
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage._shared.interpolation import extend_image
|
||||
|
||||
img = np.zeros((16, 16))
|
||||
img[:8, :8] += 1
|
||||
@@ -20,18 +20,19 @@ img[:1, :1] += 2
|
||||
img[8, 8] = 4
|
||||
|
||||
modes = ['constant', 'edge', 'wrap', 'reflect', 'symmetric']
|
||||
fig, axes = plt.subplots(1, 5, figsize=(15, 5))
|
||||
fig, axes = plt.subplots(2, 3)
|
||||
axes = axes.flatten()
|
||||
|
||||
for n, mode in enumerate(modes):
|
||||
img_extended = extend_image(img, pad=img.shape[0], mode=mode)
|
||||
axes[n].imshow(img_extended, cmap=plt.cm.gray, interpolation='nearest')
|
||||
axes[n].plot([15.5, 15.5], [15.5, 31.5], 'y--', linewidth=0.5)
|
||||
axes[n].plot([31.5, 31.5], [15.5, 31.5], 'y--', linewidth=0.5)
|
||||
axes[n].plot([15.5, 31.5], [15.5, 15.5], 'y--', linewidth=0.5)
|
||||
axes[n].plot([15.5, 31.5], [31.5, 31.5], 'y--', linewidth=0.5)
|
||||
axes[n].set_axis_off()
|
||||
axes[n].set_aspect('equal')
|
||||
axes[n].plot([15.5, 15.5, 31.5, 31.5, 15.5],
|
||||
[15.5, 31.5, 31.5, 15.5, 15.5], 'y--', linewidth=0.5)
|
||||
axes[n].set_title(mode)
|
||||
|
||||
for n in range(len(axes)):
|
||||
axes[n].set_axis_off()
|
||||
axes[n].set_aspect('equal')
|
||||
|
||||
plt.tight_layout()
|
||||
|
||||
plt.show()
|
||||
+9
-6
@@ -31,9 +31,9 @@ Technique (SART).
|
||||
|
||||
For further information on tomographic reconstruction, see
|
||||
|
||||
- AC Kak, M Slaney, "Principles of Computerized Tomographic Imaging",
|
||||
http://www.slaney.org/pct/pct-toc.html
|
||||
- http://en.wikipedia.org/wiki/Radon_transform
|
||||
- AC Kak, M Slaney, "Principles of Computerized Tomographic Imaging",
|
||||
http://www.slaney.org/pct/pct-toc.html
|
||||
- http://en.wikipedia.org/wiki/Radon_transform
|
||||
|
||||
The forward transform
|
||||
=====================
|
||||
@@ -73,7 +73,7 @@ ax2.set_ylabel("Projection position (pixels)")
|
||||
ax2.imshow(sinogram, cmap=plt.cm.Greys_r,
|
||||
extent=(0, 180, 0, sinogram.shape[0]), aspect='auto')
|
||||
|
||||
fig.subplots_adjust(hspace=0.4, wspace=0.5)
|
||||
fig.tight_layout()
|
||||
plt.show()
|
||||
|
||||
"""
|
||||
@@ -101,7 +101,9 @@ error = reconstruction_fbp - image
|
||||
print('FBP rms reconstruction error: %.3g' % np.sqrt(np.mean(error**2)))
|
||||
|
||||
imkwargs = dict(vmin=-0.2, vmax=0.2)
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4.5),
|
||||
sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax1.set_title("Reconstruction\nFiltered back projection")
|
||||
ax1.imshow(reconstruction_fbp, cmap=plt.cm.Greys_r)
|
||||
ax2.set_title("Reconstruction error\nFiltered back projection")
|
||||
@@ -152,7 +154,8 @@ error = reconstruction_sart - image
|
||||
print('SART (1 iteration) rms reconstruction error: %.3g'
|
||||
% np.sqrt(np.mean(error**2)))
|
||||
|
||||
fig, ax = plt.subplots(2, 2, figsize=(8, 8.5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, ax = plt.subplots(2, 2, figsize=(8, 8.5), sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
ax1, ax2, ax3, ax4 = ax.ravel()
|
||||
ax1.set_title("Reconstruction\nSART")
|
||||
ax1.imshow(reconstruction_sart, cmap=plt.cm.Greys_r)
|
||||
@@ -19,19 +19,14 @@ but with very different mean structural similarity indices.
|
||||
assessment: From error visibility to structural similarity," IEEE
|
||||
Transactions on Image Processing, vol. 13, no. 4, pp. 600-612,
|
||||
Apr. 2004.
|
||||
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from skimage import data, img_as_float
|
||||
from skimage.measure import structural_similarity as ssim
|
||||
|
||||
|
||||
matplotlib.rcParams['font.size'] = 9
|
||||
|
||||
|
||||
img = img_as_float(data.camera())
|
||||
rows, cols = img.shape
|
||||
|
||||
@@ -45,7 +40,10 @@ def mse(x, y):
|
||||
img_noise = img + noise
|
||||
img_const = img + abs(noise)
|
||||
|
||||
fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, figsize=(8, 4), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
|
||||
fig, (ax0, ax1, ax2) = plt.subplots(nrows=1, ncols=3, figsize=(16, 6),
|
||||
sharex=True, sharey=True,
|
||||
subplot_kw={'adjustable': 'box-forced'})
|
||||
plt.tight_layout()
|
||||
|
||||
mse_none = mse(img, img)
|
||||
ssim_none = ssim(img, img, dynamic_range=img.max() - img.min())
|
||||
@@ -63,13 +61,16 @@ label = 'MSE: %2.f, SSIM: %.2f'
|
||||
ax0.imshow(img, cmap=plt.cm.gray, vmin=0, vmax=1)
|
||||
ax0.set_xlabel(label % (mse_none, ssim_none))
|
||||
ax0.set_title('Original image')
|
||||
ax0.axes.get_yaxis().set_visible(False)
|
||||
|
||||
ax1.imshow(img_noise, cmap=plt.cm.gray, vmin=0, vmax=1)
|
||||
ax1.set_xlabel(label % (mse_noise, ssim_noise))
|
||||
ax1.set_title('Image with noise')
|
||||
ax1.axes.get_yaxis().set_visible(False)
|
||||
|
||||
ax2.imshow(img_const, cmap=plt.cm.gray, vmin=0, vmax=1)
|
||||
ax2.set_xlabel(label % (mse_const, ssim_const))
|
||||
ax2.set_title('Image plus constant')
|
||||
ax2.axes.get_yaxis().set_visible(False)
|
||||
|
||||
plt.show()
|
||||
+31
-27
@@ -10,41 +10,45 @@ if len(sys.argv) != 2:
|
||||
|
||||
tag = sys.argv[1]
|
||||
|
||||
def call(cmd):
|
||||
return subprocess.check_output(shlex.split(cmd), universal_newlines=True).split('\n')
|
||||
|
||||
tag_date = call("git show --format='%%ci' %s" % tag)[0]
|
||||
print("Release %s was on %s\n" % (tag, tag_date))
|
||||
if not sys.version_info[:2] == (2, 6):
|
||||
|
||||
merges = call("git log --since='%s' --merges --format='>>>%%B' --reverse" % tag_date)
|
||||
merges = [m for m in merges if m.strip()]
|
||||
merges = '\n'.join(merges).split('>>>')
|
||||
merges = [m.split('\n')[:2] for m in merges]
|
||||
merges = [m for m in merges if len(m) == 2 and m[1].strip()]
|
||||
def call(cmd):
|
||||
return subprocess.check_output(shlex.split(cmd), universal_newlines=True).split('\n')
|
||||
|
||||
num_commits = call("git rev-list %s..HEAD --count" % tag)[0]
|
||||
print("A total of %s changes have been committed.\n" % num_commits)
|
||||
tag_date = call("git show --format='%%ci' %s" % tag)[0]
|
||||
print("Release %s was on %s\n" % (tag, tag_date))
|
||||
|
||||
print("It contained the following %d merges:\n" % len(merges))
|
||||
for (merge, message) in merges:
|
||||
if merge.startswith('Merge pull request #'):
|
||||
PR = ' (%s)' % merge.split()[3]
|
||||
else:
|
||||
PR = ''
|
||||
merges = call("git log --since='%s' --merges --format='>>>%%B' --reverse" % tag_date)
|
||||
merges = [m for m in merges if m.strip()]
|
||||
merges = '\n'.join(merges).split('>>>')
|
||||
merges = [m.split('\n')[:2] for m in merges]
|
||||
merges = [m for m in merges if len(m) == 2 and m[1].strip()]
|
||||
|
||||
print('- ' + message + PR)
|
||||
num_commits = call("git rev-list %s..HEAD --count" % tag)[0]
|
||||
print("A total of %s changes have been committed.\n" % num_commits)
|
||||
|
||||
print("It contained the following %d merges:\n" % len(merges))
|
||||
for (merge, message) in merges:
|
||||
if merge.startswith('Merge pull request #'):
|
||||
PR = ' (%s)' % merge.split()[3]
|
||||
else:
|
||||
PR = ''
|
||||
|
||||
print('- ' + message + PR)
|
||||
|
||||
|
||||
print("\nMade by the following committers [alphabetical by last name]:\n")
|
||||
print("\nMade by the following committers [alphabetical by last name]:\n")
|
||||
|
||||
authors = call("git log --since='%s' --format=%%aN" % tag_date)
|
||||
authors = [a.strip() for a in authors if a.strip()]
|
||||
authors = call("git log --since='%s' --format=%%aN" % tag_date)
|
||||
authors = [a.strip() for a in authors if a.strip()]
|
||||
|
||||
def key(author):
|
||||
author = [v for v in author.split() if v[0] in string.ascii_letters]
|
||||
return author[-1]
|
||||
def key(author):
|
||||
author = [v for v in author.split() if v[0] in string.ascii_letters]
|
||||
if len(author) > 0:
|
||||
return author[-1]
|
||||
|
||||
authors = sorted(set(authors), key=key)
|
||||
authors = sorted(set(authors), key=key)
|
||||
|
||||
for a in authors:
|
||||
print('- ' + a)
|
||||
for a in authors:
|
||||
print('- ' + a)
|
||||
|
||||
@@ -81,9 +81,9 @@ disk: ::
|
||||
... (nrows / 2)**2)
|
||||
>>> camera[outer_disk_mask] = 0
|
||||
|
||||
.. image:: ../auto_examples/images/plot_camera_numpy_1.png
|
||||
.. image:: ../auto_examples/numpy_operations/images/plot_camera_numpy_1.png
|
||||
:width: 45%
|
||||
:target: ../auto_examples/plot_camera_numpy.html
|
||||
:target: ../auto_examples/numpy_operations/plot_camera_numpy.html
|
||||
|
||||
Boolean arithmetic can be used to define more complex masks: ::
|
||||
|
||||
|
||||
@@ -78,8 +78,8 @@ using an array of labels to encode the regions to be represented with the
|
||||
same color.
|
||||
|
||||
|
||||
.. image: ../auto_examples/images/plot_join_segmentations_1.png
|
||||
:target: ../auto_examples/plot_join_segmentations.html
|
||||
.. image: ../auto_examples/segmentation/images/plot_join_segmentations_1.png
|
||||
:target: ../auto_examples/segmentation/plot_join_segmentations.html
|
||||
:align: center
|
||||
:width: 80%
|
||||
|
||||
@@ -87,9 +87,9 @@ same color.
|
||||
|
||||
.. topic:: Examples:
|
||||
|
||||
* :ref:`example_plot_tinting_grayscale_images.py`
|
||||
* :ref:`example_plot_join_segmentations.py`
|
||||
* :ref:`example_plot_rag_mean_color.py`
|
||||
* :ref:`example_color_exposure_plot_tinting_grayscale_images.py`
|
||||
* :ref:`example_segmentation_plot_join_segmentations.py`
|
||||
* :ref:`example_segmentation_plot_rag_mean_color.py`
|
||||
|
||||
|
||||
Contrast and exposure
|
||||
@@ -122,7 +122,7 @@ the image. The histogram of pixel values is computed with
|
||||
|
||||
:func:`histogram` returns the number of pixels for each value bin, and
|
||||
the centers of the bins. The behavior of :func:`histogram` is therefore
|
||||
slightly different from the one of :func:`np.histogram`, which returns
|
||||
slightly different from the one of :func:`numpy.histogram`, which returns
|
||||
the boundaries of the bins.
|
||||
|
||||
The simplest contrast enhancement :func:`rescale_intensity` consists in
|
||||
@@ -157,16 +157,16 @@ details are enhanced in large regions with poor contrast. As a further
|
||||
refinement, histogram equalization can be performed in subregions of the
|
||||
image with :func:`equalize_adapthist`, in order to correct for exposure
|
||||
gradients across the image. See the example
|
||||
:ref:`example_plot_equalize.py`.
|
||||
:ref:`example_color_exposure_plot_equalize.py`.
|
||||
|
||||
.. image:: ../auto_examples/images/plot_equalize_1.png
|
||||
:target: ../auto_examples/plot_equalize.html
|
||||
.. image:: ../auto_examples/color_exposure/images/plot_equalize_1.png
|
||||
:target: ../auto_examples/color_exposure/plot_equalize.html
|
||||
:align: center
|
||||
:width: 90%
|
||||
|
||||
|
||||
.. topic:: Examples:
|
||||
|
||||
* :ref:`example_plot_equalize.py`
|
||||
* :ref:`example_color_exposure_plot_equalize.py`
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ the coins cannot be done directly from the histogram of grey values,
|
||||
because the background shares enough grey levels with the coins that a
|
||||
thresholding segmentation is not sufficient.
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_1.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_1.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
::
|
||||
@@ -26,8 +26,8 @@ Simply thresholding the image leads either to missing significant parts
|
||||
of the coins, or to merging parts of the background with the
|
||||
coins. This is due to the inhomogeneous lighting of the image.
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_2.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_2.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
A first idea is to take advantage of the local contrast, that is, to
|
||||
@@ -53,8 +53,8 @@ boundary of the coins, or inside the coins.
|
||||
>>> from scipy import ndimage as ndi
|
||||
>>> fill_coins = ndi.binary_fill_holes(edges)
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_3.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_3.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
Now that we have contours that delineate the outer boundary of the coins,
|
||||
@@ -62,8 +62,8 @@ we fill the inner part of the coins using the
|
||||
``ndi.binary_fill_holes`` function, which uses mathematical morphology
|
||||
to fill the holes.
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_4.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_4.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
Most coins are well segmented out of the background. Small objects from
|
||||
@@ -83,8 +83,8 @@ 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:: ../auto_examples/applications/images/plot_coins_segmentation_5.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_5.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
Therefore, this segmentation method is not very robust: if we miss a
|
||||
@@ -128,8 +128,8 @@ separate the coins from the background.
|
||||
|
||||
and here is the corresponding 2-D plot:
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_6.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_6.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
The next step is to find markers of the background and the coins based on the
|
||||
@@ -139,8 +139,8 @@ extreme parts of the histogram of grey values::
|
||||
>>> markers[coins < 30] = 1
|
||||
>>> markers[coins > 150] = 2
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_7.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_7.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
Let us now compute the watershed transform::
|
||||
@@ -148,8 +148,8 @@ Let us now compute the watershed transform::
|
||||
>>> from skimage.morphology import watershed
|
||||
>>> segmentation = watershed(elevation_map, markers)
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_8.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_8.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
With this method, the result is satisfying for all coins. Even if the
|
||||
@@ -165,7 +165,7 @@ We can now label all the coins one by one using ``ndi.label``::
|
||||
|
||||
>>> labeled_coins, _ = ndi.label(segmentation)
|
||||
|
||||
.. image:: ../auto_examples/applications/images/plot_coins_segmentation_9.png
|
||||
:target: ../auto_examples/applications/plot_coins_segmentation.html
|
||||
.. image:: ../auto_examples/xx_applications/images/plot_coins_segmentation_9.png
|
||||
:target: ../auto_examples/xx_applications/plot_coins_segmentation.html
|
||||
:align: center
|
||||
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@ numpy>=1.6.1
|
||||
scipy>=0.9.0
|
||||
six>=1.4
|
||||
networkx>=1.8
|
||||
pillow>=1.7.8
|
||||
pillow>=2.1.0
|
||||
dask[array]>=0.5.0
|
||||
|
||||
@@ -156,4 +156,9 @@ else:
|
||||
_raise_build_error(e)
|
||||
from .util.dtype import *
|
||||
|
||||
|
||||
if sys.version.startswith('2.6'):
|
||||
warnings.warn("Python 2.6 is deprecated and will not be supported in scikit-image 0.13+")
|
||||
|
||||
|
||||
del warnings, functools, osp, imp, sys
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 116 B |
Binary file not shown.
@@ -5,19 +5,19 @@ from ._draw import _coords_inside_image
|
||||
|
||||
def _ellipse_in_shape(shape, center, radiuses):
|
||||
"""Generate coordinates of points within ellipse bounded by shape."""
|
||||
y, x = np.ogrid[0:float(shape[0]), 0:float(shape[1])]
|
||||
cy, cx = center
|
||||
r_lim, c_lim = np.ogrid[0:float(shape[0]), 0:float(shape[1])]
|
||||
r, c = center
|
||||
ry, rx = radiuses
|
||||
distances = ((y - cy) / ry) ** 2 + ((x - cx) / rx) ** 2
|
||||
distances = ((r_lim - r) / ry) ** 2 + ((c_lim - c) / rx) ** 2
|
||||
return np.nonzero(distances < 1)
|
||||
|
||||
|
||||
def ellipse(cy, cx, yradius, xradius, shape=None):
|
||||
def ellipse(r, c, yradius, xradius, shape=None):
|
||||
"""Generate coordinates of pixels within ellipse.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cy, cx : double
|
||||
r, c : double
|
||||
Centre coordinate of ellipse.
|
||||
yradius, xradius : double
|
||||
Minor and major semi-axes. ``(x/xradius)**2 + (y/yradius)**2 = 1``.
|
||||
@@ -53,7 +53,7 @@ def ellipse(cy, cx, yradius, xradius, shape=None):
|
||||
|
||||
"""
|
||||
|
||||
center = np.array([cy, cx])
|
||||
center = np.array([r, c])
|
||||
radiuses = np.array([yradius, xradius])
|
||||
|
||||
# The upper_left and lower_right corners of the
|
||||
@@ -77,12 +77,12 @@ def ellipse(cy, cx, yradius, xradius, shape=None):
|
||||
return rr, cc
|
||||
|
||||
|
||||
def circle(cy, cx, radius, shape=None):
|
||||
def circle(r, c, radius, shape=None):
|
||||
"""Generate coordinates of pixels within circle.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cy, cx : double
|
||||
r, c : double
|
||||
Centre coordinate of circle.
|
||||
radius: double
|
||||
Radius of circle.
|
||||
@@ -122,7 +122,7 @@ def circle(cy, cx, radius, shape=None):
|
||||
|
||||
"""
|
||||
|
||||
return ellipse(cy, cx, radius, radius, shape)
|
||||
return ellipse(r, c, radius, radius, shape)
|
||||
|
||||
|
||||
def set_color(img, coords, color):
|
||||
|
||||
+11
-6
@@ -5,7 +5,8 @@ from . import _hoghistogram
|
||||
|
||||
|
||||
def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
cells_per_block=(3, 3), visualise=False, normalise=False):
|
||||
cells_per_block=(3, 3), visualise=False, normalise=False,
|
||||
feature_vector=True):
|
||||
"""Extract Histogram of Oriented Gradients (HOG) for a given image.
|
||||
|
||||
Compute a Histogram of Oriented Gradients (HOG) by
|
||||
@@ -31,6 +32,9 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
normalise : bool, optional
|
||||
Apply power law compression to normalise the image before
|
||||
processing.
|
||||
feature_vector : bool, optional
|
||||
Return the data as a feature vector by calling .ravel() on the result
|
||||
just before returning.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -127,13 +131,11 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
orientations_arr = np.arange(orientations)
|
||||
dx_arr = radius * np.cos(orientations_arr / orientations * np.pi)
|
||||
dy_arr = radius * np.sin(orientations_arr / orientations * np.pi)
|
||||
cr2 = cy + cy
|
||||
cc2 = cx + cx
|
||||
hog_image = np.zeros((sy, sx), dtype=float)
|
||||
for x in range(n_cellsx):
|
||||
for y in range(n_cellsy):
|
||||
for o, dx, dy in zip(orientations_arr, dx_arr, dy_arr):
|
||||
centre = tuple([y * cr2 // 2, x * cc2 // 2])
|
||||
centre = tuple([y * cy + cy // 2, x * cx + cx // 2])
|
||||
rr, cc = draw.line(int(centre[0] - dx),
|
||||
int(centre[1] + dy),
|
||||
int(centre[0] + dx),
|
||||
@@ -171,8 +173,11 @@ def hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
overlapping grid of blocks covering the detection window into a combined
|
||||
feature vector for use in the window classifier.
|
||||
"""
|
||||
|
||||
if feature_vector:
|
||||
normalised_blocks = normalised_blocks.ravel()
|
||||
|
||||
if visualise:
|
||||
return normalised_blocks.ravel(), hog_image
|
||||
return normalised_blocks, hog_image
|
||||
else:
|
||||
return normalised_blocks.ravel()
|
||||
return normalised_blocks
|
||||
|
||||
@@ -10,7 +10,9 @@ cdef float cell_hog(double[:, ::1] magnitude,
|
||||
float orientation_start, float orientation_end,
|
||||
int cell_columns, int cell_rows,
|
||||
int column_index, int row_index,
|
||||
int size_columns, int size_rows) nogil:
|
||||
int size_columns, int size_rows,
|
||||
int range_rows_start, int range_rows_stop,
|
||||
int range_columns_start, int range_columns_stop) nogil:
|
||||
"""Calculation of the cell's HOG value
|
||||
|
||||
Parameters
|
||||
@@ -35,22 +37,23 @@ cdef float cell_hog(double[:, ::1] magnitude,
|
||||
Number of columns.
|
||||
size_rows : int
|
||||
Number of rows.
|
||||
range_rows_start : int
|
||||
Start row of cell.
|
||||
range_rows_stop : int
|
||||
Stop row of cell.
|
||||
range_columns_start : int
|
||||
Start column of cell.
|
||||
range_columns_stop : int
|
||||
Stop column of cell
|
||||
|
||||
Returns
|
||||
-------
|
||||
total : float
|
||||
The total HOG value.
|
||||
"""
|
||||
cdef int cell_column, cell_row, cell_row_index, cell_column_index, \
|
||||
range_columns_start, range_columns_stop, range_rows_start, \
|
||||
range_rows_stop
|
||||
|
||||
range_rows_stop = cell_rows/2
|
||||
range_rows_start = -range_rows_stop
|
||||
range_columns_stop = cell_columns/2
|
||||
range_columns_start = -range_columns_stop
|
||||
|
||||
cdef int cell_column, cell_row, cell_row_index, cell_column_index
|
||||
cdef float total = 0.
|
||||
|
||||
for cell_row in range(range_rows_start, range_rows_stop):
|
||||
cell_row_index = row_index + cell_row
|
||||
if (cell_row_index < 0 or cell_row_index >= size_rows):
|
||||
@@ -67,7 +70,7 @@ cdef float cell_hog(double[:, ::1] magnitude,
|
||||
|
||||
total += magnitude[cell_row_index, cell_column_index]
|
||||
|
||||
return total
|
||||
return total / (cell_rows * cell_columns)
|
||||
|
||||
def hog_histograms(double[:, ::1] gradient_columns,
|
||||
double[:, ::1] gradient_rows,
|
||||
@@ -106,7 +109,9 @@ def hog_histograms(double[:, ::1] gradient_columns,
|
||||
gradient_rows)
|
||||
cdef double[:, ::1] orientation = \
|
||||
np.arctan2(gradient_rows, gradient_columns) * (180 / np.pi) % 180
|
||||
cdef int i, x, y, o, yi, xi, cc, cr, x0, y0
|
||||
cdef int i, x, y, o, yi, xi, cc, cr, x0, y0, \
|
||||
range_rows_start, range_rows_stop, \
|
||||
range_columns_start, range_columns_stop
|
||||
cdef float orientation_start, orientation_end, \
|
||||
number_of_orientations_per_180
|
||||
|
||||
@@ -115,6 +120,10 @@ def hog_histograms(double[:, ::1] gradient_columns,
|
||||
cc = cell_rows * number_of_cells_rows
|
||||
cr = cell_columns * number_of_cells_columns
|
||||
number_of_orientations_per_180 = 180. / number_of_orientations
|
||||
range_rows_stop = cell_rows/2
|
||||
range_rows_start = -range_rows_stop
|
||||
range_columns_stop = cell_columns/2
|
||||
range_columns_start = -range_columns_stop
|
||||
|
||||
with nogil:
|
||||
# compute orientations integral images
|
||||
@@ -134,7 +143,8 @@ def hog_histograms(double[:, ::1] gradient_columns,
|
||||
while x < cr:
|
||||
orientation_histogram[yi, xi, i] = cell_hog(magnitude,
|
||||
orientation, orientation_start, orientation_end,
|
||||
cell_columns, cell_rows, x, y, size_columns, size_rows)
|
||||
cell_columns, cell_rows, x, y, size_columns, size_rows,
|
||||
range_rows_start, range_rows_stop, range_columns_start, range_columns_stop)
|
||||
xi += 1
|
||||
x += cell_columns
|
||||
|
||||
|
||||
@@ -271,8 +271,8 @@ def _local_binary_pattern(double[:, ::1] image,
|
||||
# Values represent offsets of neighbour rectangles relative to central one.
|
||||
# It has order starting from top left and going clockwise.
|
||||
cdef:
|
||||
Py_ssize_t[::1] mlbp_r_offsets = np.asarray([-1, -1, -1, 0, 1, 1, 1, 0])
|
||||
Py_ssize_t[::1] mlbp_c_offsets = np.asarray([-1, 0, 1, 1, 1, 0, -1, -1])
|
||||
Py_ssize_t[::1] mlbp_r_offsets = np.asarray([-1, -1, -1, 0, 1, 1, 1, 0], dtype=np.intp)
|
||||
Py_ssize_t[::1] mlbp_c_offsets = np.asarray([-1, 0, 1, 1, 1, 0, -1, -1], dtype=np.intp)
|
||||
|
||||
|
||||
def _multiblock_lbp(float[:, ::1] int_image,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import os
|
||||
import numpy as np
|
||||
from scipy import ndimage as ndi
|
||||
import skimage as si
|
||||
from skimage import data
|
||||
from skimage import feature
|
||||
from skimage import img_as_float
|
||||
@@ -9,7 +11,7 @@ from numpy.testing import (assert_raises,
|
||||
)
|
||||
|
||||
|
||||
def test_histogram_of_oriented_gradients():
|
||||
def test_histogram_of_oriented_gradients_output_size():
|
||||
img = img_as_float(data.astronaut()[:256, :].mean(axis=2))
|
||||
|
||||
fd = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
|
||||
@@ -18,6 +20,17 @@ def test_histogram_of_oriented_gradients():
|
||||
assert len(fd) == 9 * (256 // 8) * (512 // 8)
|
||||
|
||||
|
||||
def test_histogram_of_oriented_gradients_output_correctness():
|
||||
img = np.load(os.path.join(si.data_dir, 'lena_GRAY_U8.npy'))
|
||||
correct_output = np.load(os.path.join(si.data_dir, 'lena_GRAY_U8_hog.npy'))
|
||||
|
||||
output = feature.hog(img, orientations=9, pixels_per_cell=(8, 8),
|
||||
cells_per_block=(3, 3), feature_vector=True,
|
||||
normalise=False, visualise=False)
|
||||
|
||||
assert_almost_equal(output, correct_output)
|
||||
|
||||
|
||||
def test_hog_image_size_cell_size_mismatch():
|
||||
image = data.camera()[:150, :200]
|
||||
fd = feature.hog(image, orientations=9, pixels_per_cell=(8, 8),
|
||||
|
||||
+67
-77
@@ -1,16 +1,6 @@
|
||||
try:
|
||||
import networkx as nx
|
||||
except ImportError:
|
||||
msg = "Graph functions require networkx, which is not installed"
|
||||
|
||||
class nx:
|
||||
class Graph:
|
||||
def __init__(self, *args, **kwargs):
|
||||
raise ImportError(msg)
|
||||
import warnings
|
||||
warnings.warn(msg)
|
||||
|
||||
import networkx as nx
|
||||
import numpy as np
|
||||
from numpy.lib.stride_tricks import as_strided
|
||||
from scipy import ndimage as ndi
|
||||
import math
|
||||
from ... import draw, measure, segmentation, util, color
|
||||
@@ -51,21 +41,79 @@ def min_weight(graph, src, dst, n):
|
||||
return min(w1, w2)
|
||||
|
||||
|
||||
def _add_edge_filter(values, graph):
|
||||
"""Create edge in `graph` between central element of `values` and the rest.
|
||||
|
||||
Add an edge between the middle element in `values` and
|
||||
all other elements of `values` into `graph`. ``values[len(values) // 2]``
|
||||
is expected to be the central value of the footprint used.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
values : array
|
||||
The array to process.
|
||||
graph : RAG
|
||||
The graph to add edges in.
|
||||
|
||||
Returns
|
||||
-------
|
||||
0 : float
|
||||
Always returns 0. The return value is required so that `generic_filter`
|
||||
can put it in the output array, but it is ignored by this filter.
|
||||
"""
|
||||
values = values.astype(int)
|
||||
center = values[len(values) // 2]
|
||||
for value in values:
|
||||
if value != center and not graph.has_edge(center, value):
|
||||
graph.add_edge(center, value)
|
||||
return 0.
|
||||
|
||||
|
||||
class RAG(nx.Graph):
|
||||
|
||||
"""
|
||||
The Region Adjacency Graph (RAG) of an image, subclasses
|
||||
`networx.Graph <http://networkx.github.io/documentation/latest/reference/classes.graph.html>`_
|
||||
|
||||
Parameters
|
||||
----------
|
||||
label_image : array of int
|
||||
An initial segmentation, with each region labeled as a different
|
||||
integer. Every unique value in ``label_image`` will correspond to
|
||||
a node in the graph.
|
||||
connectivity : int in {1, ..., ``label_image.ndim``}, optional
|
||||
The connectivity between pixels in ``label_image``. For a 2D image,
|
||||
a connectivity of 1 corresponds to immediate neighbors up, down,
|
||||
left, and right, while a connectivity of 2 also includes diagonal
|
||||
neighbors. See `scipy.ndimage.generate_binary_structure`.
|
||||
data : networkx Graph specification, optional
|
||||
Initial or additional edges to pass to the NetworkX Graph
|
||||
constructor. See `networkx.Graph`. Valid edge specifications
|
||||
include edge list (list of tuples), NumPy arrays, and SciPy
|
||||
sparse matrices.
|
||||
**attr : keyword arguments, optional
|
||||
Additional attributes to add to the graph.
|
||||
"""
|
||||
|
||||
def __init__(self, data=None, **attr):
|
||||
def __init__(self, label_image=None, connectivity=1, data=None, **attr):
|
||||
|
||||
super(RAG, self).__init__(data, **attr)
|
||||
try:
|
||||
self.max_id = max(self.nodes_iter())
|
||||
except ValueError:
|
||||
# Empty sequence
|
||||
if self.number_of_nodes() == 0:
|
||||
self.max_id = 0
|
||||
else:
|
||||
self.max_id = max(self.nodes_iter())
|
||||
|
||||
if label_image is not None:
|
||||
fp = ndi.generate_binary_structure(label_image.ndim, connectivity)
|
||||
ndi.generic_filter(
|
||||
label_image,
|
||||
function=_add_edge_filter,
|
||||
footprint=fp,
|
||||
mode='nearest',
|
||||
output=as_strided(np.empty((1,), dtype=np.float_),
|
||||
shape=label_image.shape,
|
||||
strides=((0,) * label_image.ndim)),
|
||||
extra_arguments=(self,))
|
||||
|
||||
def merge_nodes(self, src, dst, weight_func=min_weight, in_place=True,
|
||||
extra_arguments=[], extra_keywords={}):
|
||||
@@ -172,36 +220,6 @@ class RAG(nx.Graph):
|
||||
super(RAG, self).add_node(n)
|
||||
|
||||
|
||||
def _add_edge_filter(values, graph):
|
||||
"""Create edge in `g` between the first element of `values` and the rest.
|
||||
|
||||
Add an edge between the first element in `values` and
|
||||
all other elements of `values` in the graph `g`. `values[0]`
|
||||
is expected to be the central value of the footprint used.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
values : array
|
||||
The array to process.
|
||||
graph : RAG
|
||||
The graph to add edges in.
|
||||
|
||||
Returns
|
||||
-------
|
||||
0 : int
|
||||
Always returns 0. The return value is required so that `generic_filter`
|
||||
can put it in the output array.
|
||||
|
||||
"""
|
||||
values = values.astype(int)
|
||||
current = values[0]
|
||||
for value in values[1:]:
|
||||
if value != current:
|
||||
graph.add_edge(current, value)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def rag_mean_color(image, labels, connectivity=2, mode='distance',
|
||||
sigma=255.0):
|
||||
"""Compute the Region Adjacency Graph using mean colors.
|
||||
@@ -224,7 +242,7 @@ def rag_mean_color(image, labels, connectivity=2, mode='distance',
|
||||
Pixels with a squared distance less than `connectivity` from each other
|
||||
are considered adjacent. It can range from 1 to `labels.ndim`. Its
|
||||
behavior is the same as `connectivity` parameter in
|
||||
`scipy.ndimage.filters.generate_binary_structure`.
|
||||
`scipy.ndimage.generate_binary_structure`.
|
||||
mode : {'distance', 'similarity'}, optional
|
||||
The strategy to assign edge weights.
|
||||
|
||||
@@ -263,35 +281,7 @@ def rag_mean_color(image, labels, connectivity=2, mode='distance',
|
||||
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.11.5274
|
||||
|
||||
"""
|
||||
graph = RAG()
|
||||
|
||||
# The footprint is constructed in such a way that the first
|
||||
# element in the array being passed to _add_edge_filter is
|
||||
# the central value.
|
||||
fp = ndi.generate_binary_structure(labels.ndim, connectivity)
|
||||
for d in range(fp.ndim):
|
||||
fp = fp.swapaxes(0, d)
|
||||
fp[0, ...] = 0
|
||||
fp = fp.swapaxes(0, d)
|
||||
|
||||
# For example
|
||||
# if labels.ndim = 2 and connectivity = 1
|
||||
# fp = [[0,0,0],
|
||||
# [0,1,1],
|
||||
# [0,1,0]]
|
||||
#
|
||||
# if labels.ndim = 2 and connectivity = 2
|
||||
# fp = [[0,0,0],
|
||||
# [0,1,1],
|
||||
# [0,1,1]]
|
||||
|
||||
ndi.generic_filter(
|
||||
labels,
|
||||
function=_add_edge_filter,
|
||||
footprint=fp,
|
||||
mode='nearest',
|
||||
output=np.zeros(labels.shape, dtype=np.uint8),
|
||||
extra_arguments=(graph,))
|
||||
graph = RAG(labels, connectivity=connectivity)
|
||||
|
||||
for n in graph:
|
||||
graph.node[n].update({'labels': [n],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user