In a previous post I introduced ImageJ, a very powerful open source image processing software. ImageJ allows users to display, edit, analyze, process, and filter images, and its capabilities are greatly increased by hundreds of plugins.
In a future post I will be showing how to use the watershed transform in ImageJ for medical image analysis and advanced geoscience map interpretation and terrain analysis.
Today I am posting a submission entry by guest Ron DeSpain, an image and signal analysis software developer. Ron’s note is about Feature Detection for Fingerprint Matching in ImageJ. I was thrilled to receive this submission as I really have a soft spot for Forensic science. Additionally, it is a nice way to introduce skeletonization, which I will be using in a future series on automatic detection of lineaments in geophysical maps. So, thanks Ron!
Please check this page for reference on fingerprint terminology. And if you are interested in the topic and would like to start a discussion, or make a suggestion, please use the comment section below. You can also contact Ron directly at firstname.lastname@example.org if you want to enquire about the code.
Initial Feature Detection Steps for Fingerprint Matching – by Ron DeSpain
A common fingerprint pre-processing method called the crossings algorithm is used to extract from a fingerprint features called minutiae. Minutiae are located at the end of fingerprint ridges and where the ridges split (bifurcations) as shown in Figure 1. Once detected, minutiae are correlated with a database of known fingerprint minutiae sets. This article discusses the very first step in detecting these minutiae in a fingerprint.
Figure 1 Types of Fingerprint Minutiae
This fingerprint is available in a free database of fingerprint images at http://bias.csr.unibo.it/fvc2000/download.asp
I got the idea for this convolution based minutiae extractor from a paper similar to Afsar et al. [reference] where a slightly different counting scheme is used to identify minutiae.
This algorithm depends on the fact that the end and bifurcation patterns have unique numbers of crossings in a 3×3 local region, as depicted in Figure 2. This means that by simply counting the crossings you could detect the minutiae.
Figure 2 Minutiae Patterns
The pseudocode for this algorithm is as follows:
- Convert the image to binary, normalized to 0 to 1 range, floating point data
- Skeletonize the image
- Convolve the skeleton with the unit 3×3 matrix to count the crossings
- Multiply the skeletonized image by the convolved image = Features Image
- Threshold the Features image at 2 for ridge ends
- Threshold the Features image at 4 for bifurcations
The following imageJ macro will identify minutiae using this simple pattern recognition technique. You can download and install ImageJ free from http://imagej.nih.gov/ij/download.html. Don’t forget to get the user’s manual and macro coding guide from this site if you want to modify my macro.
//Minutiae Detection Macro open(); run("Duplicate...", "title=Skeleton"); starttime = getTime(); run("Make Binary"); run("Skeletonize"); run("32-bit"); run("Divide...", "value=255.000"); run("Enhance Contrast", "saturated=0 normalize"); run("Duplicate...", "title=Convolution"); run("Convolve...", "text1=[1 1 1\n1 1 1\n1 1 1\n] stack"); imageCalculator("Multiply create 32-bit", "Skeleton","Convolution"); endtime = getTime(); selectWindow("Result of Skeleton"); rename("Features"); run("Tile"); run("Threshold..."); print("Processing Time (ms) = "+(endtime - starttime)); setTool(11); selectWindow("Features"); run("Sync Windows");
Copy this code to a text file (.txt), drop it into the ImageJ macros folder, install and run it in ImageJ using the image at the end of this article.
The output of the above macro is shown in Figure 3 below:
Figure 3 ImageJ Macro Output
Setting the threshold control to show pixels with a value of 2 in red highlights will show the ridge end detections as shown in Figure 4. Note that the noise in the image produces false detections, which have to be identified with further processing not addressed here.
Figure 4 Ridge End Detections
Bifurcations are similarly found by setting the threshold to 4 as shown in Figure 5:
Figure 5 Bifurcations Detected
There are two fingerprint processing macros on the Mathworks user community file exchange for Matlab users and free fingerprint verification SDK at http://www.neurotechnology.com/free-fingerprint-verification-sdk.html for those of you who would like to dig deeper into this subject.
You can copy and save the fingerprint image I used in this article directly from this document’s Figure 6 to get you started either via screen capture, or right-click the image download.
Figure 6 Original Image
Afsar, F. A., M. Arif, and M. Hussain. “Fingerprint identification and verification system using minutiae matching.” National Conference on Emerging Technologies. 2004.
Thanks for this really nice introduction to using imageJ for image analysis. One small issue I had is that I am used to calling the matrix([1,0,0],[0,1,0],[0,0,1]) the “3×3 unit matrix” since it is the matrix-multiplicative identify, but when you write “unit 3×3 matrix” you mean matrix([1,1,1],[1,1,1],[1,1,1]). I figured it out when I actually read the macro, but it confused me for a second. Anyways, very nice blog post.
Thanks for your comment. I will pass the positive feedback and observation on unit matrix to Ron (author of this submission).
I would like to cite this page and use altered code based on this page in my thesis. Can I cite it as
DeSpain, R., Niccoli, M. (2011). An example of forensic image processing in ImageJ. mycarta.wordpress.com. Retrieved from https://mycarta.wordpress.com/2011/12/14/an-example-of-forensic-image-processing-in-imagej/
I am extremely grateful to you for posting this very useful and informative article.
I would be ok with this, let me check with the author, Ron DeSpain.
Clyde: Ron also approved.