Add DAISY visualization + example plot.

This commit is contained in:
Anders Boesen Lindbo Larsen
2012-12-15 18:44:23 +01:00
parent 2849cbf858
commit 6c19cf0693
4 changed files with 103 additions and 8 deletions
+28
View File
@@ -0,0 +1,28 @@
"""
===============================
Dense DAISY feature description
===============================
The DAISY local image descriptor is based on gradient orientation histograms
similar to the SIFT descriptor. It is formulated in a way that allows for fast
dense extraction which is useful for e.g. bag-of-features image
representations.
In this example a limited number of DAISY descriptors are extracted at a large
scale for illustrative purposes.
"""
from skimage.feature import daisy
from skimage import data
import matplotlib.pyplot as plt
img = data.camera()
descs, descs_img = daisy(img, step=180, radius=58, rings=2, histograms=6,
orientations=8, visualize=True)
plt.axis('off')
plt.imshow(descs_img)
descs_num = descs.shape[0] * descs.shape[1]
plt.title('%i DAISY descriptors extracted:' % descs_num)
plt.show()
+6 -2
View File
@@ -13,7 +13,7 @@ This example shows how to fill several different shapes:
import matplotlib.pyplot as plt
from skimage.draw import line, polygon, circle, ellipse
from skimage.draw import line, polygon, circle, circle_perimeter, ellipse
import numpy as np
@@ -42,5 +42,9 @@ img[rr,cc,:] = (255, 255, 0)
rr, cc = ellipse(300, 300, 100, 200, img.shape)
img[rr,cc,2] = 255
# circle
rr, cc = circle_perimeter(120, 400, 50)
img[rr, cc, :] = (255, 0, 255)
plt.imshow(img)
plt.show()
plt.show()
+64 -6
View File
@@ -6,7 +6,7 @@ from skimage import img_as_float
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.
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
histogram.
``len(ring_radii) == len(sigmas)+1``
visualize : bool, optional
Generate a visualization of the DAISY descriptors
Returns
@@ -75,10 +77,12 @@ def daisy(img, step=4, radius=15, rings=3, histograms=8, orientations=8,
| ``P = ceil((M-radius*2)/step)``
| ``Q = ceil((N-radius*2)/step)``
| ``R = (rings*histograms + 1)*orientations``
descs_img : (M, N, 3) array (only if visualize==True)
Visualization of the DAISY descriptors.
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
Transactions on 32.5 (2010): 815-830.
.. [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
bessel = iv(0, kappa)
hist = np.empty((orientations,) + img.shape, dtype=float)
for i in range(orientations):
mu = 2 * i * pi / orientations - pi
orientation_angles = [2 * o * pi / orientations - pi
for o in range(orientations)]
for i, o in enumerate(orientation_angles):
# 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
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))
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
+5
View File
@@ -85,6 +85,11 @@ def test_daisy_normalization():
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__':
from numpy import testing
testing.run_module_suite()