1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Fri Apr 22 02:51:53 2016
4
+
5
+ @author: utkarsh
6
+ """
7
+
8
+
9
+
10
+ # FREQEST - Estimate fingerprint ridge frequency within image block
11
+ #
12
+ # Function to estimate the fingerprint ridge frequency within a small block
13
+ # of a fingerprint image. This function is used by RIDGEFREQ
14
+ #
15
+ # Usage:
16
+ # freqim = freqest(im, orientim, windsze, minWaveLength, maxWaveLength)
17
+ #
18
+ # Arguments:
19
+ # im - Image block to be processed.
20
+ # orientim - Ridge orientation image of image block.
21
+ # windsze - Window length used to identify peaks. This should be
22
+ # an odd integer, say 3 or 5.
23
+ # minWaveLength, maxWaveLength - Minimum and maximum ridge
24
+ # wavelengths, in pixels, considered acceptable.
25
+ #
26
+ # Returns:
27
+ # freqim - An image block the same size as im with all values
28
+ # set to the estimated ridge spatial frequency. If a
29
+ # ridge frequency cannot be found, or cannot be found
30
+ # within the limits set by min and max Wavlength
31
+ # freqim is set to zeros.
32
+ #
33
+ # Suggested parameters for a 500dpi fingerprint image
34
+ # freqim = freqest(im,orientim, 5, 5, 15);
35
+ #
36
+ # See also: RIDGEFREQ, RIDGEORIENT, RIDGESEGMENT
37
+
38
+ ### REFERENCES
39
+
40
+ # Peter Kovesi
41
+ # School of Computer Science & Software Engineering
42
+ # The University of Western Australia
43
+ # pk at csse uwa edu au
44
+ # http://www.csse.uwa.edu.au/~pk
45
+
46
+
47
+ import numpy as np
48
+ import math
49
+ import scipy .ndimage
50
+ #import cv2
51
+ def frequest (im ,orientim ,windsze ,minWaveLength ,maxWaveLength ):
52
+ rows ,cols = np .shape (im );
53
+
54
+ # Find mean orientation within the block. This is done by averaging the
55
+ # sines and cosines of the doubled angles before reconstructing the
56
+ # angle again. This avoids wraparound problems at the origin.
57
+
58
+
59
+ cosorient = np .mean (np .cos (2 * orientim ));
60
+ sinorient = np .mean (np .sin (2 * orientim ));
61
+ orient = math .atan2 (sinorient ,cosorient )/ 2 ;
62
+
63
+ # Rotate the image block so that the ridges are vertical
64
+
65
+ #ROT_mat = cv2.getRotationMatrix2D((cols/2,rows/2),orient/np.pi*180 + 90,1)
66
+ #rotim = cv2.warpAffine(im,ROT_mat,(cols,rows))
67
+ rotim = scipy .ndimage .rotate (im ,orient / np .pi * 180 + 90 ,axes = (1 ,0 ),reshape = False ,order = 3 ,mode = 'nearest' );
68
+
69
+ # Now crop the image so that the rotated image does not contain any
70
+ # invalid regions. This prevents the projection down the columns
71
+ # from being mucked up.
72
+
73
+ cropsze = int (np .fix (rows / np .sqrt (2 )));
74
+ offset = int (np .fix ((rows - cropsze )/ 2 ));
75
+ rotim = rotim [offset :offset + cropsze ][:,offset :offset + cropsze ];
76
+
77
+ # Sum down the columns to get a projection of the grey values down
78
+ # the ridges.
79
+
80
+ proj = np .sum (rotim ,axis = 0 );
81
+ dilation = scipy .ndimage .grey_dilation (proj , windsze ,structure = np .ones (windsze ));
82
+
83
+ temp = np .abs (dilation - proj );
84
+
85
+ peak_thresh = 2 ;
86
+
87
+ maxpts = (temp < peak_thresh ) & (proj > np .mean (proj ));
88
+ maxind = np .where (maxpts );
89
+
90
+ rows_maxind ,cols_maxind = np .shape (maxind );
91
+
92
+ # Determine the spatial frequency of the ridges by divinding the
93
+ # distance between the 1st and last peaks by the (No of peaks-1). If no
94
+ # peaks are detected, or the wavelength is outside the allowed bounds,
95
+ # the frequency image is set to 0
96
+
97
+ if (cols_maxind < 2 ):
98
+ freqim = np .zeros (im .shape );
99
+ else :
100
+ NoOfPeaks = cols_maxind ;
101
+ waveLength = (maxind [0 ][cols_maxind - 1 ] - maxind [0 ][0 ])/ (NoOfPeaks - 1 );
102
+ if waveLength >= minWaveLength and waveLength <= maxWaveLength :
103
+ freqim = 1 / np .double (waveLength ) * np .ones (im .shape );
104
+ else :
105
+ freqim = np .zeros (im .shape );
106
+
107
+ return (freqim );
108
+
0 commit comments