-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathorientation.py
103 lines (78 loc) · 3.02 KB
/
orientation.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import math
import numpy as np
import cv2 as cv
def calculate_angles(im, W, smoth=False):
"""
im: image
W: int width of the ridge
returns: array
"""
j1 = lambda x, y: 2 * x * y
j2 = lambda x, y: x**2 - y**2
j3 = lambda x, y: x**2 + y**2
(y, x) = im.shape
sobelOperator = [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
ySobel = np.array(sobelOperator).astype(np.int32)
xSobel = np.transpose(ySobel).astype(np.int32)
result = [[] for i in range(1, y, W)]
Gx_ = cv.filter2D(im / 125, -1, ySobel) * 125
Gy_ = cv.filter2D(im / 125, -1, xSobel) * 125
for j in range(1, y, W):
for i in range(1, x, W):
nominator = 0
denominator = 0
for l in range(j, min(j + W, y - 1)):
for k in range(i, min(i + W, x - 1)):
Gx = round(Gx_[l, k])
Gy = round(Gy_[l, k])
nominator += j1(Gx, Gy)
denominator += j2(Gx, Gy)
if nominator or denominator:
angle = (math.pi + math.atan2(nominator, denominator)) / 2
orientation = np.pi / 2 + math.atan2(nominator, denominator) / 2
result[int((j - 1) // W)].append(angle)
else:
result[int((j - 1) // W)].append(0)
result = np.array(result)
if smoth:
result = smooth_angles(result)
return result
def gauss(x, y):
ssigma = 1.0
return (1 / (2 * math.pi * ssigma)) * math.exp(-(x * x + y * y) / (2 * ssigma))
def kernel_from_function(size, f):
kernel = [[] for i in range(0, size)]
for i in range(0, size):
for j in range(0, size):
kernel[i].append(f(i - size / 2, j - size / 2))
return kernel
def smooth_angles(angles):
angles = np.array(angles)
cos_angles = np.cos(angles.copy() * 2)
sin_angles = np.sin(angles.copy() * 2)
kernel = np.array(kernel_from_function(5, gauss))
cos_angles = cv.filter2D(cos_angles / 125, -1, kernel) * 125
sin_angles = cv.filter2D(sin_angles / 125, -1, kernel) * 125
smooth_angles = np.arctan2(sin_angles, cos_angles) / 2
return smooth_angles
def get_line_ends(i, j, W, tang):
if -1 <= tang and tang <= 1:
begin = (i, int((-W / 2) * tang + j + W / 2))
end = (i + W, int((W / 2) * tang + j + W / 2))
else:
begin = (int(i + W / 2 + W / (2 * tang)), j + W // 2)
end = (int(i + W / 2 - W / (2 * tang)), j - W // 2)
return (begin, end)
def visualize_angles(im, mask, angles, W):
(y, x) = im.shape
result = cv.cvtColor(np.zeros(im.shape, np.uint8), cv.COLOR_GRAY2RGB)
mask_threshold = (W - 1) ** 2
for i in range(1, x, W):
for j in range(1, y, W):
radian = np.sum(mask[j - 1 : j + W, i - 1 : i + W])
if radian > mask_threshold:
tang = math.tan(angles[(j - 1) // W][(i - 1) // W])
(begin, end) = get_line_ends(i, j, W, tang)
cv.line(result, begin, end, color=150)
cv.resize(result, im.shape, result)
return result