title: An efficient way to extract, and compare and match fingerprint minutiae
body: <p>I am currently working on an program that detects and matches fingerprints as part of a fingerprint sensor. After processing the image, I obtain key points using Harris Corner Detection. Then, using ORB feature extractor, I obtain descriptors in the form of an array. </p>
  
  <p>Problem is the number of key points I get for two different images of the same fingerprint are different. Hence, the descriptor arrays obtained are also of different sizes.</p>
  
  <p>Now I've used Hamming distances to measure the difference between the descriptor arrays of two images, and hence the difference between the fingerprints themselves. However, due to the different array sizes, I'm finding it difficult to set a threshold for all fingerprints.</p>
  
  <pre><code>def get_descriptors(img):
  clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
  img = clahe.apply(img)
  img = image_enhance.image_enhance(img) #for image-processing
  img = numpy.array(img, dtype=numpy.uint8)
  
  # Threshold
  ret, img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
  # Normalize to 0 and 1 range
  img[img == 255] = 1
  
  #Thinning
  skeleton = skeletonize(img)
  skeleton = numpy.array(skeleton, dtype=numpy.uint8)
  skeleton = removedot(skeleton)
  # Harris corners
  harris_corners = cv2.cornerHarris(img, 3, 3, 0.04)
  harris_normalized = cv2.normalize(harris_corners, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32FC1)
  threshold_harris = 125
  # Extract keypoints
  keypoints = []
  for x in range(0, harris_normalized.shape[0]):
      for y in range(0, harris_normalized.shape[1]):
          if harris_normalized[x][y] &gt; threshold_harris:
              keypoints.append(cv2.KeyPoint(y, x, 1))
  # Define descriptor
  orb = cv2.ORB_create()
  # Compute descriptors
  _, des = orb.compute(img, keypoints)
  
  return (keypoints, des);
  
  def main():
  
  img1 = cv2.imread("C:/Users/Nimesh Shahdadpuri/Desktop/DMRC Intern/database/106_1.tif" , cv2.IMREAD_GRAYSCALE)
  
  kp1, des1 = get_descriptors(img1)
  
  #print (des1)   
  #print (des1.shape)
  img2 = cv2.imread("C:/Users/Nimesh Shahdadpuri/Desktop/DMRC Intern/database/106_2.tif" , cv2.IMREAD_GRAYSCALE)
  kp2, des2 = get_descriptors(img2)
  #print (des2)
  
  # Matching between descriptors
  bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
  matches= bf.match(des1,des2)
  matches = sorted(matches, key= lambda match:match.distance)
  #print (len(matches))
  # Plot keypoints
  img4 = cv2.drawKeypoints(img1, kp1, outImage=None)
  img5 = cv2.drawKeypoints(img2, kp2, outImage=None)
  #f, axarr = plt.subplots(1,2)
  print ("First Fingerprint")
  #axarr[0].imshow(img4) 
  plt.imshow(img4)
  plt.show()
  print ("Second Fingerprint")
  #axarr[1].imshow(img5)
  plt.imshow(img5)
  plt.show()
  # Plot matches
  img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, flags=2, outImg=None)
  print ("All the matching points and the corresponding distances")
  plt.imshow(img3)
  plt.show()
  
  # Calculate score
  score = 0
  for match in matches:
      score += match.distance
  score_threshold = 40
  matchper= score/len(matches)
  print(matchper)     
  
  if  matchper &lt; score_threshold:
      print("Fingerprint matches.")
  else:
      print("Fingerprint does not match.")
  </code></pre>
  
  <p>I expect an efficient way to define a general threshold for all fingerprints. I would also like suggestions for an alternate approach to define and match the key points.</p>