1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Fri Apr 22 03:15:03 2016
4
+
5
+ @author: utkarsh
6
+ """
7
+
8
+
9
+ # RIDGEFILTER - enhances fingerprint image via oriented filters
10
+ #
11
+ # Function to enhance fingerprint image via oriented filters
12
+ #
13
+ # Usage:
14
+ # newim = ridgefilter(im, orientim, freqim, kx, ky, showfilter)
15
+ #
16
+ # Arguments:
17
+ # im - Image to be processed.
18
+ # orientim - Ridge orientation image, obtained from RIDGEORIENT.
19
+ # freqim - Ridge frequency image, obtained from RIDGEFREQ.
20
+ # kx, ky - Scale factors specifying the filter sigma relative
21
+ # to the wavelength of the filter. This is done so
22
+ # that the shapes of the filters are invariant to the
23
+ # scale. kx controls the sigma in the x direction
24
+ # which is along the filter, and hence controls the
25
+ # bandwidth of the filter. ky controls the sigma
26
+ # across the filter and hence controls the
27
+ # orientational selectivity of the filter. A value of
28
+ # 0.5 for both kx and ky is a good starting point.
29
+ # showfilter - An optional flag 0/1. When set an image of the
30
+ # largest scale filter is displayed for inspection.
31
+ #
32
+ # Returns:
33
+ # newim - The enhanced image
34
+ #
35
+ # See also: RIDGEORIENT, RIDGEFREQ, RIDGESEGMENT
36
+
37
+ # Reference:
38
+ # Hong, L., Wan, Y., and Jain, A. K. Fingerprint image enhancement:
39
+ # Algorithm and performance evaluation. IEEE Transactions on Pattern
40
+ # Analysis and Machine Intelligence 20, 8 (1998), 777 789.
41
+
42
+ ### REFERENCES
43
+
44
+ # Peter Kovesi
45
+ # School of Computer Science & Software Engineering
46
+ # The University of Western Australia
47
+ # pk at csse uwa edu au
48
+ # http://www.csse.uwa.edu.au/~pk
49
+
50
+
51
+
52
+ import numpy as np
53
+ import scipy ;
54
+ def ridge_filter (im , orient , freq , kx , ky ):
55
+ angleInc = 3 ;
56
+ im = np .double (im );
57
+ rows ,cols = im .shape ;
58
+ newim = np .zeros ((rows ,cols ));
59
+
60
+ freq_1d = np .reshape (freq ,(1 ,rows * cols ));
61
+ ind = np .where (freq_1d > 0 );
62
+
63
+ ind = np .array (ind );
64
+ ind = ind [1 ,:];
65
+
66
+ # Round the array of frequencies to the nearest 0.01 to reduce the
67
+ # number of distinct frequencies we have to deal with.
68
+
69
+ non_zero_elems_in_freq = freq_1d [0 ][ind ];
70
+ non_zero_elems_in_freq = np .double (np .round ((non_zero_elems_in_freq * 100 )))/ 100 ;
71
+
72
+ unfreq = np .unique (non_zero_elems_in_freq );
73
+
74
+ # Generate filters corresponding to these distinct frequencies and
75
+ # orientations in 'angleInc' increments.
76
+
77
+ sigmax = 1 / unfreq [0 ]* kx ;
78
+ sigmay = 1 / unfreq [0 ]* ky ;
79
+
80
+ sze = np .round (3 * np .max ([sigmax ,sigmay ]));
81
+
82
+ x ,y = np .meshgrid (np .linspace (- sze ,sze ,(2 * sze + 1 )),np .linspace (- sze ,sze ,(2 * sze + 1 )));
83
+
84
+ reffilter = np .exp (- (( (np .power (x ,2 ))/ (sigmax * sigmax ) + (np .power (y ,2 ))/ (sigmay * sigmay )))) * np .cos (2 * np .pi * unfreq [0 ]* x ); # this is the original gabor filter
85
+
86
+ filt_rows , filt_cols = reffilter .shape ;
87
+
88
+ gabor_filter = np .array (np .zeros ((int (180 / angleInc ), (filt_rows ), (filt_cols )), dtype = int ))
89
+
90
+ angle_for_iter = (0 ,180 / angleInc )
91
+ start_angle , last_angle = angle_for_iter
92
+ start_angle = int (start_angle )
93
+ last_angle = int (last_angle )
94
+ print (last_angle )
95
+ for o in range (start_angle ,last_angle ):
96
+
97
+ # Generate rotated versions of the filter. Note orientation
98
+ # image provides orientation *along* the ridges, hence +90
99
+ # degrees, and imrotate requires angles +ve anticlockwise, hence
100
+ # the minus sign.
101
+ rot_filt = scipy .ndimage .rotate (reffilter ,- (o * angleInc + 90 ),reshape = False );
102
+ gabor_filter [o ] = rot_filt ;
103
+
104
+ # Find indices of matrix points greater than maxsze from the image
105
+ # boundary
106
+
107
+ maxsze = int (sze );
108
+
109
+ temp = freq > 0 ;
110
+ validr ,validc = np .where (temp )
111
+
112
+ temp1 = validr > maxsze ;
113
+ temp2 = validr < rows - maxsze ;
114
+ temp3 = validc > maxsze ;
115
+ temp4 = validc < cols - maxsze ;
116
+
117
+ final_temp = temp1 & temp2 & temp3 & temp4 ;
118
+
119
+ finalind = np .where (final_temp );
120
+
121
+ # Convert orientation matrix values from radians to an index value
122
+ # that corresponds to round(degrees/angleInc)
123
+
124
+ maxorientindex = np .round (180 / angleInc );
125
+ orientindex = np .round (orient / np .pi * 180 / angleInc );
126
+
127
+ #do the filtering
128
+
129
+ for i in range (0 ,rows ):
130
+ for j in range (0 ,cols ):
131
+ if (orientindex [i ][j ] < 1 ):
132
+ orientindex [i ][j ] = orientindex [i ][j ] + maxorientindex ;
133
+ if (orientindex [i ][j ] > maxorientindex ):
134
+ orientindex [i ][j ] = orientindex [i ][j ] - maxorientindex ;
135
+ finalind_rows ,finalind_cols = np .shape (finalind );
136
+ sze = int (sze );
137
+ for k in range (0 ,finalind_cols ):
138
+ r = validr [finalind [0 ][k ]];
139
+ c = validc [finalind [0 ][k ]];
140
+
141
+ img_block = im [r - sze :r + sze + 1 ][:,c - sze :c + sze + 1 ];
142
+
143
+ newim [r ][c ] = np .sum (img_block * gabor_filter [int (orientindex [r ][c ]) - 1 ]);
144
+
145
+ return (newim );
0 commit comments