-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfrequency.py
84 lines (72 loc) · 3.29 KB
/
frequency.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
import numpy as np
import math
import scipy.ndimage
def frequest(im, orientim, kernel_size, minWaveLength, maxWaveLength):
"""
Function to estimate the fingerprint ridge frequency within a small block
of a fingerprint image.
An image block the same size as im with all values set to the estimated ridge spatial frequency. If a
ridge frequency cannot be found, or cannot be found within the limits set by min and max Wavlength freqim is set to zeros.
"""
rows, cols = np.shape(im)
# Find mean orientation within the block. This is done by averaging the
# sines and cosines of the doubled angles before reconstructing the angle again.
cosorient = np.cos(2 * orientim)
sinorient = np.sin(2 * orientim)
block_orient = math.atan2(sinorient, cosorient) / 2
# Rotate the image block so that the ridges are vertical
rotim = scipy.ndimage.rotate(
im,
block_orient / np.pi * 180 + 90,
axes=(1, 0),
reshape=False,
order=3,
mode="nearest",
)
# Now crop the image so that the rotated image does not contain any invalid regions.
cropsze = int(np.fix(rows / np.sqrt(2)))
offset = int(np.fix((rows - cropsze) / 2))
rotim = rotim[offset : offset + cropsze][:, offset : offset + cropsze]
# Sum down the columns to get a projection of the grey values down the ridges.
ridge_sum = np.sum(rotim, axis=0)
dilation = scipy.ndimage.grey_dilation(
ridge_sum, kernel_size, structure=np.ones(kernel_size)
)
ridge_noise = np.abs(dilation - ridge_sum)
peak_thresh = 2
maxpts = (ridge_noise < peak_thresh) & (ridge_sum > np.mean(ridge_sum))
maxind = np.where(maxpts)
_, no_of_peaks = np.shape(maxind)
# Determine the spatial frequency of the ridges by dividing the
# distance between the 1st and last peaks by the (No of peaks-1). If no
# peaks are detected, or the wavelength is outside the allowed bounds, the frequency image is set to 0
if no_of_peaks < 2:
freq_block = np.zeros(im.shape)
else:
waveLength = (maxind[0][-1] - maxind[0][0]) / (no_of_peaks - 1)
if waveLength >= minWaveLength and waveLength <= maxWaveLength:
freq_block = 1 / np.double(waveLength) * np.ones(im.shape)
else:
freq_block = np.zeros(im.shape)
return freq_block
def ridge_freq(im, mask, orient, block_size, kernel_size, minWaveLength, maxWaveLength):
# Function to estimate the fingerprint ridge frequency across a
# fingerprint image.
rows, cols = im.shape
freq = np.zeros((rows, cols))
for row in range(0, rows - block_size, block_size):
for col in range(0, cols - block_size, block_size):
image_block = im[row : row + block_size][:, col : col + block_size]
angle_block = orient[row // block_size][col // block_size]
if angle_block:
freq[row : row + block_size][:, col : col + block_size] = frequest(
image_block, angle_block, kernel_size, minWaveLength, maxWaveLength
)
freq = freq * mask
freq_1d = np.reshape(freq, (1, rows * cols))
ind = np.where(freq_1d > 0)
ind = np.array(ind)
ind = ind[1, :]
non_zero_elems_in_freq = freq_1d[0][ind]
medianfreq = np.median(non_zero_elems_in_freq) * mask
return medianfreq