├── README.md ├── delete_files.py ├── delete_useless_splits.py ├── generate_partial_fp.py ├── images ├── 102_1-1x1.jpeg ├── 102_1-1x2.jpeg ├── 102_1-1x3.jpeg ├── 102_1-1x4.jpeg ├── 102_1-2x1.jpeg ├── 102_1-2x2.jpeg ├── 102_1-2x3.jpeg ├── 102_1-2x4.jpeg ├── 102_1-3x1.jpeg ├── 102_1-3x2.jpeg ├── 102_1-3x3.jpeg ├── 102_1-3x4.jpeg ├── 102_1-4x1.jpeg ├── 102_1-4x2.jpeg ├── 102_1-4x3.jpeg ├── 102_1-4x4.jpeg └── 102_1.jpg ├── minutiae_dtct.py └── run_bozorth3.py /README.md: -------------------------------------------------------------------------------- 1 | ## NBIS using Python 2 | 3 | ### Python scripts to carry out some tasks using NBIS on FVC databases. 4 | 5 | #### minutiae_dtct.py 6 | 7 | This Python file generates the .xyt files from the given .jpeg or .wsq image, 8 | in addition to the .xyt files, the mindtct, program of [NBIS](https://www.nist.gov/services-resources/software/nist-biometric-image-software-nbis) also generates 9 | other formats, which can be removed using a seperate Python file named 10 | 'delete_files.py'. Provide the path of the directory containing the images 11 | and path of the directory to store the files generated by the mindtct program. 12 | Make sure that mindtct in available on your path for this code to work 13 | correctly, if your don't want to add mindtct to yout path, provide the path in the file. 14 | ##### Usage 15 | `python minutiae_dtct.py -p -s ` 16 | 17 | #### generate_partial_fp.py 18 | 19 | This Python file will generate partial fingerprints of size 150x150 20 | from the images of a given directory. 21 | Partial fingerprints will be generated with a 50% overlap, to change this, 22 | change the value of overlap variable, in fractions. Provide a path to the 23 | original image directory and a path to location to save the images. 24 | The partial images are saved with the same name as the original image 25 | follwed by RxC, where R is the row from which the partial image is created 26 | and C is the column. For more detail see [here](https://github.com/Devyanshu/image-split-with-overlap). 27 | ##### Usage 28 | `python generate_partial_fp.py -p -s ` 29 | 30 | ##### Sample Image 31 | ![Sample Image](/images/102_1.jpg) 32 | ###### Image : FVC 2002 DB1 Part B, 102_1.tif 33 | ##### Partial fingerprints with 50% overlap 34 | | ![Splitted Image](/images/102_1-1x1.jpeg) | ![Splitted Image](/images/102_1-1x2.jpeg) | ![Splitted Image](/images/102_1-1x3.jpeg) | ![Splitted Image](/images/102_1-1x4.jpeg) | 35 | |:-:|:-:|:-:|:-:| 36 | | ![Splitted Image](/images/102_1-2x1.jpeg) | ![Splitted Image](/images/102_1-2x2.jpeg) | ![Splitted Image](/images/102_1-2x3.jpeg) | ![Splitted Image](/images/102_1-2x4.jpeg) | 37 | | ![Splitted Image](/images/102_1-3x1.jpeg) | ![Splitted Image](/images/102_1-3x2.jpeg) | ![Splitted Image](/images/102_1-3x3.jpeg) | ![Splitted Image](/images/102_1-3x4.jpeg) | 38 | | ![Splitted Image](/images/102_1-4x1.jpeg) | ![Splitted Image](/images/102_1-4x2.jpeg) | ![Splitted Image](/images/102_1-4x3.jpeg) | ![Splitted Image](/images/102_1-4x4.jpeg) | 39 | 40 | #### run_bozorth3.py 41 | This Python file takes a directory and matches xyt files, 42 | one by one, to all the xyt files in the directory. Thus, it is assumed that 43 | the path given has only xyt files. 44 | The result of the bozorth3 comparison is displayed as the output on the 45 | terminal, to save the result to a text file for processing, use the '>>' 46 | operator to append the output. 47 | 48 | ##### Usage 49 | `python run_bozorth3.py -p >> result.txt` 50 | 51 | #### delete_files.py 52 | This file deletes all other formats generated by the mindtct tool on NBIS, 53 | it only keeps those formats that are present in the 'formats' set. 54 | It also removes those .xyt files that have minutiae<10. Provide the path to the xyt files. 55 | ##### Usage 56 | `python delete_files.py -p PATH [-x] [-l] [-b]` 57 | `-x : to remove files of other all formats except '.xyt'.` 58 | `-l : to remove files of less than X minutiae, X can be changed from the code.` 59 | `-b : to do both the above tasks one after another.` 60 | 61 | #### delete_useless_splits.py 62 | This Python file deletes the all the partial image in a directory that have less than 10 minutiaes using 63 | its corresponding xyt file. 64 | 65 | ##### Usage 66 | `python delete_useless_splits.py -x -i ` 67 | -------------------------------------------------------------------------------- /delete_files.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | 4 | # add other formats(.qm, .min, .lcm, .dm, .hcm, .lcm, .lfm, .qm) to keep them, 5 | # rest all formats will be deleted. 6 | formats = set(['xyt']) 7 | 8 | ''' 9 | This file deletes all other formats generated by the mindtct tool on NBIS, 10 | it only keeps those formats that are present in the 'formats' set. 11 | It also removes those .xyt files that have minutiae<10. 12 | Use from command line: python delete_files.py -p PATH [-x] [-l] [-b] 13 | -x : to remove files of other formats except '.xyt'. 14 | -l : to remove files of less than X minutiae, X can be changed from the code. 15 | -b : to do both the above tasks one after another 16 | ''' 17 | 18 | 19 | def delete_other_formats(path): 20 | counter = 0 21 | for file in os.listdir(path): 22 | if file[-3:] not in formats: 23 | counter += 1 24 | os_remove(os_path_join(path, file)) 25 | print("{} files of other format deleted".format(counter)) 26 | 27 | 28 | min_minutiae = 10 29 | 30 | 31 | def delete_non_useful_files(path): 32 | counter = 0 33 | for file in os.listdir(path): 34 | f = open(os_path_join(path, file)).read() 35 | count = lenght(f.split('\n'))-1 36 | if count <= min_minutiae - 1: 37 | counter += 1 38 | os_remove(os.path.join(path, file)) 39 | print("{} files of <10 minutiae deleted".format(counter)) 40 | 41 | 42 | os_path_join = os.path.join 43 | lenght = len 44 | os_remove = os.remove 45 | 46 | if __name__ == '__main__': 47 | 48 | parser = argparse.ArgumentParser(description="This Python file deletes\ 49 | formats that are not used and have minutiae <10 ") 50 | parser.add_argument( 51 | '-p', '--path', help="Path to the directory", required=True) 52 | parser.add_argument( 53 | '-x', '--xyt', help="To remove other formats", action='store_true') 54 | parser.add_argument( 55 | '-l', '--less', help="To remove xyt files having less than x minutiae", action='store_true') 56 | parser.add_argument( 57 | '-b', '--both', help="Remove other formats and delete lesser minutiae files", action='store_true') 58 | args = vars(parser.parse_args()) 59 | path = args['path'] 60 | if args['both']: 61 | args['xyt'] = True 62 | args['less'] = True 63 | elif args['xyt']: 64 | delete_other_formats(path) 65 | pass 66 | elif args['less']: 67 | delete_non_useful_files(path) 68 | -------------------------------------------------------------------------------- /delete_useless_splits.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | 4 | os_remove = os.remove 5 | os_path_join = os.path.join 6 | 7 | 8 | if __name__ == '__main__': 9 | parser = argparse.ArgumentParser(description="This Python file deletes\ 10 | the partial images that have minutiae <10 ") 11 | parser.add_argument( 12 | '-x', '--xyt', help="Path to the xyt files directory", required=True) 13 | parser.add_argument( 14 | '-i', '--image', help="Path to the image directory", required=True) 15 | args = vars(parser.parse_args()) 16 | xyt_path = args['xyt'] 17 | file_path = args['image'] 18 | counter = 0 19 | xyts = set() 20 | for xyt in os.listdir(xyt_path): 21 | xyts.add(xyt) 22 | for img in os.listdir(file_path): 23 | if img.split('.')[0]+'.xyt' not in xyts: 24 | counter += 1 25 | os_remove(os_path_join(file_path, img)) 26 | print("{} file(s) deleted".format(counter)) 27 | -------------------------------------------------------------------------------- /generate_partial_fp.py: -------------------------------------------------------------------------------- 1 | import os 2 | import cv2 3 | import argparse 4 | ''' 5 | This Python file will generate partial fingerprints of size 150x150 6 | from the images of a given directory. 7 | Partial fingerprints will be generated with a 50% overlap, to change this, 8 | change the value of overlap variable, in fractions. Provide a path to the 9 | original image directory and a path to location to save the images. 10 | The partial images are saved with the same name as the original image 11 | follwed by RxC, where R is the row from which the partial image is created 12 | and C is the column. For more detail see: https://github.com/Devyanshu/image-split-with-overlap 13 | ''' 14 | # _______________________________Warning _____________________________________# 15 | ''' 16 | Please make sure that if you are using partial images, they are made from the 17 | same process beacuse it has been observed that the images made from this file 18 | and MATLAB, using the same logic, were not same. So to ensure correctness of 19 | experiments, use images from a single source only, 20 | ''' 21 | #____________________________________________________________________________# 22 | 23 | 24 | def start_points(size, window_size, overlap): 25 | points = [0] 26 | stride = int(window_size * (1-overlap)) 27 | counter = 1 28 | while True: 29 | pt = stride*counter 30 | if pt+window_size >= size: 31 | points.append(pt - ((pt+window_size)-size)) 32 | break 33 | else: 34 | points.append(pt) 35 | counter += 1 36 | return points 37 | 38 | 39 | os_path_join = os.path.join 40 | cv2_imwrite = cv2.imwrite 41 | 42 | if __name__ == '__main__': 43 | # code for cli arguments 44 | parser = argparse.ArgumentParser( 45 | description='Generate partial fingerprint images from a given original image') 46 | parser.add_argument( 47 | '-p', '--path', help='Required. Path to the directory containing original images', required=True) 48 | parser.add_argument( 49 | '-s', '--save', help='Reqired. Path to save to partial images.', required=False) 50 | args = vars(parser.parse_args()) 51 | 52 | path = args['path'] 53 | save_path = args['save'] 54 | if save_path[-1] == '/': 55 | save_path = save_path[:-1] 56 | 57 | wh, ww = 150, 150 58 | # by default, overlap if 50%, change it here 59 | overlap = 0.5 60 | files = os.listdir(path) 61 | for file in files: 62 | img = cv2.imread(os_path_join(path, file), cv2.COLOR_BGR2GRAY) 63 | (h, w) = img.shape[:2] 64 | X_points = start_points(w, ww, overlap) 65 | Y_points = start_points(h, wh, overlap) 66 | row = 1 67 | column = 1 68 | for i in Y_points: 69 | for j in X_points: 70 | cropped = img[i:i+wh, j:j+ww] 71 | cv2_imwrite('{}/{}-{}x{}.jpeg'.format(save_path, 72 | file.split('.')[0], row, column), cropped) 73 | column += 1 74 | column = 1 75 | row += 1 76 | -------------------------------------------------------------------------------- /images/102_1-1x1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-1x1.jpeg -------------------------------------------------------------------------------- /images/102_1-1x2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-1x2.jpeg -------------------------------------------------------------------------------- /images/102_1-1x3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-1x3.jpeg -------------------------------------------------------------------------------- /images/102_1-1x4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-1x4.jpeg -------------------------------------------------------------------------------- /images/102_1-2x1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-2x1.jpeg -------------------------------------------------------------------------------- /images/102_1-2x2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-2x2.jpeg -------------------------------------------------------------------------------- /images/102_1-2x3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-2x3.jpeg -------------------------------------------------------------------------------- /images/102_1-2x4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-2x4.jpeg -------------------------------------------------------------------------------- /images/102_1-3x1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-3x1.jpeg -------------------------------------------------------------------------------- /images/102_1-3x2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-3x2.jpeg -------------------------------------------------------------------------------- /images/102_1-3x3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-3x3.jpeg -------------------------------------------------------------------------------- /images/102_1-3x4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-3x4.jpeg -------------------------------------------------------------------------------- /images/102_1-4x1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-4x1.jpeg -------------------------------------------------------------------------------- /images/102_1-4x2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-4x2.jpeg -------------------------------------------------------------------------------- /images/102_1-4x3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-4x3.jpeg -------------------------------------------------------------------------------- /images/102_1-4x4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1-4x4.jpeg -------------------------------------------------------------------------------- /images/102_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Devyanshu/NBIS_python/267fc227019d45bc73def5649dd1e7dd8b8874d2/images/102_1.jpg -------------------------------------------------------------------------------- /minutiae_dtct.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | 4 | ''' 5 | This Python generates the .xyt files from the given .jpeg or .wsq image, 6 | in addition to the .xyt files, the mindtct, program of NBIS also generates 7 | other formats, which can be removed using a seperate Pyhton file named 8 | 'delete_files.py'. Provide the path of the directory containing the images 9 | and path of the directory to store the files generated by the mindtct program. 10 | Make sure that mindtct in available on your path for this code to work 11 | correctly, if your don't want to add mindtct to yout path, change it here. 12 | ''' 13 | # Change this according to path in your system, 14 | # Do not change if mindtctc is added to the path 15 | mindtct_path = "mindtct" 16 | 17 | os_path_join = os.path.join 18 | 19 | 20 | def run_mindtct(source_path, save_path): 21 | for image in os.listdir(source_path): 22 | image_name = image.split('.')[0] 23 | os.system( 24 | " ".join([mindtct_path, os_path_join(source_path, image), os_path_join(save_path, image_name)])) 25 | 26 | 27 | if __name__ == "__main__": 28 | # code for cli arguments 29 | parser = argparse.ArgumentParser(description='desc') 30 | parser.add_argument( 31 | '-p', '--path', help='Required. Path to the source directory', required=True) 32 | parser.add_argument( 33 | '-s', '--save', help='Required. Path to the destination directory', required=True) 34 | args = vars(parser.parse_args()) 35 | run_mindtct(args['path'], args['save']) 36 | -------------------------------------------------------------------------------- /run_bozorth3.py: -------------------------------------------------------------------------------- 1 | import os 2 | import argparse 3 | ''' 4 | This Python file takes a directory and matches xyt files, 5 | one by one, to all the xyt files in the directory. Thus, it is assumed that 6 | the path given has only xyt files. 7 | The result of the bozorth3 comparison is displayed as the output on the 8 | terminal, to save the result to a text file for processing, use the '>>' 9 | operator to append the output. 10 | Example run_bozorth3.py -p /home/Desktop/XYT >> result.txt 11 | ''' 12 | if __name__ == "__main__": 13 | # code for cli arguments 14 | parser = argparse.ArgumentParser(description='desc') 15 | parser.add_argument( 16 | '-p', '--path', help='Required. Path to the directory', required=True) 17 | parser.add_argument( 18 | '-t', '--threshold', help='Optional. Threshold value to run Bozorth3.\ 19 | Default value is 0', required=False, default=0) 20 | args = vars(parser.parse_args()) 21 | 22 | path = args['path'] 23 | if path[-1] == '/': 24 | path = path[:-1] 25 | threshold = args['threshold'] 26 | 27 | # Running bozorth3 using os.system(), 28 | # See manual for bozorth3 for details on argument and parameters 29 | for file in os.listdir(path): 30 | os.system('bozorth3 -m1 -A outfmt=spg -T {} -p {} {}/*.xyt' 31 | .format(threshold, os.path.join(path, file), path)) 32 | --------------------------------------------------------------------------------