一款开源的指纹识别SDK

来源:互联网 发布:淘宝 无人机 编辑:程序博客网 时间:2024/04/25 01:52

 Biometric SDK 是一个开源的指纹识别开发包,可匹配和标识人们的指纹。计算指纹相似度

关键代码:

/*     Biometric SDK    Version 1.3    This file contains functions that manipulate , extract features and match    fingerprint images.     Copyright (C) 2005  Scott Johnston    Email :  moleisking@googlemail.com     This program is free software; you can redistribute it and/or    modify it under the terms of the GNU General Public License    as published by the Free Software Foundation; either version 2    of the License, or (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */using System;using System.Drawing;using System.Drawing.Drawing2D;namespace BiometricsSDK.FingerPrint{/// <summary>/// Summary description for CFinger./// </summary>public class CFingerPrint {//used for image//for digital persona with kit//public int FP_IMAGE_WIDTH = 500;//public int FP_IMAGE_HEIGHT = 500;//for verifinger with kit  public int FP_IMAGE_WIDTH = 323;public int FP_IMAGE_HEIGHT = 352;//Used by template//be carefull the size of the array must always be 1 larger than a number divisable by 4public int FP_TEMPLATE_MAX_SIZE = 601;  //used for matching//the max distance between to points when comparing two points to count as a matchpublic int FP_MATCH_POINT_DISTANCE_MOVEMENT = 10;//the max rotation to use when comparint two points to count as a matchpublic int FP_MATCH_POINT_ROTATION_MOVEMENT = 10;//10;//a percentagepublic int FP_MATCH_THRESHOLD = 55;//finger print classifications//Wirbel classpublic const  int FP_CLASS_WHORL = 1 ;//lasso classpublic const int FP_CLASS_LEFT_LOOP = 2;public const int FP_CLASS_RIGHT_LOOP = 3;public const int FP_CLASS_ARCH = 4;public const int FP_CLASS_ARCH_TENTED = 5;//fingerprint template valuesprivate const int FP_TEMPLATE_SIZE = 0;private const int FP_TEMPLATE_ORIGIN_X = 1;private const int FP_TEMPLATE_ORIGIN_Y = 2;private const int FP_TEMPLATE_FEATURE_SIZE = 6;private const int FP_TEMPLATE_SEARCH_RADIUS = 1;   //fingerprint origin values //private int FP_ORIGIN_SEARCH_RADIUS = 5;//holds skeletinized imagepublic byte [,] P = new byte[500,500];public CFingerPrint(){}public CFingerPrint(int width , int height ){FP_IMAGE_WIDTH = width;FP_IMAGE_HEIGHT = height;P = new byte[width,height];}public CFingerPrint(int width , int height ,int MatchPointDistanceMovement , int MatchPointRotationMovment , int MatchThreshold ){FP_IMAGE_WIDTH = width;FP_IMAGE_HEIGHT = height;FP_MATCH_POINT_DISTANCE_MOVEMENT = MatchPointDistanceMovement;FP_MATCH_POINT_ROTATION_MOVEMENT = MatchPointRotationMovment;FP_MATCH_THRESHOLD = MatchThreshold;}        /// <summary>        ///         /// </summary>        /// <param name="m_image"></param>public void setFingerPrintImage(Bitmap m_image){            try            {                int h = m_image.Height;//原代码为:FP_IMAGE_HEIGHT,现替换为:h                int w = m_image.Width;//原代码为:FP_IMAGE_WIDTH,现替换为:w                               for (int i = 0; i <= w - 1; i++)                {                                        for (int j = 0; j <= h - 1; j++)                    {                        if ((m_image.GetPixel(i, j).B <= 127) && (m_image.GetPixel(i, j).R <= 127) && (m_image.GetPixel(i, j).G <= 127))                        {                            P[i, j] = 1;                        }                        else                        {                            P[i, j] = 0;                        }                    }                }                //set edges to 0                for (int i = 0; i <= w - 1; i++)                {                    P[i, 0] = 0;                    P[i, h - 1] = 0;                }                for (int j = 0; j <= h - 1; j++)                {                    P[0, j] = 0;                    P[w - 1, j] = 0;                }            }            catch (Exception ex)            {                throw ex;            }}public Bitmap getFingerPrintImage(){            Bitmap imageBuffer = new Bitmap(FP_IMAGE_WIDTH, FP_IMAGE_HEIGHT);for (int i = 0; i<= FP_IMAGE_WIDTH - 1;i++){for (int j = 0;j<= FP_IMAGE_HEIGHT - 1;j++){                    if (P[i, j] == 1)                    {                        imageBuffer.SetPixel(i, j, Color.Blue);                    }                    else                    {                        imageBuffer.SetPixel(i, j, Color.White);                    }}}return imageBuffer;}public Bitmap getFingerPrintImageDetail(){//set finger print imageBitmap imageBuffer = new Bitmap(FP_IMAGE_WIDTH,FP_IMAGE_HEIGHT );for (int i = 0; i<= FP_IMAGE_WIDTH - 1;i++){for (int j = 0;j<= FP_IMAGE_HEIGHT - 1;j++){if (P[i,j] == 1)imageBuffer.SetPixel(i,j,Color.Blue);elseimageBuffer.SetPixel(i,j,Color.White  );}}//get featuresdouble[] m_arr = this.getFingerPrintTemplate();//int linelength = 5;//draw pointsPen penBlue = new Pen(Color.Blue, 1);            Pen penRed = new Pen(Color.Red, 1);Pen penGreen = new Pen(Color.Green, 1);Pen penGray = new Pen(Color.Gray, 1);//Graphics gf = Graphics.FromImage(Image.FromHbitmap(m_ImageBuffer.GetHbitmap() ));Graphics gf = Graphics.FromImage(imageBuffer);gf.CompositingMode = CompositingMode.SourceOver;for(int i=7 ; i<=m_arr[0]-1;i=i+6){if(m_arr[i+4]>1){gf.DrawRectangle(penRed,(int)m_arr[i]+(int)m_arr[1]-3,(int)m_arr[i+1]+(int)m_arr[2]-2,5,5);}else if(m_arr[i+4]==1){gf.DrawEllipse(penGreen,(int)m_arr[i]+(int)m_arr[1]-3,(int)m_arr[i+1]+(int)m_arr[2]-2,5,5);}                 }//end for//draws the origingf.DrawLine(penGray,(int)m_arr[1]-5,(int)m_arr[2],(int)m_arr[1]+5,(int)m_arr[2]);gf.DrawLine(penGray,(int)m_arr[1],(int)m_arr[2]-5,(int)m_arr[1],(int)m_arr[2]+5);return imageBuffer;}//end getFingerPrintImageDetail()public void ThinningHilditch(){int change  = 1;bool mbool  = true;while (change != 0){change = 0;for(int i = 2; i <= FP_IMAGE_WIDTH - 2;i++){for(int j = 2; j <= FP_IMAGE_HEIGHT - 2;j++){if (P[i,j] == 1){short c  = 0;//count surrounding 1//a) Make sure pixel 1, has 2 to 6 (inclusive) neighborsif (P[i,j+1] == 1) { c++;}if (P[i+1,j+1] == 1) { c++;}if (P[i+1,j] == 1) { c++;}if (P[i+1,j-1] == 1) { c++;}if (P[i,j-1] == 1) { c++;}if (P[i-1,j-1] == 1) { c++;}if (P[i-1,j] == 1) { c++;}if (P[i-1,j+1] == 1) { c++;}if ((c >= 2) && (c <= 6 )){c = 0;//b) starting from 2, go clockwise until 9, and count the//'   number of 0 to 1 transitions.  This should be equal to 1.if ((P[i-1,j+1] == 0) && (P[i,j+1] == 1)) { c++;}if ((P[i,j+1] == 0) && (P[i+1,j+1] == 1)) { c++;}if ((P[i+1,j+1] == 0) && (P[i+1,j] == 1)) { c++;}if ((P[i+1,j] == 0) && (P[i+1,j-1] == 1)) { c++;}if ((P[i + 1,j-1] == 0) && (P[i,j-1] == 1)) { c++;}if ((P[i,j-1] == 0) && (P[i-1,j-1] == 1)) { c++;}if ((P[i-1,j-1] == 0) && (P[i-1,j] == 1)) { c++;}if ((P[i - 1,j] == 0) && (P[i-1,j+1] == 1)) { c++;}if (c == 1 ){c = 0;if (mbool == true){//c) 2*4*6=0  (ie either 2,4 ,or 6 is off)if ((P[i,j+1] * P[i+1,j] * P[i+1,j-1]) == 0 ){//d) 4*6*8=0if ((P[i+1,j] * P[i+1,j-1] * P[i-1,j]) == 0 ){P[i,j] = 0;change++;}}mbool = false;}else{//c) 2*6*8=0if ((P[i,j+1] * P[i+1,j-1] * P[i-1,j]) == 0){//d) 2*4*8=0if ((P[i,j+1] * P[i+1,j] * P[i-1,j]) == 0){P[i,j] = 0;change++;}}mbool = true;}}}}}}}//End While}//end ThinningHilditchAlgorithimpublic void ThinningHitAndMiss(){/**    basicly you take all patterns*    111    X1X*    X1X or x11 so on*    000    xxX*    if these conditions are true then set the middle 1 to 0*/int c  = 1;while (c != 0){c = 0;for(int i = 1;i<=FP_IMAGE_WIDTH - 1;i++){for(int j = 1;j<=FP_IMAGE_HEIGHT - 1;j++){if ((P[i,j] == 1) && (i != 0) && (j != FP_IMAGE_HEIGHT - 1) && (j != 0) && (i != FP_IMAGE_WIDTH - 1)){if ((P[i-1,j-1] == 1) &&( P[i,j-1] == 1) && (P[i+1,j-1] == 1) && (P[i-1,j+1] == 0) && (P[i,j+1] == 0) && (P[i+1,j+1] == 0)){P[i,j] = 0; //'1 on bottomc++;}else if ((P[i-1,j+1] == 1) && (P[i,j+1] == 1) && (P[i+1,j+1] == 1) && (P[i-1,j-1] == 0) && (P[i,j-1] == 0) && (P[i+1,j-1] == 0)){P[i,j] = 0; //'1 on topc++;}else if ((P[i-1,j] == 1) && (P[i-1,j - 1] == 1) && (P[i-1,j+1] == 1) && (P[i+1,j] == 0) && (P[i+1,j+1] == 0) && (P[i+1,j-1] == 0)){P[i,j] = 0; //'1 on leftc++;}else if ((P[i+1,j] == 1) && (P[i+1,j-1] == 1) && (P[i+1,j+1] == 1) && (P[i-1,j] == 0) && (P[i-1,j+1] == 0) && (P[i-1,j-1] == 0) ){P[i,j] = 0; //'1 on rightc++;}else if ((P[i-1,j] == 1) && (P[i,j-1] == 1) && (P[i,j+1] == 0) && (P[i+1,j+1] == 0) && (P[i + 1,j] == 0)){//x00//110//x1xP[i,j] = 0; //'1 on Bottem Leftc++;}else if ((P[i-1,j] == 1) && (P[i,j+1] == 1) && (P[i,j-1] == 0) && (P[i+1,j-1] == 0) && (P[i+1,j] == 0)){//x1x//110//x00P[i,j] = 0; //'1 on Top Leftc++;}else if ((P[i,j+1]== 1) && (P[i+1,j] == 1) && (P[i-1,j] == 0) && (P[i-1,j-1] == 0) && (P[i,j-1] == 0)){//x1x//011//00xP[i,j] = 0; //'1 on Top Rightc++;}else if ((P[i,j-1] == 1) && (P[i+1,j] == 1) && (P[i-1,j] == 0) && (P[i-1,j+1] == 0) && (P[i,j+1] == 0) ){//00x//011//x1xP[i,j] = 0; //'1 on Bottom Rightc++;}}}//Next}//Next}//End While}//end ThinningHitAndMisspublic void ChaneLinkAlgorithm(int ChainLinkDistance){//short count1;for(int i = 1;i<=  FP_IMAGE_WIDTH - 1;i++){for (int j = 1 ; j <= FP_IMAGE_HEIGHT - 1;j++){//change second condition when changeing direction//Horizontalif ((P[i,j] == 1) && (i != FP_IMAGE_WIDTH - 1) && (i != 0) && (j != FP_IMAGE_HEIGHT - 1) && (j != 0)){if (P[i + 1,j] == 0){short countX  = 0;//count Horizontal Holewhile (((i + countX) <= FP_IMAGE_WIDTH - 1) && (countX <= ChainLinkDistance)){if (((i + countX + 1) <= FP_IMAGE_WIDTH - 1) && ((countX + 1) <= ChainLinkDistance)){if (P[i + countX + 1,j] == 0){countX++;}else{break;}}else{break;}}//Fill hole if it is wide enoughif ((countX != 0) && ((countX + 1) <= ChainLinkDistance)){for (int temp = 0; temp<= countX;temp++){P[i+temp,j] = 1;}}}}//change second condition when changeing direction//Verticalif ((P[i,j] == 1) && (i != FP_IMAGE_WIDTH - 1) && (i != 0) && (j != FP_IMAGE_HEIGHT - 1) && (j != 0)){if (P[i,j+1] == 0 ){short countY  = 0;//count Horizontal Holewhile (((j + countY) <= FP_IMAGE_HEIGHT-1) && (countY <= ChainLinkDistance)){if (((j + countY + 1) <= FP_IMAGE_HEIGHT-1) && ((countY + 1) <= ChainLinkDistance) ){//i pu this here bacause it kept on crashingif (P[i,j + countY + 1] == 0){countY++;}else{break;}}else{break;}}//Fill hole if it is wide enoughif ((countY != 0) && (countY + 1 <= ChainLinkDistance)){for(int temp = 0;temp<=  countY;temp++){P[i,j + temp] = 1;}}}}//change second condition when changeing direction//Vertical Horizontalif ((P[i,j] == 1) && (i != FP_IMAGE_WIDTH - 1) && (i != 0) && (j != FP_IMAGE_HEIGHT - 1) && (j != 0)){if (P[i + 1,j + 1] == 0){short countYX  = 0; //1//count Horizontal Holewhile ((j + countYX <= FP_IMAGE_HEIGHT-1) && (i + countYX <= FP_IMAGE_WIDTH-1) && (countYX <= ChainLinkDistance)){if (((j + countYX + 1) <= FP_IMAGE_HEIGHT-1) && ((i + countYX + 1) <= FP_IMAGE_WIDTH-1) && ((countYX + 1) <= ChainLinkDistance))if (P[i+countYX+1,j + countYX + 1] == 0){countYX++;}else{break;}else{break;}}//Fill hole if it is wide enoughif ((countYX != 0) && (countYX + 1 <= ChainLinkDistance)){for(int temp = 0 ; temp <=  countYX ; temp++){P[i+temp,j+temp] = 1;}}}}}}}  /// <summery>/// /// ################################/// #     Extract Origin           #/// ################################/// /// In future i want to use the gradients to classifie the finger print into the 5 different /// catagories which are marked in the FP_CLASS.///    /// This function still needs to improved and somtimes dosen't find the center of the finger print.///    /// The principle in finding the centre is simple , just find the greatest change in the gradient/// bettween two lines and you have your centre.///    /// To find the classification you have to find the average changes in gradients in the different /// sectors (if you divided your picture in 4 using the fingerprint centre as the centre).You should /// then classifie the fingerprint according to this./// /// <summery>private Point getFingerPrintOrigin(){Point m_Point = new Point();double gradcur=0;double gradprev=0;double gradchangebig=0;double gradchange=0;      double graddistancebig=0;double graddistance=0;      double prevx=0;double prevy=0;      for(int j =50;j<=FP_IMAGE_HEIGHT-50;j++){ for(int i =50;i<=FP_IMAGE_WIDTH-50;i++){if(P[i,j]==1){//count surrounding pixelsint tc=0;int x1=0;int y1=0;int x2=0;int y2=0;//find surrounding 1sfor (int m = -1*FP_TEMPLATE_SEARCH_RADIUS;m<=FP_TEMPLATE_SEARCH_RADIUS;m++){for (int n = -1*FP_TEMPLATE_SEARCH_RADIUS;n<=FP_TEMPLATE_SEARCH_RADIUS;n++){if ((m==FP_TEMPLATE_SEARCH_RADIUS)||(m==(-1)*FP_TEMPLATE_SEARCH_RADIUS)||(n==FP_TEMPLATE_SEARCH_RADIUS)||(n==(-1)*FP_TEMPLATE_SEARCH_RADIUS)){if(P[i+m,j+n] == 1 ){tc++;if (tc==1){x1=i+m;y1=j+n;}if (tc==2){x2=i+m;y2=j+n;}}//end if}//end if}//end for n} //end for m         //does all the hard work of finding the greatest change in gradientif(tc==2){if ((x2-x1)>0){ gradcur  = (y2-y1)/(x2-x1);//check to see gradient change by at least 270 degreesif((gradcur>0)&&(gradprev<0)){gradchange = Math.Abs(gradcur) + Math.Abs(gradprev) ;  graddistance = Math.Abs(i) - Math.Abs(prevx);   if(gradchangebig<gradchange){if (graddistancebig<graddistance){gradchangebig=gradchange;graddistancebig=graddistance;m_Point.X=i;//FP_ORIGIN_X =i;m_Point.Y=j;//FP_ORIGIN_Y =j;}}break;}//reset varibles for new checksgradprev=gradcur;gradcur=0;prevx=i;prevy=j;}//(x2-x1)>0}//end if tc==2}//end if P[x,y]==1}//end for i}//end for j//  JOptionPane.showMessageDialog (null,Integer.toString(FP_ORIGIN_X)+";"+Integer.toString(FP_ORIGIN_Y),"getFingerPrintOrigin",JOptionPane.PLAIN_MESSAGE);return m_Point;}private int getFingerPrintClassification(){Point m_Point = this.getFingerPrintOrigin();double gradcur=0;      //stores total gradient of cornersdouble gradlt=0;double gradrt=0;double gradlb=0;double gradrb=0;     //counts total of each corner gradientdouble cgradlt=0;double cgradrt=0;double cgradlb=0;double cgradrb=0;     for(int j =50;j<=FP_IMAGE_HEIGHT-50;j++){ for(int i =50;i<=FP_IMAGE_WIDTH-50;i++){if(P[i,j]==1){//count surrounding pixelsint tc=0;int x1=0;int y1=0;int x2=0;int y2=0;//find surrounding 1sfor (int m = -1*FP_TEMPLATE_SEARCH_RADIUS;m<=FP_TEMPLATE_SEARCH_RADIUS;m++){for (int n = -1*FP_TEMPLATE_SEARCH_RADIUS;n<=FP_TEMPLATE_SEARCH_RADIUS;n++){if ((m==FP_TEMPLATE_SEARCH_RADIUS)||(m==(-1)*FP_TEMPLATE_SEARCH_RADIUS)||(n==FP_TEMPLATE_SEARCH_RADIUS)||(n==(-1)*FP_TEMPLATE_SEARCH_RADIUS)){if(P[i+m,j+n] == 1 ){tc++;if (tc==1){x1=i+m;y1=j+n;}if (tc==2){x2=i+m;y2=j+n;}}//end if}//end if}//end for n} //end for m         //does all the hard work of finding the greatest change in gradientif(tc==2){if ((x2-x1)>0){ gradcur  = (y2-y1)/(x2-x1);//check to see gradient change by at least 270 degreesif ((x2<m_Point.X)&&(y2>m_Point.Y)){    gradlt=gradlt+gradcur;gradlt++;}    else if ((x2>m_Point.X)&&(y2>m_Point.Y)){    gradrt=gradrt+gradcur;gradrt++;}    else if ((x2<m_Point.X)&&(y2<m_Point.Y)){    gradlb=gradlb+gradcur;gradlb++;}    else if ((x2>m_Point.X)&&(y2<m_Point.Y)){    gradrb=gradrb+gradcur;gradrb++;}         }//(x2-x1)>0}//end if tc==2}//end if P[x,y]==1}//end for i}//end for j//get average gradient for 4 cornersgradlb=gradlb/cgradlb;gradrb=gradrb/cgradrb;gradlt=gradlt/cgradlt;gradrt=gradrt/cgradrt;//determin classification according to gradient//needs workif ((gradlt>0)&&(gradrt>0)&&(gradlb>0)&&(gradrb>0)){return FP_CLASS_WHORL;}else if ((gradlt>0)&&(gradrt>0)&&(gradlb>0)&&(gradrb>0)){return FP_CLASS_LEFT_LOOP;}else if ((gradlt>0)&&(gradrt>0)&&(gradlb>0)&&(gradrb>0)){return FP_CLASS_RIGHT_LOOP;}else if ((gradlt>0)&&(gradrt>0)&&(gradlb>0)&&(gradrb>0)){return FP_CLASS_ARCH;}else if ((gradlt>0)&&(gradrt>0)&&(gradlb>0)&&(gradrb>0)){return FP_CLASS_ARCH_TENTED;}else{return 1;}    //  JOptionPane.showMessageDialog (null,Integer.toString(FP_ORIGIN_X)+";"+Integer.toString(FP_ORIGIN_Y),"getFingerPrintOrigin",JOptionPane.PLAIN_MESSAGE);}   /*<summery>  ################################ #     Extract Template         # ################################  The template will have to be formated according to the ISO standards as set out buy NIST , NIST also has a set of binary pictures to use for examples. This database is used for determaning the FAR(False Acceptance Rate) and FRR (False Rejection Rate)  First 7 are (elements in array , originx , originy , null , null , null ,null) after that the format is (x,y,r,degree ,number of ends,resultant degree).The size of the array  is always pre set.  There is also future work that needs to be done on genralization , basicly what this means is  that you take 3 finger templates , then take the features that are common to all three templeate and you will then come out with a generalized template.This will improve quality of the template. </summery>*/public double[] getFingerPrintTemplate(){// final int SEARCH_RADIUS = 1;   double x=0;double y=0;double r=0;double d=0;double[] m_arr = new double[FP_TEMPLATE_MAX_SIZE]; this.ThinningHilditch();this.ThinningHitAndMiss();this.ThinningHilditch();this.ThinningHitAndMiss();    Point origin = this.getFingerPrintOrigin();  m_arr[1]=origin.X;m_arr[2]=origin.Y;       int c = 7 ;int previ=0;int prevj=0;    bool first = true;    //start from 5 units in to avoid detection of edges of finger print and out of bound exceptionsfor(int j = 5 ;j<= FP_IMAGE_HEIGHT - 6;j++){first = true;  for( int i =5 ;i<= FP_IMAGE_WIDTH - 6;i++){if ((c<FP_TEMPLATE_MAX_SIZE)&&(P[i,j] == 1) && (i != FP_IMAGE_WIDTH - 1) && (i != 0) && (j != FP_IMAGE_HEIGHT - 1) && (j != 0) ){/*  *   Must not capture first and last feature because those are the edges of the finger print*   and will provide no value to the template.*/  if(first == true){first = false;//cheak to see if previos item in array was aslo endif( (c>7)&&((m_arr[c-6]+origin.X)==previ)&&((m_arr[c-5]+origin.Y)==prevj) ){//delete previos featuem_arr[c--]=0;m_arr[c--]=0;m_arr[c--]=0;m_arr[c--]=0;m_arr[c--]=0;m_arr[c--]=0;         }}else{int tc = 0;for (int m = -1*FP_TEMPLATE_SEARCH_RADIUS;m<=FP_TEMPLATE_SEARCH_RADIUS;m++){for (int n = -1*FP_TEMPLATE_SEARCH_RADIUS;n<=FP_TEMPLATE_SEARCH_RADIUS;n++){if ((m==FP_TEMPLATE_SEARCH_RADIUS)||(m==(-1)*FP_TEMPLATE_SEARCH_RADIUS)||(n==FP_TEMPLATE_SEARCH_RADIUS)||(n==(-1)*FP_TEMPLATE_SEARCH_RADIUS)){if(P[i+m,j+n] == 1 ){tc++;}//end if}//end if}//end for n} //end for m                  //calculate parameters necesary for templateif ((tc==1)||(tc==3)){x = i- origin.X;y = j- origin.Y;r = Math.Sqrt(x*x + y*y);if ((x>0)&&(y>0)){d =Math.Atan(y/x);}else if ((x<0)&&(y>0)){d =Math.Atan(y/x) - Math.PI ;}else if ((x<0)&&(y<0)){d =Math.PI + Math.Atan(y/x);}else if ((x>0)&&(y<0)){d =2*Math.PI + Math.Atan(y/x);}}              //check to see if point already been capturedbool foundx = false;  bool foundy = false;  for (int m=7;m<=c;m=m+6){if(m_arr[m+4]==3){if(Math.Abs(Math.Abs((int)m_arr[m])-Math.Abs(x))<4){foundx=true;}if(Math.Abs(Math.Abs((int)m_arr[m+1])-Math.Abs(y))<4){foundy=true;}}//end if}//end for m                                     //1 surrounding 1sif ((tc==1) && (c <= FP_TEMPLATE_MAX_SIZE-6)  && (x!=0) && (y!=0) && ((foundx==false)||(foundy==false)) ){              if (P[i-1,j+1] == 1)  {m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] = 135 ;}else if (P[i,j+1] == 1){m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] =90  ;}else if (P[i+1,j+1] == 1){m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] =45  ;}else if (P[i+1,j] == 1) {m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] = 0  ;}else if (P[i+1,j-1] == 1){m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] =315  ;}else if (P[i,j-1] == 1){m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] = 270  ;}else if (P[i-1,j-1] == 1){m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] = 225 ;}else if (P[i-1, j] == 1 ) {m_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 1 ;m_arr[c++] = 180 ;}}else if ((tc>=3)&&(c <= FP_TEMPLATE_MAX_SIZE - 6)&&(x!=0)&&(y!=0)&&((foundx==false)||(foundy==false)) ){          //3 surrounding 1sm_arr[c++] = x;m_arr[c++] = y;m_arr[c++] = r;m_arr[c++] = d;m_arr[c++] = 3;m_arr[c++] = 0;}//if tc>=3 }//end if firstprevi=i;prevj=j;         //306;269if (((i- origin.X)>=(306 - 4))&&((i- origin.Y)>=(269-4))){if (((i- origin.X)<=(306+4))&&((i- origin.Y)<=(269+4))){//JOptionPane.showMessageDialog (null,Double.toString(c)+";"+Integer.toString(i)+";"+Integer.toString(j),"My Point",JOptionPane.PLAIN_MESSAGE);}}         }//end if that checks for p[x,y]=1}//end for}//end for//put total size of points collected at 0 in arraym_arr[0]=c;return m_arr;}//end getFingerPrintTemplate()public String ConvertFingerPrintTemplateDoubleToString(double[] finger){String temp="";for (int i=0;i<=finger.Length-1 ; i++){temp = temp + finger[i].ToString() +";";}return temp;} public double [] ConvertFingerPrintTemplateStringToDouble(String finger){double[] m_finger = new double[FP_TEMPLATE_MAX_SIZE]; int c=-1;String m_double = "";String temp ="";for (int i=0;i<=finger.Length-1 ; i++){char[] tempch = finger.ToCharArray();temp = temp[i].ToString();if (temp==";"){m_finger[c++] =Double.Parse(m_double);}else{m_double  = m_double +  temp;    }}return m_finger;}  /// <summery>/// ################################/// #         Matching             #/// ################################///     /// Something to possably look at are/// /// Distance = (X1 -X2)^2 + (Y1 - Y2)^2. The Error_Rating , if a image is is to the left or/// right or even at a angle the distance betwwen matched points will always be the same.///     /// The matching dose account for rotation , thats what the cos and sin are for. /// /// In matching you will never get a 100% match uunless they are exactly the same /// image. 60% is quite good in general ,anything above 55% is considered a match , even /// in other commercial versions. Remember you comparing twod DIFFERENT images then drawing a conclusion of a match./// /// </summery>  //cross-corelation algorithmpublic int Match(double[] finger1,double[] finger2 ,  int threshold , bool fastmatch){//compare matrix with all shifted matrixes//must do later. must get the size of the array// JOptionPane.showMessageDialog (null,Double.toString(finger1[0])+";"+Double.toString(finger1[1])+";"+Double.toString(finger2[3]),"Match",JOptionPane.PLAIN_MESSAGE);double matchcount = 0;double matchcounttotal = (finger1[0]-6)/6;double bestmatch =0;double radian = Math.PI/180;bool foundpoint;        for (int k = -1*FP_MATCH_POINT_ROTATION_MOVEMENT; k <= FP_MATCH_POINT_ROTATION_MOVEMENT; k++){for (int i =7; i <= finger1[0]-5; i=i+6){foundpoint = false;  for (int j =7; j <= finger2[0]-5; j=j+6){if(foundpoint==false){//compare two points account for rotational , verticle and horizontal shiftint resx=0;int resy=0;double x1=0 ;double y1=0;double x2=0;double y2=0;double r=0;double d=0;//find nessasary parameters                            r =finger2[j+2];d = finger2[j+3];x2=finger1[i];y2=finger1[i+1];//do angle shift for xx1 = r*Math.Cos(d+(k*radian));resx = Math.Abs((int)x2 + (int)(-1*x1));//do angle shift for y         y1 = r*Math.Sin(d+(k*radian));resy = Math.Abs((int)y2 + (int)(-1*y1));                           //cheak shift matchs count as matchif((FP_MATCH_POINT_DISTANCE_MOVEMENT > resx) && (FP_MATCH_POINT_DISTANCE_MOVEMENT > resy)){             //cheak if same kind of featureif(finger1[i+4] == finger2[j+4]){//cheak if feature in  same direction//  if(((finger1[i+5]-finger2[j+5])<=46)||((finger1[i+5]==0)&&(finger2[j+5]==315))||((finger1[i+5]==0)&&(finger2[j+5]==45)))//  {matchcount++;foundpoint = true;//break;//  }//cheak if feature in  same direction} //cheak if same kind of feature                      }//end if}//if found}//end for j}//end for i//see if we have a match          if ((((matchcount/matchcounttotal)*100)>=threshold)&& (fastmatch == true)){//found matchreturn (int)((matchcount/matchcounttotal)*100);}else{//not found match     if(matchcount>bestmatch){bestmatch = matchcount;}//reset match counter to 0matchcount=0;   } //end if              }//end for kreturn (int)((bestmatch/matchcounttotal)*100);}//end Match    }//end class}//end namespace

 

源代码下载地址1:http://download.csdn.net/detail/lovegonghui/8996059

源代码下载地址2:http://down.51cto.com/data/2081611
 

1 0
原创粉丝点击