-
Notifications
You must be signed in to change notification settings - Fork 160
/
hashkey.py
67 lines (56 loc) · 1.44 KB
/
hashkey.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import numpy as np
from math import atan2, floor, pi
def hashkey(block, Qangle, W):
# Calculate gradient
gy, gx = np.gradient(block)
# Transform 2D matrix into 1D array
gx = gx.ravel()
gy = gy.ravel()
# SVD calculation
G = np.vstack((gx,gy)).T
GTWG = G.T.dot(W).dot(G)
w, v = np.linalg.eig(GTWG);
# Make sure V and D contain only real numbers
nonzerow = np.count_nonzero(np.isreal(w))
nonzerov = np.count_nonzero(np.isreal(v))
if nonzerow != 0:
w = np.real(w)
if nonzerov != 0:
v = np.real(v)
# Sort w and v according to the descending order of w
idx = w.argsort()[::-1]
w = w[idx]
v = v[:,idx]
# Calculate theta
theta = atan2(v[1,0], v[0,0])
if theta < 0:
theta = theta + pi
# Calculate lamda
lamda = w[0]
# Calculate u
sqrtlamda1 = np.sqrt(w[0])
sqrtlamda2 = np.sqrt(w[1])
if sqrtlamda1 + sqrtlamda2 == 0:
u = 0
else:
u = (sqrtlamda1 - sqrtlamda2)/(sqrtlamda1 + sqrtlamda2)
# Quantize
angle = floor(theta/pi*Qangle)
if lamda < 0.0001:
strength = 0
elif lamda > 0.001:
strength = 2
else:
strength = 1
if u < 0.25:
coherence = 0
elif u > 0.5:
coherence = 2
else:
coherence = 1
# Bound the output to the desired ranges
if angle > 23:
angle = 23
elif angle < 0:
angle = 0
return angle, strength, coherence