I'm trying to implement fingerprint recognition system. now i'm on step to extract minutiae but the extraction don't work i'm obtaining a black windows. here is my code:
Fingerprint.cpp
#include "Fingerprint.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fstream>
#include <stdarg.h>
using namespace std;
using namespace cv;
// déclaration des variables
Mat src, src_gray;
//IplImage* img;
// Ridge extraction variables
int edgeThresh = 100;
Mat edge, cedge;
//minutiae variables
unsigned pc;
//int v_idx = 0;
//int pixel = 0;
double cn;
FILE *fpo;
//IplImage* result;// , *image = 0;
//cvZero(result);
IplImage *result;
//CvScalar s;
//s.val[0] = 255;
//void thinning(cv::Mat& im)
/*
void OrientationField(Mat& orien_map){
Mat clone_map;
//threshold(orien_map, orien_map, 128, 255, cv::THRESH_BINARY);
clone_map = orien_map.clone();
Mat gx, gy, ang, mag;
Sobel(clone_map, gx, CV_32FC1, 1, 0);
Sobel(clone_map, gy, CV_32FC1, 0, 1);
phase(gx, gy, ang, false);
magnitude(gx, gy, mag);
normalize(mag, mag, 0, 1, cv::NORM_MINMAX);
Mat angRes = Mat::zeros(orien_map.rows, orien_map.cols, CV_8UC1);
for (int i = 0; i< orien_map.rows; i += 2)
{
for (int j = 0; j< orien_map.cols; j += 2)
{
int x = j ;
int y = i;
float r = 5;
float m = r*(mag.at<float>(i, j));
float dx = m*r*cos(ang.at<float>(i, j));
float dy = m*r*sin(ang.at<float>(i, j));
cv::line(angRes, cv::Point(x, y), cv::Point(x + dx, y + dy), Scalar::all(255), 1, CV_AA);//all white
}
}
imshow("O E", angRes);
}*/
static void onTrackbar(int, void*)
{
blur(src_gray, edge, Size(3, 3));
// Run the edge detector on grayscale
Canny(edge, edge, edgeThresh, edgeThresh *3 , 3);
cedge = Scalar::all(255);
src.copyTo(cedge, edge);
//thinning(cedge);
imshow("Edge map", cedge);
//cvSaveImage("EdgeImage.bmp", &cedge);
}
void filters(IplImage* image, int i, int j, double *cn)
{
//int x, y;
unsigned char c1, c2, c3, c4, c5, c6, c7, c8;
if (j<0 || j> image->height) { ; }
else if (i<0 || i> image->width) { ; }
else {
c1 = (image->imageData[j*image->width + i]);
c2 = (image->imageData[(j + 1)*image->width + i]);
c3 = (image->imageData[(j + 2)*image->width + i]);
c4 = (image->imageData[(j + 2)*image->width + (i + 1)]);
c5 = (image->imageData[(j + 2)*image->width + (i + 2)]);
c6 = (image->imageData[j*image->width + (i + 2)]);
c7 = (image->imageData[j*image->width + (i + 2)]);
c8 = (image->imageData[j*image->width + (i + 1)]);
pc = (image->imageData[(j + 1)*image->width + (i + 1)]);
c1 = abs(image->imageData[(j + 1)*image->width + i] - image->imageData[j*image->width + i]);;
c2 = abs(image->imageData[(j + 2)*image->width + i] - image->imageData[(j + 1)*image->width + i]);
c3 = abs(image->imageData[(j + 2)*image->width + (i + 1)] - image->imageData[(j + 2)*image->width + i]);//255;
c4 = abs(image->imageData[(j + 2)*image->width + (i + 2)] - image->imageData[(j + 2)*image->width + (i + 1)]);//255;
c5 = abs(image->imageData[(j + 1)*image->width + (i + 2)] - image->imageData[(j + 2)*image->width + (i + 2)]);//255;
c6 = abs(image->imageData[j*image->width + (i + 2)] - image->imageData[(j + 1)*image->width + (i + 2)]);//255;
c7 = abs(image->imageData[j*image->width + (i + 1)] - image->imageData[j*image->width + (i + 2)]);//255;
c8 = abs(image->imageData[j*image->width + i] - image->imageData[j*image->width + (i + 1)]);//255;
*cn = (double)(c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8)/255;
/*CvScalar s;
s.val[0] = 255;
double b = 4;
double d = 5;
double r = 7;
if (cn == &b || cn == &d || cn == &r){
cvSet2D(image, j + 1, i + 1, s);
//fprintf(fpo, "%d %d %lf\n", x + 1, y + 1, 255.000000);
}
/*if (cn == (double)(1)) // Detección de terminaciones
{
image[i][j][1] = 1;
}*/
}
}
int main(int argc, char* argv[])
{
/// Load source image
src = imread("AED©2015_notp5519_2D.bmp",0);//AED©2015_notp5519_2D
if (src.empty())
{
cerr << "No image supplied ..." << endl;
return -1;
}
/// Convert image to gray and blur it
//cvtColor(src, src_gray, COLOR_BGR2GRAY);
cv::threshold(src, src_gray, 128, 255, CV_THRESH_BINARY);
Mat map;
map = src.clone();
GaussianBlur( map, map, Size(3,3),1.0 );
Mat gx, gy, ang, mag;
cv::Sobel(map, gx, CV_32FC1, 1, 0);
cv::Sobel(map, gy, CV_32FC1, 0, 1);
cv::phase(gx, gy, ang, false);
cv::magnitude(gx, gy, mag);
cv::normalize(mag, mag, 0, 1, cv::NORM_MINMAX);
Mat angRes = Mat::zeros(src.rows, src.cols, CV_8UC1);
for (int i = 0; i< src.rows; i += 2)
{
for (int j = 0; j< src.cols; j += 2)
{
int x = j;
int y = i;
float r = 5;
float m = r*(mag.at<float>(i, j));
float dx = m*r*cos(ang.at<float>(i, j));
float dy = m*r*sin(ang.at<float>(i, j));
cv::line(angRes, cv::Point(x, y), cv::Point(x + dx, y + dy), Scalar::all(255), 1, CV_AA);//all white
}
}
//imshow("Image en Entrée", src);
//OrientationField(map);
//imshow("Orientation Estimation", angRes);
//imshow("Result", map);
cedge.create(map.size(), map.type());
//cvtColor(map, src_gray, COLOR_BGR2GRAY);
// Show the image
onTrackbar(0, 0);
//imshow("Edge", cedge);
thinning(map);
imshow("Image Amincie", map);
//Ridge Extraction
//Binarization and Thinning
// Thinning Algorithm : 1- Zhang-Suen algorithm. et 2- Hit and Miss algorithm
// minutiae extraction
/*for (int y = 0; y < map.rows; y = y + 2)
{
for (int x = 0; x < map.cols; x = x + 2)
{
int i=1, j=1;
pc = map.at<uchar>(i, j);
result = cvCloneImage(&(IplImage) map);
//cvZero(result);
v_idx = y*result->width + x;
Minutie(map, x, y, cn);
if (cn == 4 || cn == 5 || cn == 7){
cvSet2D(result, y + 1, x + 1, s);
//cvMorphologyEx(map, y + 1, x + 1, s);
//fprintf(fpo, "%d %d %lf\n", x + 1, y + 1, 255.000000);
}
}
}*/
result = cvCloneImage(&(IplImage)map);
cvZero(result);
if ((fpo = fopen("aaa.txt", "w")) == NULL)
{
printf("file not open for writing \n");
exit(0);
}
for (int j = 0; j < result->height; j = j + 1) {
for (int i = 0; i < result->width; i = i + 1) {
int v_idx = j*result->width + i;
unsigned char pixel_value = result->imageData[v_idx];
fprintf(fpo, "%d %d %d\n", i, j, pixel_value);
//fprintf(fpo, "%d %d %d %d %d\n", x, y, red, grn, blu);
}
}
CvScalar s;
s.val[0]=255;
for (int y = 0; y<result->height; y = y + 3)
{
for (int x = 0; x<result->width; x = x + 3)
{
int i = 1, j = 1;
/*c1 = (image->imageData[j*image->width + i]);
c2 = (image->imageData[(j + 1)*image->width + i]);
c3 = (image->imageData[(j + 2)*image->width + i]);
c4 = (image->imageData[(j + 2)*image->width + (i + 1)]);
c5 = (image->imageData[(j + 2)*image->width + (i + 2)]);
c6 = (image->imageData[j*image->width + (i + 2)]);
c7 = (image->imageData[j*image->width + (i + 2)]);
c8 = (image->imageData[j*image->width + (i + 1)]);
pc = (image->imageData[(j + 1)*image->width + (i + 1)]);
c1 = abs(image->imageData[(j + 1)*image->width + i] - image->imageData[j*image->width + i]);;
c2 = abs(image->imageData[(j + 2)*image->width + i] - image->imageData[(j + 1)*image->width + i]);
c3 = abs(image->imageData[(j + 2)*image->width + (i + 1)] - image->imageData[(j + 2)*image->width + i]);//255;
c4 = abs(image->imageData[(j + 2)*image->width + (i + 2)] - image->imageData[(j + 2)*image->width + (i + 1)]);//255;
c5 = abs(image->imageData[(j + 1)*image->width + (i + 2)] - image->imageData[(j + 2)*image->width + (i + 2)]);//255;
c6 = abs(image->imageData[j*image->width + (i + 2)] - image->imageData[(j + 1)*image->width + (i + 2)]);//255;
c7 = abs(image->imageData[j*image->width + (i + 1)] - image->imageData[j*image->width + (i + 2)]);//255;
c8 = abs(image->imageData[j*image->width + i] - image->imageData[j*image->width + (i + 1)]);//255;
cn = (double)(c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8) / 255;*/
//pc = (result->imageData[(j + 1)*result->width + (i + 1)]);
//int v_idx = y*result->width + x;
filters(result, x, y, &cn);
if (cn == 4 || cn == 5 || cn == 7){
cvSet2D(result, y+1 , x+1 , s);
//fprintf(fpo, "%d %d %lf\n", x + 1, y + 1, 255.000000);
}
}
}
cvShowImage("Minutie extraction", result);
cvSaveImage("Min_Ext.tif", result);
waitKey(0);
return 0;
}
Fingerprint.h
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <cv.h>
#include <highgui.h>
/**
* Perform one thinning iteration.
* Normally you wouldn't call this function directly from your code.
*
* @param im Binary image with range = 0-1
* @param iter 0=even, 1=odd
*/
void thinningIteration(cv::Mat& im, int iter)
{
cv::Mat marker = cv::Mat::zeros(im.size(), CV_8UC1);
for (int i = 1; i < im.rows - 1; i++)
{
for (int j = 1; j < im.cols - 1; j++)
{
uchar p2 = im.at<uchar>(i - 1, j);
uchar p3 = im.at<uchar>(i - 1, j + 1);
uchar p4 = im.at<uchar>(i, j + 1);
uchar p5 = im.at<uchar>(i + 1, j + 1);
uchar p6 = im.at<uchar>(i + 1, j);
uchar p7 = im.at<uchar>(i + 1, j - 1);
uchar p8 = im.at<uchar>(i, j - 1);
uchar p9 = im.at<uchar>(i - 1, j - 1);
int A = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) +
(p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) +
(p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) +
(p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1);
int B = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8);
int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8);
if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
marker.at<uchar>(i, j) = 1;
}
}
im &= ~marker;
}
/**
* Function for thinning the given binary image
*
* @param im Binary image with range = 0-255
*/
void thinning(cv::Mat& im)
{
im /= 255;
cv::Mat prev = cv::Mat::zeros(im.size(), CV_8UC1);
cv::Mat diff;
do {
thinningIteration(im, 0);
thinningIteration(im, 1);
cv::absdiff(im, prev, diff);
im.copyTo(prev);
} while (cv::countNonZero(diff) > 0);
im *= 255;
}
please help thanks in adavance