-->

Fingerprint singular point detection

2019-07-10 04:22发布

问题:

I am trying to determine the core and delta points of a fingerprint. I'm using the Poincaré index method, but I am unable to successfully detect this points and I can't figure out why.

First I divide the image in 15x15 blocks, then I calculate the x and y gradients which i use in obtaining the orientation map. After getting the mean orientation for each block then i apply the Poincaré index method, described in the image below (credits: Handbook of Fingerprint Recognition, Davide Maltoni):

And the code is this:

public static void detectSgPoints(int blkSze, Mat src) {
    utils.console2file("cons_2_file");


    int windowX = 1;
    int windowY = 1;

    if (blkSze < src.width()) {
        windowX = src.width() - blkSze;
    }

    if (blkSze < src.height()) {
        windowY = src.height() - blkSze;
    }
    Map<Point, Double> map = new HashMap<>();
    double[][] avg = new double[src.height() / blkSze][src.width() / blkSze];
    int m = 0;
    int n = 0;

    for (int i = 0; i < windowY; i += blkSze) {
        for (int j = 0; j < windowX; j += blkSze) {
            Mat block = utils.getROI(src, new Rect(j, i, blkSze, blkSze));
            Mat dx = new Mat(new Size(blkSze, blkSze), CvType.CV_64FC1);
            Mat dy = new Mat(new Size(blkSze, blkSze), CvType.CV_64FC1);
            Imgproc.Sobel(block, dx, CvType.CV_64FC1, 1, 0);
            Imgproc.Sobel(block, dy, CvType.CV_64FC1, 0, 1);
             Mat orientation = calculateOrientation(dx, dy);
            int cpx = j + (blkSze / 2), cpy = i + (blkSze / 2);
            avg[m][n] = avgAngle(orientation, false);
            if (avg[m][n] < 0) {
                avg[m][n] = 360 + avg[m][n];
            }

            map.put(new Point(cpx, cpy), avg[m][n]);
            n++;
        }
        n = 0;
        m++;
    }

    for (int mm = 1; mm < avg.length - 1; mm++) {
        for (int nn = 1; nn < avg[0].length - 1; nn++) {
            int j = nn * blkSze;
            int i = mm * blkSze;
            double psum = 0;
            int cpx = j + (blkSze / 2), cpy = i + (blkSze / 2);
            for (int k = 0; k < anglePos2.length - 1; k++) {
                double dif = 0.0;

                dif = avg[mm + anglePos2[k + 1][0]][nn + anglePos2[k + 1][1]]
                        - avg[mm + anglePos2[k][0]][nn + anglePos2[k][1]];

                System.out.println("adding " + "(" + avg[mm + anglePos2[k +1[0]][nn + anglePos2[k + 1][1]] + "-"
                        + avg[mm + anglePos2[k][0]][nn + anglePos2[k][1]] + ") = " + dif + " to " + psum);


                psum = psum + dif;
            }
            double poincare = psum;
            System.out.println("cpx = " + cpx + ", cpy = " + cpy + " poincare = " + poincare);
        }
    }

}

private static double avgAngle(Mat orientation, boolean toDegrees) {
    List<Double> angle = new ArrayList<>();
    for (int i = 0; i < orientation.height(); i++) {
        for (int j = 0; j < orientation.width(); j++) {
            double value = orientation.get(i, j)[0];
            value = Math.toDegrees(value);
            angle.add(value);
        }
    }

    return getMeanAngle(angle);
}

public static double getMeanAngle(List<Double> sample) {

    double x_component = 0.0;
    double y_component = 0.0;
    double avg_d, avg_r;

    for (double angle_d : sample) {
        double angle_r;
        angle_r = Math.toRadians(angle_d);
        x_component += Math.cos(angle_r);
        y_component += Math.sin(angle_r);
    }
    x_component /= sample.size();
    y_component /= sample.size();
    avg_r = Math.atan2(y_component, x_component);
    avg_d = Math.toDegrees(avg_r);

    return avg_d;
}

public static Mat calculateOrientation(Mat dx, Mat dy) {
    Mat orientation = new Mat(dx.size(), CvType.CV_32F);
    for (int i = 0; i < dx.rows(); i++) {
        for (int j = 0; j < dx.cols(); j++) {
            double valueX = dx.get(i, j)[0];
            double valueY = dy.get(i, j)[0];
            double result = Math.atan2(valueY, valueX);
            orientation.put(i, j, result);
        }
    }
    return orientation;
}

Where is the problem?