-
Notifications
You must be signed in to change notification settings - Fork 0
/
Classes.py
160 lines (129 loc) · 5.46 KB
/
Classes.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import numpy as np
class Window(object):
def __init__(self, image, n, s):
self.x_boundary = image.shape[1] + n
self.y_boundary = image.shape[0] + n
self.top_left = (0, 0)
self.bot_right = (n, n)
self.previousBotY = n
self.height = n
self.stride = (s, s)
try:
self.channels = image.shape[2]
except:
self.channels = 1
def resetPos(self):
self.top_left = (0, 0)
self.bot_right = (self.height, self.height)
def getPos(self):
return self.top_left, self.bot_right
def forwardPos(self):
# Case when you need to go down and start new line
if (self.bot_right + self.stride)[0] >= (self.x_boundary - self.height):
return (0, self.top_left[1] + self.stride[1]), (self.height, self.bot_right[1] + self.stride[1])
# generic move right case
else:
return (self.top_left[0] + self.stride[0], self.top_left[1]), \
(self.bot_right[0] + self.stride[0], self.bot_right[1])
def forwardMove(self):
self.top_left, self.bot_right = self.forwardPos()
return self.top_left, self.bot_right
def inBoundary(self, new_top_left=None, new_bot_right=None):
if new_top_left is None:
new_top_left = self.top_left
if new_bot_right is None:
new_bot_right = self.bot_right
return new_bot_right[0] <= self.x_boundary and new_bot_right[1] <= self.y_boundary and \
new_top_left[0] >= 0 and new_top_left[1] >= 0
def changedY(self):
if self.previousBotY == self.bot_right[1]:
return False
else:
self.previousBotY = self.bot_right[1]
return True
def getImageInBoundary(self, image):
new_image = []
for i in range(self.top_left[1], self.bot_right[1]):
if i >= image.shape[0]:
continue
new_image.append(image[i][self.top_left[0]: self.bot_right[0]])
if self.channels == 1:
return np.resize(np.array(new_image), (self.height, self.height))
else:
return np.resize(np.array(new_image), (self.height, self.height, self.channels))
def __str__(self):
return "Top Left Corner " + str(self.top_left) + "\nBot Right Corner " + str(self.bot_right)
class Kernel:
def __init__(self, kernel, weight):
self.kernel = kernel
self.weight = weight
def filter(self, roi, axis=0, channels=1):
if axis == 2:
ret = []
for i in range(channels):
if channels == 1:
_filter = self.kernel * roi
else:
_filter = self.kernel * roi[:, :, i]
sum_of_filter1 = _filter.sum()
if channels == 1:
_filter = self.kernel.T * roi
else:
_filter = self.kernel.T * roi[:, :, i]
sum_of_filter2 = _filter.sum()
ret.append((((sum_of_filter1 ** 2) + (sum_of_filter2 ** 2)) ** (1 / 2)) * self.weight)
return np.array(ret)
else:
kernel = self.kernel if axis == 0 else self.kernel.T
ret = []
for i in range(channels):
if channels == 1:
_filter = kernel * roi
else:
_filter = kernel * roi[:, :, i]
ret.append(_filter.sum() * self.weight)
return np.array(ret)
def filterImage(self, image, stride=1, window=None, axis=0):
new_image = []
line = []
if window is None:
moving_kernel = Window(image, self.kernel.shape[0], stride)
else:
image = window.getImageInBoundary(image)
moving_kernel = Window(image, self.kernel.shape[0], stride)
new_tl, _ = moving_kernel.forwardPos()
while moving_kernel.inBoundary(new_tl):
roi = moving_kernel.getImageInBoundary(image)
if moving_kernel.changedY():
new_image.append(line)
line = []
line.append(self.filter(roi, axis, moving_kernel.channels))
moving_kernel.forwardMove()
new_tl, _ = moving_kernel.forwardPos()
return np.array(new_image)
class Sobel:
def __init__(self, weight):
self.kernel = Kernel(np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]]),
weight)
def filterImage(self, image, stride=1, window=None, axis=2):
return self.kernel.filterImage(image, stride, window, axis)
class Gaussian:
def __init__(self, size, weight):
# Source: #https://gist.github.com/andrewgiessel/4635563
fwhm = size // 2
x = np.arange(0, size, 1, float)
y = x[:, np.newaxis]
x0 = y0 = size // 2
self.kernel = Kernel(np.exp(-4 * np.log(2) * ((x - x0) ** 2 + (y - y0) ** 2) / fwhm ** 2), weight)
def filterImage(self, image, stride=1, window=None, axis=0):
return self.kernel.filterImage(image, stride, window, axis)
class Bilinear:
def __init__(self, weight):
self.kernel = Kernel(np.array([[1, 2, 1],
[2, 4, 2],
[1, 2, 1]]),
weight)
def filterImage(self, image, stride=1, window=None, axis=0):
return self.kernel.filterImage(image, stride, window, axis)