mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-09 12:30:07 +08:00
Add DAISY visualization + example plot.
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
"""
|
||||||
|
===============================
|
||||||
|
Dense DAISY feature description
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The DAISY local image descriptor is based on gradient orientation histograms
|
||||||
|
similar to the SIFT descriptor. It is formulated in a way that allows for fast
|
||||||
|
dense extraction which is useful for e.g. bag-of-features image
|
||||||
|
representations.
|
||||||
|
|
||||||
|
In this example a limited number of DAISY descriptors are extracted at a large
|
||||||
|
scale for illustrative purposes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from skimage.feature import daisy
|
||||||
|
from skimage import data
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
img = data.camera()
|
||||||
|
descs, descs_img = daisy(img, step=180, radius=58, rings=2, histograms=6,
|
||||||
|
orientations=8, visualize=True)
|
||||||
|
|
||||||
|
plt.axis('off')
|
||||||
|
plt.imshow(descs_img)
|
||||||
|
descs_num = descs.shape[0] * descs.shape[1]
|
||||||
|
plt.title('%i DAISY descriptors extracted:' % descs_num)
|
||||||
|
plt.show()
|
||||||
@@ -13,7 +13,7 @@ This example shows how to fill several different shapes:
|
|||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
from skimage.draw import line, polygon, circle, ellipse
|
from skimage.draw import line, polygon, circle, circle_perimeter, ellipse
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
@@ -42,5 +42,9 @@ img[rr,cc,:] = (255, 255, 0)
|
|||||||
rr, cc = ellipse(300, 300, 100, 200, img.shape)
|
rr, cc = ellipse(300, 300, 100, 200, img.shape)
|
||||||
img[rr,cc,2] = 255
|
img[rr,cc,2] = 255
|
||||||
|
|
||||||
|
# circle
|
||||||
|
rr, cc = circle_perimeter(120, 400, 50)
|
||||||
|
img[rr, cc, :] = (255, 0, 255)
|
||||||
|
|
||||||
plt.imshow(img)
|
plt.imshow(img)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from skimage import img_as_float
|
|||||||
|
|
||||||
|
|
||||||
def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
|
def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
|
||||||
normalization='l1', sigmas=None, ring_radii=None):
|
normalization='l1', sigmas=None, ring_radii=None, visualize=False):
|
||||||
'''Extract DAISY feature descriptors densely for the given image.
|
'''Extract DAISY feature descriptors densely for the given image.
|
||||||
|
|
||||||
DAISY is a feature descriptor similar to SIFT formulated in a way that
|
DAISY is a feature descriptor similar to SIFT formulated in a way that
|
||||||
@@ -65,6 +65,8 @@ def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
|
|||||||
following predicate since no radius is needed for the center
|
following predicate since no radius is needed for the center
|
||||||
histogram.
|
histogram.
|
||||||
``len(ring_radii) == len(sigmas)+1``
|
``len(ring_radii) == len(sigmas)+1``
|
||||||
|
visualize : bool, optional
|
||||||
|
Generate a visualization of the DAISY descriptors
|
||||||
|
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@@ -75,10 +77,12 @@ def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
|
|||||||
| ``P = ceil((M-radius*2)/step)``
|
| ``P = ceil((M-radius*2)/step)``
|
||||||
| ``Q = ceil((N-radius*2)/step)``
|
| ``Q = ceil((N-radius*2)/step)``
|
||||||
| ``R = (rings*histograms + 1)*orientations``
|
| ``R = (rings*histograms + 1)*orientations``
|
||||||
|
descs_img : (M, N, 3) array (only if visualize==True)
|
||||||
|
Visualization of the DAISY descriptors.
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
----------
|
||||||
.. [1] Tola et al. "Daisy\: An efficient dense descriptor applied to wide-
|
.. [1] Tola et al. "Daisy: An efficient dense descriptor applied to wide-
|
||||||
baseline stereo." Pattern Analysis and Machine Intelligence, IEEE
|
baseline stereo." Pattern Analysis and Machine Intelligence, IEEE
|
||||||
Transactions on 32.5 (2010): 815-830.
|
Transactions on 32.5 (2010): 815-830.
|
||||||
.. [2] http://cvlab.epfl.ch/alumni/tola/daisy.html
|
.. [2] http://cvlab.epfl.ch/alumni/tola/daisy.html
|
||||||
@@ -120,10 +124,11 @@ def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
|
|||||||
kappa = 1. / hist_sigma
|
kappa = 1. / hist_sigma
|
||||||
bessel = iv(0, kappa)
|
bessel = iv(0, kappa)
|
||||||
hist = np.empty((orientations,) + img.shape, dtype=float)
|
hist = np.empty((orientations,) + img.shape, dtype=float)
|
||||||
for i in range(orientations):
|
orientation_angles = [2 * o * pi / orientations - pi
|
||||||
mu = 2 * i * pi / orientations - pi
|
for o in range(orientations)]
|
||||||
|
for i, o in enumerate(orientation_angles):
|
||||||
# Weigh bin contribution by the circular normal distribution
|
# Weigh bin contribution by the circular normal distribution
|
||||||
hist[i, :, :] = exp(kappa * cos(grad_ori - mu)) / (2 * pi * bessel)
|
hist[i, :, :] = exp(kappa * cos(grad_ori - o)) / (2 * pi * bessel)
|
||||||
# Weigh bin contribution by the gradient magnitude
|
# Weigh bin contribution by the gradient magnitude
|
||||||
hist[i, :, :] = np.multiply(hist[i, :, :], grad_mag)
|
hist[i, :, :] = np.multiply(hist[i, :, :], grad_mag)
|
||||||
|
|
||||||
@@ -169,4 +174,57 @@ def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
|
|||||||
axis=2))
|
axis=2))
|
||||||
descs[:, :, i:i + orientations] /= norms[:, :, np.newaxis]
|
descs[:, :, i:i + orientations] /= norms[:, :, np.newaxis]
|
||||||
|
|
||||||
return descs
|
if visualize:
|
||||||
|
from skimage import draw
|
||||||
|
from skimage import color
|
||||||
|
descs_img = color.gray2rgb(img)
|
||||||
|
for i in range(descs.shape[0]):
|
||||||
|
for j in range(descs.shape[1]):
|
||||||
|
# Draw center histogram sigma
|
||||||
|
color = (1, 0, 0)
|
||||||
|
desc_y = i * step + radius
|
||||||
|
desc_x = j * step + radius
|
||||||
|
coords = draw.circle_perimeter(desc_y, desc_x, sigmas[0])
|
||||||
|
set_color(descs_img, coords, color)
|
||||||
|
max_bin = np.max(descs[i, j, :])
|
||||||
|
for o_num, o in enumerate(orientation_angles):
|
||||||
|
# Draw center histogram bins
|
||||||
|
bin_size = descs[i, j, o_num] / max_bin
|
||||||
|
dy = sigmas[0] * bin_size * sin(o)
|
||||||
|
dx = sigmas[0] * bin_size * cos(o)
|
||||||
|
coords = draw.line(desc_y, desc_x, desc_y + dy,
|
||||||
|
desc_x + dx)
|
||||||
|
set_color(descs_img, coords, color)
|
||||||
|
for r_num, r in enumerate(ring_radii):
|
||||||
|
color_offset = float(1 + r_num) / rings
|
||||||
|
color = (1 - color_offset, 1, color_offset)
|
||||||
|
for t_num, t in enumerate(theta):
|
||||||
|
# Draw ring histogram sigmas
|
||||||
|
hist_y = desc_y + int(round(r * sin(t)))
|
||||||
|
hist_x = desc_x + int(round(r * cos(t)))
|
||||||
|
coords = draw.circle_perimeter(hist_y, hist_x,
|
||||||
|
sigmas[r_num + 1])
|
||||||
|
set_color(descs_img, coords, color)
|
||||||
|
for o_num, o in enumerate(orientation_angles):
|
||||||
|
# Draw histogram bins
|
||||||
|
bin_size = descs[i, j, orientations + r_num *
|
||||||
|
histograms * orientations +
|
||||||
|
t_num * orientations + o_num]
|
||||||
|
bin_size /= max_bin
|
||||||
|
dy = sigmas[r_num + 1] * bin_size * sin(o)
|
||||||
|
dx = sigmas[r_num + 1] * bin_size * cos(o)
|
||||||
|
coords = draw.line(hist_y, hist_x, hist_y + dy,
|
||||||
|
hist_x + dx)
|
||||||
|
set_color(descs_img, coords, color)
|
||||||
|
return descs, descs_img
|
||||||
|
else:
|
||||||
|
return descs
|
||||||
|
|
||||||
|
|
||||||
|
def set_color(img, coords, color):
|
||||||
|
''' Set pixel color at the given coordiantes in the image.'''
|
||||||
|
coords = filter(lambda (y, x): y >= 0 and y < img.shape[0] and x >= 0
|
||||||
|
and x < img.shape[1], zip(*coords))
|
||||||
|
if coords:
|
||||||
|
rr, cc = zip(*coords)
|
||||||
|
img[rr, cc, :] = color
|
||||||
|
|||||||
@@ -85,6 +85,11 @@ def test_daisy_normalization():
|
|||||||
assert_raises(ValueError, daisy, img, normalization='does_not_exist')
|
assert_raises(ValueError, daisy, img, normalization='does_not_exist')
|
||||||
|
|
||||||
|
|
||||||
|
def test_daisy_visualization():
|
||||||
|
img = img_as_float(data.lena()[:128, :128].mean(axis=2))
|
||||||
|
descs, descs_img = daisy(img, visualize=True)
|
||||||
|
assert(descs_img.shape == (128, 128, 3))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from numpy import testing
|
from numpy import testing
|
||||||
testing.run_module_suite()
|
testing.run_module_suite()
|
||||||
|
|||||||
Reference in New Issue
Block a user