forked from przemekpastuszka/biometrics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
poincare.py
79 lines (60 loc) · 2.53 KB
/
poincare.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
# Metody biometryczne
# Przemyslaw Pastuszka
from PIL import Image, ImageDraw
import utils
import argparse
import math
import os
signum = lambda x: -1 if x < 0 else 1
cells = [(-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]
def get_angle(left, right):
angle = left - right
if abs(angle) > 180:
angle = -1 * signum(angle) * (360 - abs(angle))
return angle
def poincare_index_at(i, j, angles, tolerance):
deg_angles = [math.degrees(angles[i - k][j - l]) % 180 for k, l in cells]
index = 0
for k in range(0, 8):
if abs(get_angle(deg_angles[k], deg_angles[k + 1])) > 90:
deg_angles[k + 1] += 180
index += get_angle(deg_angles[k], deg_angles[k + 1])
if 180 - tolerance <= index and index <= 180 + tolerance:
return "loop"
if -180 - tolerance <= index and index <= -180 + tolerance:
return "delta"
if 360 - tolerance <= index and index <= 360 + tolerance:
return "whorl"
return "none"
def calculate_singularities(im, angles, tolerance, W):
(x, y) = im.size
result = im.convert("RGB")
draw = ImageDraw.Draw(result)
colors = {"loop" : (150, 0, 0), "delta" : (0, 150, 0), "whorl": (0, 0, 150)}
for i in range(1, len(angles) - 1):
for j in range(1, len(angles[i]) - 1):
singularity = poincare_index_at(i, j, angles, tolerance)
if singularity != "none":
draw.ellipse([(i * W, j * W), ((i + 1) * W, (j + 1) * W)], outline = colors[singularity])
del draw
return result
parser = argparse.ArgumentParser(description="Singularities with Poincare index")
parser.add_argument("image", nargs=1, help = "Path to image")
parser.add_argument("block_size", nargs=1, help = "Block size")
parser.add_argument("tolerance", nargs=1, help = "Tolerance for Poincare index")
parser.add_argument('--smooth', "-s", action='store_true', help = "Use Gauss for smoothing")
parser.add_argument("--save", action='store_true', help = "Save result image as src_poincare.gif")
args = parser.parse_args()
im = Image.open(args.image[0])
im = im.convert("L") # covert to grayscale
W = int(args.block_size[0])
f = lambda x, y: 2 * x * y
g = lambda x, y: x ** 2 - y ** 2
angles = utils.calculate_angles(im, W, f, g)
if args.smooth:
angles = utils.smooth_angles(angles)
result = calculate_singularities(im, angles, int(args.tolerance[0]), W)
result.show()
if args.save:
base_image_name = os.path.splitext(os.path.basename(args.image[0]))[0]
result.save(base_image_name + "_poincare.gif", "GIF")