Commit 5dcf393f authored by Taddeüs Kroes's avatar Taddeüs Kroes

improc ass3: Improved histogram intersection and added new intersection results.

parent 00f921ff
...@@ -7,13 +7,14 @@ from scipy.cluster.vq import kmeans ...@@ -7,13 +7,14 @@ from scipy.cluster.vq import kmeans
from intersect import col2bin, domainIterator, colHist, histogramIntersect from intersect import col2bin, domainIterator, colHist, histogramIntersect
def find_peaks(b, threshold, d_sq): def find_peaks(b, threshold, d):
"""Find the location of the peak values of a back projection histogram.""" """Find the location of the peak values of a back projection histogram."""
# Find all pixels with a value higher than a threshold of the maximum # Find all pixels with a value higher than a threshold of the maximum
# value. Collect K-means estimators on-the-fly. # value. Collect K-means estimators on-the-fly.
threshold *= b.max() threshold *= b.max()
means = [] means = []
use = [] use = []
d_sq = d ** 2
for p in domainIterator(b): for p in domainIterator(b):
if b[p] >= threshold: if b[p] >= threshold:
...@@ -34,7 +35,7 @@ def find_peaks(b, threshold, d_sq): ...@@ -34,7 +35,7 @@ def find_peaks(b, threshold, d_sq):
return [m[i].tolist() for i in xrange(m.shape[0])] return [m[i].tolist() for i in xrange(m.shape[0])]
def convolution(image, radius): def convolution(image, radius):
"""Calculate the convolution of an image with a specified circle radius.""" """Calculate the convolution of an image using a specified radius."""
# Loop to the square that surrounds the circle, and check if the pixel # Loop to the square that surrounds the circle, and check if the pixel
# is inside the circle # is inside the circle
r_sq = radius ** 2 r_sq = radius ** 2
...@@ -46,14 +47,11 @@ def convolution(image, radius): ...@@ -46,14 +47,11 @@ def convolution(image, radius):
return correlate(image, mask, mode='nearest') return correlate(image, mask, mode='nearest')
def hbp(image, environment, bins, model, radius, **kwargs): def hbp(image, environment, bins, model, radius, mask=None):
"""Create the histogram back projection of two images.""" """Create the histogram back projection of two images."""
options = dict(mask=None)
options.update(kwargs)
# Create image histograms # Create image histograms
print 'Creating histograms...' print 'Creating histograms...'
M = colHist(image, bins, model, mask=options['mask']) M = colHist(image, bins, model, mask)
I = colHist(environment, bins, model) I = colHist(environment, bins, model)
# Create ratio histogram # Create ratio histogram
...@@ -77,17 +75,18 @@ def hbp(image, environment, bins, model, radius, **kwargs): ...@@ -77,17 +75,18 @@ def hbp(image, environment, bins, model, radius, **kwargs):
for p in domainIterator(b): for p in domainIterator(b):
b[p] = min(R[col2bin(use[p])], 1.) b[p] = min(R[col2bin(use[p])], 1.)
# Create convolution to create a peak value # Create convolution to concentrate clusters into peak values
print 'Creating convolution...' print 'Creating convolution...'
return convolution(b, radius) return convolution(b, radius)
def exclude_color(color, image): def exclude_color(color, image):
mask = zeros(image.shape[:2], dtype=int) """Create an image mask that excludes a specific color."""
mask = zeros(image.shape[:2], dtype=bool)
color = array(color) color = array(color)
for p in domainIterator(image): for p in domainIterator(image):
if (image[p] != color).any(): if (image[p] != color).any():
mask[p] = 1 mask[p] = True
return mask return mask
...@@ -95,17 +94,20 @@ if __name__ == '__main__': ...@@ -95,17 +94,20 @@ if __name__ == '__main__':
print 'Reading images...' print 'Reading images...'
waldo = imread('waldo.tiff') waldo = imread('waldo.tiff')
env = imread('waldo_env.tiff') env = imread('waldo_env.tiff')
# Use a mask to ignore the white background in the Waldo image
mask = exclude_color([255] * 3, waldo) mask = exclude_color([255] * 3, waldo)
# Execute the back projection algorithm
import pickle import pickle
b = hbp(waldo, env, [64] * 3, 'rgb', 15, mask=mask) b = hbp(waldo, env, [64] * 3, 'rgb', 15, mask)
pickle.dump(b, open('projection.dat', 'w')) pickle.dump(b, open('projection.dat', 'w'))
#b = pickle.load(open('projection.dat', 'r')) #b = pickle.load(open('projection.dat', 'r'))
def plt(peaks):
"""Draw a rectangle around a list of center pixels."""
w, h = waldo.shape[:2] w, h = waldo.shape[:2]
def plt(peaks):
"""Draw a rectangle around a list of center pixels."""
for x, y in peaks: for x, y in peaks:
l = x - w / 2 l = x - w / 2
r = x + w / 2 r = x + w / 2
...@@ -113,10 +115,10 @@ if __name__ == '__main__': ...@@ -113,10 +115,10 @@ if __name__ == '__main__':
t = y + h / 2 t = y + h / 2
plot([t, t, b, b, t], [l, r, r, l, l], 'r-') plot([t, t, b, b, t], [l, r, r, l, l], 'r-')
w, h = waldo.shape[:2] # Experimental: use K-means to locate clusters, and draw a rectangle
# with the size of the model image around each cluster
print 'Locating peaks...' print 'Locating peaks...'
peaks = find_peaks(b, .75, w ** 2 + h ** 2) peaks = find_peaks(b, .75, sqrt(w ** 2 + h ** 2))
print 'Done' print 'Done'
subplot(121) subplot(121)
......
...@@ -7,7 +7,7 @@ def col2bin(color): ...@@ -7,7 +7,7 @@ def col2bin(color):
return tuple(color.astype(int)) return tuple(color.astype(int))
def domainIterator(image, dim=2): def domainIterator(image, dim=2):
"""Pixel iterator for arrays of with 2 or 3 dimensions.""" """Pixel iterator for arrays with 2 or 3 dimensions."""
if dim == 2: if dim == 2:
for x in xrange(image.shape[0]): for x in xrange(image.shape[0]):
for y in xrange(image.shape[1]): for y in xrange(image.shape[1]):
...@@ -18,9 +18,11 @@ def domainIterator(image, dim=2): ...@@ -18,9 +18,11 @@ def domainIterator(image, dim=2):
for z in xrange(image.shape[2]): for z in xrange(image.shape[2]):
yield x, y, z yield x, y, z
def colHist(image, bins, model, **kwargs): def colHist(image, bins, model, mask=None):
"""Create the color histogram of an image.""" """Create the color histogram of an image."""
h = zeros(bins, dtype=int) h = zeros(bins, dtype=int)
# Multiply with the number of bins to normalize bin coordinates
use = image.astype(float) * map(lambda x: x - 1, bins) use = image.astype(float) * map(lambda x: x - 1, bins)
if model == 'rgb': if model == 'rgb':
...@@ -31,10 +33,9 @@ def colHist(image, bins, model, **kwargs): ...@@ -31,10 +33,9 @@ def colHist(image, bins, model, **kwargs):
else: else:
raise ValueError('Color model "%s" is not supported.' % model) raise ValueError('Color model "%s" is not supported.' % model)
mask = kwargs['mask'] if 'mask' in kwargs else None
for p in domainIterator(image): for p in domainIterator(image):
if mask is None or mask[p].any(): # Optionally use a mask over the image
if mask is None or mask[p]:
h[col2bin(use[p])] += 1 h[col2bin(use[p])] += 1
return h return h
...@@ -47,24 +48,28 @@ def histogramIntersect(h1, h2): ...@@ -47,24 +48,28 @@ def histogramIntersect(h1, h2):
match = 0 match = 0
# Add the minimum of each bin to the result # Add the minimum of each bin to the result
for r in xrange(h1.shape[0]): for c in domainIterator(h1, 3):
for g in xrange(h1.shape[1]): match += min(h1[c], h2[c])
for b in xrange(h1.shape[2]):
match += min(h1[r, g, b], h2[r, g, b])
# Normalize by dividing by the number of pixels # Normalize by dividing by the number of pixels
return match / h2.sum() return float(match) / h2.sum()
# Create table of intersections of images in the database
if __name__ == '__main__': if __name__ == '__main__':
bins = [8] * 3 bins = [64] * 3
db = map(lambda x: imread('database/%d.jpg' % x), range(1, 21))
table = zeros((len(db), len(db))) # Create table of intersections of images in the database
print 'Creating histograms...'
for i, im in enumerate(db): hist = [colHist(imread('database/%d.jpg' % i), \
for j in xrange(i + 1, len(db)): bins, 'rgb') for i in xrange(1, 4)]
print 'comparing', i, j
table[i, j] = histogramIntersect(colHist(im, bins, 'rgb'), table = zeros((len(hist), len(hist)), dtype=int)
colHist(db[j], bins, 'rgb'))
for i, im in enumerate(hist):
table[i, i] = 100
for j in xrange(i + 1, len(hist)):
print 'comparing %d, %d' % (i, j)
table[i, j] = table[j, i] \
= round(histogramIntersect(hist[i], hist[j]) * 100)
print table print table
smvv@multivac ~/uva/improc/ass3 $ ./intersect.py [[100 57 56 41 40 45 28 52 51 43 45 54 35 54 59 36 51 47 38 44]
[[ 0. 0.72060366 0.77640562 0.55868417 0.61904568 0.70057057 0.41867857 0.71028194 0.70815927 0.66210259 0.56217674 0.74647126 0.69157127 0.7301907 0.63015182 0.6580901 0.7201945 0.64580169 0.71244529 0.64947058] [ 57 100 60 56 47 53 36 66 59 39 41 63 39 65 60 51 59 61 36 54]
[ 0. 0. 0.76210078 0.68254937 0.61073812 0.75221309 0.45804624 0.84188052 0.66520408 0.61869982 0.44375949 0.81177662 0.80250832 0.81112106 0.68761981 0.68464717 0.78415708 0.77850116 0.82898175 0.61402271] [ 56 60 100 46 49 63 24 66 60 58 40 75 48 52 57 35 53 54 45 48]
[ 0. 0. 0. 0.59062816 0.58618842 0.77884702 0.37966128 0.74307138 0.79882134 0.7633667 0.53812211 0.90176957 0.71549027 0.78960051 0.67587393 0.65731698 0.77088759 0.66468415 0.74784569 0.70319508] [ 41 56 46 100 47 47 35 50 48 36 39 49 39 42 48 34 40 63 38 35]
[ 0. 0. 0. 0. 0.57743327 0.5706335 0.54137505 0.61955431 0.58975785 0.57135462 0.46743887 0.62527127 0.66735388 0.63696967 0.64811876 0.57083921 0.57917164 0.83977593 0.67239719 0.56083397] [ 40 47 49 47 100 50 27 53 46 40 40 48 38 45 41 34 38 50 38 36]
[ 0. 0. 0. 0. 0. 0.58057545 0.39684154 0.59966589 0.59130633 0.58189788 0.48560701 0.6197781 0.60343424 0.62944426 0.62893112 0.64971472 0.61038321 0.61493824 0.60368291 0.6308639 ] [ 45 53 63 47 50 100 25 60 53 43 38 59 49 46 47 35 45 55 46 42]
[ 0. 0. 0. 0. 0. 0. 0.36698405 0.75341119 0.6696167 0.64238372 0.46783447 0.77779812 0.69940864 0.76000977 0.63139513 0.66474067 0.78877089 0.64574969 0.74502903 0.62157525] [ 28 36 24 35 27 25 100 29 28 14 28 25 14 28 28 31 28 35 24 28]
[ 0. 0. 0. 0. 0. 0. 0. 0.40475125 0.38825367 0.37169732 0.44320114 0.38835992 0.41549344 0.41294804 0.38801179 0.35337773 0.37813766 0.50352195 0.50384974 0.40321859] [ 52 66 66 50 53 60 29 100 51 44 40 67 44 57 54 43 52 57 44 45]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0.64927391 0.6057694 0.43672689 0.76137288 0.73324698 0.77394839 0.64404071 0.67853687 0.84670455 0.72278058 0.8552653 0.5965011 ] [ 51 59 60 48 46 53 28 51 100 45 41 56 41 51 49 39 53 50 37 48]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.68963623 0.55953188 0.77286106 0.66498029 0.69918258 0.66703514 0.61316822 0.66380932 0.6590011 0.65070258 0.69579174] [ 43 39 58 36 40 43 14 44 45 100 29 48 52 35 39 20 35 40 53 27]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.51026521 0.70946587 0.63632767 0.6379598 0.65104619 0.58336046 0.63911947 0.61372658 0.60435429 0.69943802] [ 45 41 40 39 40 38 28 40 41 29 100 39 25 40 40 31 39 40 26 43]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.52328378 0.43955033 0.48742224 0.46883816 0.42306179 0.46300139 0.44289596 0.43518066 0.56698043] [ 54 63 75 49 48 59 25 67 56 48 39 100 41 57 62 41 55 56 36 51]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.75162082 0.84240044 0.74099166 0.6944874 0.78685619 0.70499901 0.74825711 0.72843651] [ 35 39 48 39 38 49 14 44 41 52 25 41 100 31 35 20 36 43 65 25]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.73753074 0.69874629 0.68486419 0.73546459 0.76116943 0.72118462 0.61668792] [ 54 65 52 42 45 46 28 57 51 35 40 57 31 100 55 51 57 48 31 54]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.72817654 0.68990524 0.76550067 0.69791441 0.76446533 0.68274604] [ 59 60 57 48 41 47 28 54 49 39 40 62 35 55 100 39 49 52 34 45]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.63760263 0.65532317 0.67954961 0.63642714 0.67855044] [ 36 51 35 34 34 35 31 43 39 20 31 41 20 51 39 100 57 41 19 45]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.68466526 0.65059181 0.66531711 0.58990026] [ 51 59 53 40 38 45 28 52 53 35 39 55 36 57 49 57 100 47 32 57]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.6701095 0.81639721 0.63657633] [ 47 61 54 63 50 55 35 57 50 40 40 56 43 48 52 41 47 100 40 40]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.72159831 0.60368969] [ 38 36 45 38 38 46 24 44 37 53 26 36 65 31 34 19 32 40 100 25]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.5848253 ] [ 44 54 48 35 36 42 28 45 48 27 43 51 25 54 45 45 57 40 25 100]]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment