Skip to content

Commit a3a0f80

Browse files
committed
Add gabor filter to filters in image processing
1 parent 6a99fe4 commit a3a0f80

File tree

3 files changed

+200
-0
lines changed

3 files changed

+200
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Metody biometryczne
2+
# Przemyslaw Pastuszka
3+
4+
from PIL import Image, ImageDraw
5+
import utils
6+
import argparse
7+
import math
8+
9+
10+
def points_on_line(line, W):
11+
im = Image.new("L", (W, 3 * W), 100)
12+
draw = ImageDraw.Draw(im)
13+
draw.line([(0, line(0) + W), (W, line(W) + W)], fill=10)
14+
im_load = im.load()
15+
16+
points = []
17+
for x in range(0, W):
18+
for y in range(0, 3 * W):
19+
if im_load[x, y] == 10:
20+
points.append((x, y - W))
21+
22+
del draw
23+
del im
24+
25+
dist = lambda x, y: (x - W / 2) ** 2 + (y - W / 2) ** 2
26+
27+
return sorted(points)[:W]
28+
29+
def vec_and_step(tang, W):
30+
(begin, end) = utils.get_line_ends(0, 0, W, tang)
31+
(x_vec, y_vec) = (end[0] - begin[0], end[1] - begin[1])
32+
length = math.hypot(x_vec, y_vec)
33+
(x_norm, y_norm) = (x_vec / length, y_vec / length)
34+
step = length / W
35+
36+
return (x_norm, y_norm, step)
37+
38+
def block_frequency(i, j, W, angle, im_load):
39+
tang = math.tan(angle)
40+
ortho_tang = -1 / tang
41+
42+
(x_norm, y_norm, step) = vec_and_step(tang, W)
43+
(x_corner, y_corner) = (0 if x_norm >= 0 else W, 0 if y_norm >= 0 else W)
44+
45+
grey_levels = []
46+
47+
for k in range(0, W):
48+
line = lambda x: (x - x_norm * k * step - x_corner) * ortho_tang + y_norm * k * step + y_corner
49+
points = points_on_line(line, W)
50+
level = 0
51+
for point in points:
52+
level += im_load[point[0] + i * W, point[1] + j * W]
53+
grey_levels.append(level)
54+
55+
treshold = 100
56+
upward = False
57+
last_level = 0
58+
last_bottom = 0
59+
count = 0.0
60+
spaces = len(grey_levels)
61+
for level in grey_levels:
62+
if level < last_bottom:
63+
last_bottom = level
64+
if upward and level < last_level:
65+
upward = False
66+
if last_bottom + treshold < last_level:
67+
count += 1
68+
last_bottom = last_level
69+
if level > last_level:
70+
upward = True
71+
last_level = level
72+
73+
return count / spaces if spaces > 0 else 0
74+
75+
def freq(im, W, angles):
76+
(x, y) = im.size
77+
im_load = im.load()
78+
freqs = [[0] for i in range (0, int(x / W))]
79+
80+
for i in range(1, int(x / W - 1)):
81+
for j in range(1, int(y / W - 1)):
82+
freq = block_frequency(i, j, W, angles[i][j], im_load)
83+
freqs[i].append(freq)
84+
freqs[i].append(0)
85+
86+
freqs[0] = freqs[-1] = [0 for i in range(0, y / W)]
87+
88+
return freqs
89+
90+
def freq_img(im, W, angles):
91+
(x, y) = im.size
92+
freqs = freq(im, W, angles)
93+
freq_img = im.copy()
94+
95+
for i in range(1, x / W - 1):
96+
for j in range(1, y / W - 1):
97+
box = (i * W, j * W, min(i * W + W, x), min(j * W + W, y))
98+
freq_img.paste(freqs[i][j] * 255.0 * 1.2, box)
99+
100+
return freq_img
101+
102+
if __name__ == "__main__":
103+
parser = argparse.ArgumentParser(description="Image frequency")
104+
parser.add_argument("image", nargs=1, help = "Path to image")
105+
parser.add_argument("block_size", nargs=1, help = "Block size")
106+
parser.add_argument('--smooth', "-s", action='store_true', help = "Use Gauss for smoothing")
107+
args = parser.parse_args()
108+
109+
im = Image.open(args.image[0])
110+
im = im.convert("L") # covert to grayscale
111+
im.show()
112+
113+
W = int(args.block_size[0])
114+
115+
f = lambda x, y: 2 * x * y
116+
g = lambda x, y: x ** 2 - y ** 2
117+
118+
angles = utils.calculate_angles(im, W, f, g)
119+
if args.smooth:
120+
angles = utils.smooth_angles(angles)
121+
122+
freq_img = freq_img(im, W, angles)
123+
freq_img.show()
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Metody biometryczne
2+
# Przemyslaw Pastuszka
3+
4+
from PIL import Image, ImageDraw
5+
import utils
6+
import argparse
7+
import math
8+
import frequency
9+
import os
10+
11+
def gabor_kernel(W, angle, freq):
12+
cos = math.cos(angle)
13+
sin = math.sin(angle)
14+
15+
yangle = lambda x, y: x * cos + y * sin
16+
xangle = lambda x, y: -x * sin + y * cos
17+
18+
xsigma = ysigma = 4
19+
20+
return utils.kernel_from_function(W, lambda x, y:
21+
math.exp(-(
22+
(xangle(x, y) ** 2) / (xsigma ** 2) +
23+
(yangle(x, y) ** 2) / (ysigma ** 2)) / 2) *
24+
math.cos(2 * math.pi * freq * xangle(x, y)))
25+
26+
def gabor(im, W, angles):
27+
(x, y) = im.size
28+
im_load = im.load()
29+
30+
freqs = frequency.freq(im, W, angles)
31+
print ("computing local ridge frequency done")
32+
33+
gauss = utils.gauss_kernel(3)
34+
utils.apply_kernel(freqs, gauss)
35+
36+
for i in range(1, x / W - 1):
37+
for j in range(1, y / W - 1):
38+
kernel = gabor_kernel(W, angles[i][j], freqs[i][j])
39+
for k in range(0, W):
40+
for l in range(0, W):
41+
im_load[i * W + k, j * W + l] = utils.apply_kernel_at(
42+
lambda x, y: im_load[x, y],
43+
kernel,
44+
i * W + k,
45+
j * W + l)
46+
47+
return im
48+
49+
if __name__ == "__main__":
50+
parser = argparse.ArgumentParser(description="Gabor filter applied")
51+
parser.add_argument("-t","--image", nargs=1, help = "Path to image")
52+
parser.add_argument("-l","--block_size", nargs=1, help = "Block size")
53+
parser.add_argument("--save", action='store_true', help = "Save result image as src_image_enhanced.gif")
54+
args = parser.parse_args()
55+
56+
im = Image.open(args.image[0])
57+
im = im.convert("L") # covert to grayscale
58+
im.show()
59+
60+
W = int(args.block_size[0])
61+
62+
f = lambda x, y: 2 * x * y
63+
g = lambda x, y: x ** 2 - y ** 2
64+
65+
angles = utils.calculate_angles(im, W, f, g)
66+
print(angles)
67+
print ("calculating orientation done")
68+
69+
angles = utils.smooth_angles(angles)
70+
print("smoothing angles done")
71+
72+
result = gabor(im, W, angles)
73+
result.show()
74+
75+
if args.save:
76+
base_image_name = os.path.splitext(os.path.basename(args.image[0]))[0]
77+
im.save(base_image_name + "_enhanced.gif", "GIF")
Loading

0 commit comments

Comments
 (0)