日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一款开源的指纹识别SDK

發布時間:2023/12/14 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一款开源的指纹识别SDK 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?Biometric SDK 是一個開源的指紋識別開發包,可匹配和標識人們的指紋。計算指紋相似度

關鍵代碼:

/* Biometric SDKVersion 1.3This file contains functions that manipulate , extract features and matchfingerprint images.Copyright (C) 2005 Scott JohnstonEmail : moleisking@googlemail.comThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 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,現替換為:hint w = m_image.Width;//原代碼為:FP_IMAGE_WIDTH,現替換為:wfor (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 0for (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 buyNIST , NIST also has a set of binary pictures to use for examples. This database is used fordetermaning the FAR(False Acceptance Rate) and FRR (False Rejection Rate)First 7 are (elements in array , originx , originy , null , null , null ,null) after thatthe 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 templeateand 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 parametersr =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 matchif ((((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
?

總結

以上是生活随笔為你收集整理的一款开源的指纹识别SDK的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。