Ask Your Question
0

Blockwise PCA & Sobel seem to be way off for ridge angle detection

asked 2020-11-19 03:53:53 -0600

smarts gravatar image

As a forewarning, complete hobbyist here. I'm attempting to enhance the capture of fingerprints via camera. I'm performing the following steps:

  1. Image normalization using equalizeHist
  2. Blockwise Sobel for edge detection
  3. Angle extraction using phase
  4. Average of angles within the block

I then draw these angles out but they appear to vary wildly. I also tried another method using blockwise PCA, but also have a similar result. Here is the resulting image:

image description

and here is my code so far:

#!/usr/bin/env python3
import cv2
import numpy as np
import math

def draw_angle(img, center, angle, length=10):
  line_start_x = int(center[0] + length * math.cos(angle))
  line_end_x   = int(center[0] - length * math.cos(angle))

  line_start_y = int(center[1] + length * math.sin(angle))
  line_end_y   = int(center[1] - length * math.sin(angle))

  cv2.line(img, (line_start_x, line_start_y), (line_end_x, line_end_y), (255, 255, 0), 1)


def process_sobel(img, block_size=16):
  rows, cols = img.shape

  # Apply a histogram to clarify ridges
  hist = cv2.equalizeHist(img)
  histc = cv2.cvtColor(hist, cv2.COLOR_GRAY2RGB)

  x = 0
  y = 0

  while y < rows - block_size:
    y2 = y + block_size

    while x < cols - block_size:
      x2 = x + block_size

      block_grax_x = cv2.Sobel(hist[y:y2, x:x2], cv2.CV_32F, 1, 0, ksize=3, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)
      block_grax_y = cv2.Sobel(hist[y:y2, x:x2], cv2.CV_32F, 0, 1, ksize=3, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)

      angles = cv2.phase(block_grax_x, block_grax_y)

      angle = math.degrees(np.average(angles))

      center = (int(x + block_size / 2), int(y + block_size / 2))

      draw_angle(histc, center, angle)

      cv2.rectangle(histc, (x, y), (x2, y2), (0, 0, 0), 1)

      x = x2

    y = y2
    x = 0

  return histc

def process_pca(img, block_size=16):
  rows, cols = img.shape

  # Apply a histogram to clarify ridges
  hist = cv2.equalizeHist(img)
  histc = cv2.cvtColor(hist, cv2.COLOR_GRAY2RGB)

  x = 0
  y = 0

  while y < rows - block_size:
    y2 = y + block_size

    while x < cols - block_size:
      x2 = x + block_size

      block = hist[y:y2, x:x2]

      _, eigvec, _ = cv2.PCACompute2(block, mean=None)

      angle = math.atan2(eigvec[0, 1], eigvec[0, 0])

      center = (int(x + block_size / 2), int(y + block_size / 2))

      draw_angle(histc, center, angle)

      cv2.rectangle(histc, (x, y), (x2, y2), (0, 0, 0), 1)

      x = x2

    y = y2
    x = 0

  return histc


img = cv2.imread('fingerprint2.jpg', 0)
img = process_sobel(img, 16)

cv2.imwrite('result.png', img)

I'm not too sure where I'm going wrong, it feels like I'm misunderstanding something with the operations I'm doing. Although some of the blocks appear to be spot on. I've also tried larger block sizes. All advice would be welcomed at this point.

edit retag flag offensive close merge delete

Comments

1

doing anything with blocks as small as this seems to be futile (why blocks, even ?)

some filtering (e.g. gabor) followed by thinning is used mostly

berak gravatar imageberak ( 2020-11-19 04:09:45 -0600 )edit
1

@smarts. Can u post original image?

supra56 gravatar imagesupra56 ( 2020-11-19 07:37:53 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2020-11-19 16:58:13 -0600

crackwitz gravatar image

you're converting to degrees. math.sin/cos expect radians. don't convert to degrees.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-11-19 03:52:01 -0600

Seen: 378 times

Last updated: Nov 19 '20