private void OnEnrollCompleted(IAsyncResult r) { try { if (InvokeRequired) { BeginInvoke(new AsyncCallback(OnEnrollCompleted), r); } else { var task = _biometricClient.EndPerformTask(r); var status = task.Status; // Check if extraction was canceled if (status == NBiometricStatus.Canceled) { return; } if (status == NBiometricStatus.Ok) { lblQuality.Text = $"Quality: {_subjectFinger.Objects[0].Quality}"; _template = _subject.Save(); ShowMessage(@"Please wait while your fingerprint is being processed..."); UpdateStateToParent(ApplicationController.State.Captured_Good); } else { lblQuality.Text = string.Empty; ShowMessage(@"Fingerprint image is of low quality"); UpdateStateToParent(ApplicationController.State.Captured_Bad); } } } catch (Exception ex) { ShowMessage(string.Format("Extraction error: {0}", ex.Message)); Logger.logToFile(ex, AppSettings.ErrorLogPath); } }
private void SetActiveTemplate(NBuffer template) { this.Template = null; this.Template = template; }
private string MatchStudents(NFRecord template, BindingList<student> StudentsInCourse) { const string Components = "Biometrics.FingerExtraction,Biometrics.FingerMatching"; matchedFingerID = 0; matchedScore = 0; string highestStudent = ""; int highestMatch = 0; NFExtractor extractor = null; NMatcher matcher = null; try { lblStatus.Text = "Getting License!"; Application.DoEvents(); // Obtain license. if (!NLicense.ObtainComponents(licServer, 5000, Components)) { Console.WriteLine(@"Could not obtain licenses for components: {0}", Components); //return -1; } lblStatus.Text = "Got License!"; Application.DoEvents(); // create an extractor //extractor = new NFExtractor(); // extract probe template NBuffer probeTemplate = template.Save(); lblStatus.Text = "Exctracting templates"; // extract gallery templates int args = StudentsInCourse.Count * 10; NBuffer[] galleryTemplates = new NBuffer[args - 1]; string[] students = new string[args - 1]; int n = 0; foreach (student currentStudent in StudentsInCourse) { for (int count = 0; count < 10; count++) { try { galleryTemplates[n+count] = new NBuffer(currentStudent.template[count]); students[n + count] = currentStudent.StudentNumber; } catch (Exception ex) { Console.WriteLine("Could not load template for student" + currentStudent.StudentNumber + " - " + ex.Message); } } n = n + 10; } // create a matcher matcher = new NMatcher(); // identify reference template by comparing to each template from arguments Console.WriteLine(@"=== identification started ==="); matcher.IdentifyStart(probeTemplate); lblStatus.Text = "Identifying start"; try { for (int i = 1; i < args; i++) { if (galleryTemplates[i - 1].Size != 0) { int score = matcher.IdentifyNext(galleryTemplates[i - 1]); if (score > highestMatch) { Console.WriteLine(@"template[{0}] scored {1} {2}", i - 1, score, score > 0 ? "(Matched)" : ""); Console.WriteLine("student number matched: " + students[i-1]); highestMatch = score; highestStudent = students[i - 1]; matchedFingerID = i % 10; matchedScore = score; } } } } finally { matcher.IdentifyEnd(); } Console.WriteLine(@"=== identification finished ==="); //return 0; } catch (Exception ex) { Console.WriteLine(ex); } finally { lblStatus.Text = "Releasing License"; Application.DoEvents(); NLicense.ReleaseComponents(Components); if (extractor != null) { extractor.Dispose(); } if (matcher != null) { matcher.Dispose(); } lblStatus.Text = "License Released"; Application.DoEvents(); } return highestStudent; }
internal static BiometricsRecord GetBiometricsRecord(BiometricsRecord _BiometricsRecord, string SourceFileDir) { String userDir = SourceFileDir + "\\" + _BiometricsRecord.EnrollmentId + "\\"; //Find Images If Exists and Save in Biometrics Record //Get Signature if (File.Exists(userDir + "sign_image.jpg")) { byte[] imageBytes = File.ReadAllBytes(userDir + "sign_image.jpg"); Image image = Image.FromStream(new MemoryStream(imageBytes)); _BiometricsRecord.Signature = image; } //Get Photo if (File.Exists(userDir + "photo_image.jpg")) { byte[] imageBytes = File.ReadAllBytes(userDir + "photo_image.jpg"); Image image = Image.FromStream(new MemoryStream(imageBytes)); _BiometricsRecord.Photograph = image; } //Get Photo Template if (File.Exists(userDir + "photo_template.tem")) { byte[] imageBytes = File.ReadAllBytes(userDir + "photo_template.tem"); _BiometricsRecord.PhotographTemplate = imageBytes; } //Get Finger Images foreach (var fingerDescription in Enum.GetValues(typeof(FingerDescription))) { string fingerFile = userDir + fingerDescription + ".jpg"; string fingerTemplateFile = userDir + fingerDescription + ".tem"; Image image = null; if (File.Exists(fingerFile)) { byte[] imageBytes = File.ReadAllBytes(fingerFile); image = Image.FromStream(new MemoryStream(imageBytes)); } //Get Finger Template if (File.Exists(fingerTemplateFile)) { var imageBytes = File.ReadAllBytes(fingerTemplateFile); var fingerprintBuffer = new NBuffer(imageBytes); //NFinger finger, NBuffer fingerTemplate using (var biometricClient = new NBiometricClient()) using (var subject = new NSubject()) using (var finger = new NFinger()) { //Read finger image from enrollment and add it to NFinger object finger.Image = NImage.FromMemory(fingerprintBuffer, NImageFormat.Wsq); //add NFinger object to NSubject subject.Fingers.Add(finger); ////Set finger template size (recommended, for enroll to database, is large) (optional) //biometricClient.FingersTemplateSize = NTemplateSize.Large; //Create template from added finger image var status = biometricClient.CreateTemplate(subject); if (status == NBiometricStatus.Ok) { _BiometricsRecord.SaveActiveUserFingerRecords(finger, subject, (FingerDescription)fingerDescription); } } } } //Get Grouped Finger Templates if (File.Exists(userDir + "fingers_template.tem")) { byte[] imageBytes = File.ReadAllBytes(userDir + "fingers_template.tem"); _BiometricsRecord.FingerTemplates = imageBytes; } return _BiometricsRecord; }
internal bool SaveBiometricsRecords(BiometricsRecord BiometricsRecord, string DestFileDir) { NFTemplate _NFTemplate = new NFTemplate(); //Create Folder for the User String userDir = DestFileDir + "\\" + BiometricsRecord.EnrollmentId + "\\"; if (!Directory.Exists(userDir)) { DirectoryInfo dir = Directory.CreateDirectory(userDir); } //Save User Signature if (BiometricsRecord.Signature != null) { BiometricsRecord.Signature.Save(userDir + "sign_image.jpg"); } //Save User Photo if (BiometricsRecord.Photograph != null) { BiometricsRecord.Photograph.Save(userDir + "photo_image.jpg"); File.WriteAllBytes(userDir + "photo_template.tem", BiometricsRecord.PhotographTemplate.ToArray()); } if (BiometricsRecord.FingerprintRecords.Count > 0) { //save Fingerprint foreach (var userFingerprint in BiometricsRecord.FingerprintRecords) { userFingerprint.FingerImage.Save(userDir + userFingerprint.FingerDescription + ".jpg"); File.WriteAllBytes(userDir + userFingerprint.FingerDescription + ".tem", userFingerprint.FingerTemplate.ToArray()); //Add FingerTemplate to NFTemplate if (userFingerprint.FingerRecord != null) { _NFTemplate.Records.Add(userFingerprint.FingerRecord); } else { var wsq = new NBuffer(userFingerprint.FingerWsq); //var image = NImage.FromMemory(wsq, NImageFormat.Wsq).ToBitmap(); //NFinger finger, NBuffer fingerTemplate using (var biometricClient = new NBiometricClient()) using (var subject = new NSubject()) using (var finger = new NFinger()) { //Read finger image from enrollment and add it to NFinger object finger.Image = NImage.FromMemory(wsq, NImageFormat.Wsq); //add NFinger object to NSubject subject.Fingers.Add(finger); ////Set finger template size (recommended, for enroll to database, is large) (optional) //biometricClient.FingersTemplateSize = NTemplateSize.Large; //Create template from added finger image var status = biometricClient.CreateTemplate(subject); if (status == NBiometricStatus.Ok) { userFingerprint.FingerRecord = finger.Objects[0].Template; _NFTemplate.Records.Add(finger.Objects[0].Template); } } //NLicense.ReleaseComponents("Biometrics.FingerExtraction"); } } //Save Grouped FingerTemplates var ms = new NMemoryStream(); _NFTemplate.Save(ms); BiometricsRecord.FingerTemplates = ms.ToArray(); File.WriteAllBytes(userDir + "fingers_template.tem", BiometricsRecord.FingerTemplates); } //Save User Record as Serilalised Binary Data BinarySerialization.WriteToBinaryFile(userDir + "UserRecord.crims", BiometricsRecord); //If the code runs to this point without Failure, We are good return true; }
private void OnCapturingCompleted(IAsyncResult r) { if (InvokeRequired) { BeginInvoke(new AsyncCallback(OnCapturingCompleted), r); } else { try { var status = _biometricClient.EndCapture(r); // If Stop button was pushed if (status == NBiometricStatus.Canceled) { return; } lblStatus.Text = status.ToString(); if (status != NBiometricStatus.Ok) { // Since capture failed start capturing again _subject.Faces[0].Image = null; _biometricClient.BeginCapture(_subject, OnCapturingCompleted, null); } else { if (_subject.Faces[0].Image != null) { //facesView.Image = image; var size = new Size { Width = int.Parse(Settings.Default.ImageWidth), Height = int.Parse(Settings.Default.ImageHeight) }; var memoryStream = new MemoryStream(); _subject.Faces[0].Image.ToBitmap().Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg); var faceBoundingRect = _subject.Faces[0].Objects[0].BoundingRect; //var resizedImage = _subject.Faces[0].Image.Crop(50, 50, 50, 50).ToBitmap(); //int widthOffset; //if (faceBoundingRect.Left > faceBoundingRect.Right) //{ // //widthOffset = 2*tt.Right/6 + tt.Width; // widthOffset = (faceBoundingRect.Left - faceBoundingRect.Right) / 3 + faceBoundingRect.Width + 50; //} //else //{ // //widthOffset = 2*tt.Left/6 + tt.Width; // //widthOffset = tt.Left + tt.Width + 50; // widthOffset = (faceBoundingRect.Right - faceBoundingRect.Left) / 3 + faceBoundingRect.Width; //} //if (faceBoundingRect.Left > faceBoundingRect.Right) //{ // //widthOffset = tt.Left - tt.Right; // widthOffset = (faceBoundingRect.Right - faceBoundingRect.Right) / 2 + faceBoundingRect.Width / 2 + 50; //} //else //{ // widthOffset = faceBoundingRect.Right - faceBoundingRect.Left; // widthOffset = (faceBoundingRect.Width * 10) / 100 + faceBoundingRect.Width; //} var resizedImage = ResizeImage(memoryStream, (faceBoundingRect.Location.X - faceBoundingRect.Left) + faceBoundingRect.Width, faceBoundingRect.Height + 50, true, faceBoundingRect.X, faceBoundingRect.Top, faceBoundingRect.Right, faceBoundingRect.Bottom); if (resizedImage != null) { pictureBoxCroped.Image = resizedImage; _croppedPhotoImage = resizedImage; } _template = _subject.GetTemplateBuffer(); EnableControls(false); } //UpdateView(_subject.Faces[0], status); } } catch (Exception ex) { AppUtils.ShowException(ex); lblStatus.Text = string.Empty; EnableControls(false); } } }
private void SaveTemplateForVerification(NBuffer _template) { TemplateNotifyer(_template); }
private void OnEnrollCompleted(IAsyncResult r) { if (InvokeRequired) { BeginInvoke(new AsyncCallback(OnEnrollCompleted), r); } else { var task = _biometricClient.EndPerformTask(r); var status = task.Status; // Check if extraction was canceled if (status == NBiometricStatus.Canceled) { return; } if (status == NBiometricStatus.Ok) { lblQuality.Text = $"Quality: {_subjectFinger.Objects[0].Quality}"; if (_nfView.Finger.Image != null) { _nfView.Finger.Image.Dispose(); _nfView.Finger.Image = null; } if (_nfView.Finger.Objects[0].Template != null) { _nfView.Finger.Objects[0].Template.Dispose(); _nfView.Finger.Objects[0].Template = null; } lblQuality.Text = string.Empty; OnIsScanningChanged(false); _template = _subject.Save(); _nfView.Finger.Objects[0].Template = _subject.Fingers[0].Objects[0].Template; SaveTemplateForVerification(_template); SaveUserIdForVerification(textBoxIDNumber.Text); UpdateStateToParent(ApplicationController.State.Captured_Good); NImage image = _subjectFinger.Image; if (image == null) { return; } _nfView.Width = (int)image.Width; _nfView.Height = (int)image.Height; _nfView.Finger.Image = image; _nfView.Refresh(); } else { MessageBox.Show($"Fingerprint image is of low quality OR The template was not extracted: {status}.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error); _subject = null; _subjectFinger = null; } } }
/// <summary> /// Sort an n-tuple file in external memory. The file is overwritten. /// </summary> /// <param name="file">The n-tuple file.</param> /// <param name="itemLength">The length of the tuples in the file.</param> /// <param name="maxItemsInMemory">The maximum amount of n-tuples to keep in memory.</param> /// <param name="sortOrder">The sort order to use.</param> public static void SortFile(string file, int itemLength, int maxItemsInMemory, params int[] sortOrder) { // // step 1: sort in chuncks that fit in the memory we have. the size of each chunk is // equal to the amount of memory provided (given in numbers of items) // // temp files used to store the sorted chunks var chunkFiles = new List <string>(); // // IComparer used to compare two items. the priorities are given. var sorter = new NComparer(sortOrder); // // open the file for reading using (var br = new BinaryReader(File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None))) { // // counter to keep track of how much items we've read var i = 0; // // current chunk, represented as an array of items var chunk = new long[maxItemsInMemory][]; // // we read as long as we have not yet reached the end of the file while (br.BaseStream.Position < br.BaseStream.Length) { // // if we still have space in the chunk, read the next triple from the file if (i < maxItemsInMemory) { chunk[i] = Read(br, itemLength); i++; } // // if not, we need to sort and output the current chunk. // for this part sorting is done in-memory else { // // use default array sorting using the IComparer we have defined earlier Array.Sort(chunk, sorter); // // generate a file name for the chunk. it needs to be unique for obvious // reasons var fileName = String.Format("~{0}.chunk.tmp", Generator.GetRandomFilename(12)); // // add the file to the list of chunk files. we'll need it later chunkFiles.Add(fileName); // // open a binary writer and write the sorted items from the current chunk // to the chunk file using (var bw = new BinaryWriter(File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))) { for (int j = 0; j < chunk.Length; j++) { if (chunk[j] != null) { Write(bw, chunk[j]); } } } // // clear the chunk array as it might not get completely overwritten during // the next pass Array.Clear(chunk, 0, chunk.Length); // // reset the triples-read counter i = 0; } } // // here, we have read the entire file, but there still might be some items left // in the last chunk that we need to handle. // the code to do this is duplicated from the else block above. if (i > 0) { Array.Sort(chunk, sorter); var fileName = String.Format("~{0}.chunk.tmp", Generator.GetRandomFilename(12)); chunkFiles.Add(fileName); using (var bw = new BinaryWriter(File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.None))) { for (int j = 0; j < chunk.Length; j++) { if (chunk[j] != null) { Write(bw, chunk[j]); } } } } } // // force garbage collection GC.Collect(); // // step 2: perform k-way merge sort on the chunks. now that we have the sorted chunks, // we need to merge them and write out the final result. // // the number of pages used for reading must be equal to the number of chunk files var numReadPages = chunkFiles.Count; // // the total number of pages has one additional page for writing the output to var numPages = numReadPages + 1; // // the size of each page is the number of items that may be kept in memory // devided by the number of pages. WARNING: if the amount of memory available is // too small in relation to the size of the input file, then there may be too // many chunks, hence too many pages to fit in memory when each page should have // at least space for 1 item. var pageSize = maxItemsInMemory / numPages; // // the buffer simply contains the pages var buffer = new NBuffer(numPages, pageSize); // // the last page is the one used for writing the output to. this variable is a shortcut // that allows us to say buffer[pageOutputId] instead of buffer[numPages - 1]. var pageOutputId = numPages - 1; // // the page cursors are simply integers denoting the position of the reading pointers // in each of the pages var pageCursors = new int[numPages]; // // the chunk cursors are binary readers pointing to each of the chunks from the // previous step var chunkCursors = new BinaryReader[numReadPages]; // // these variables keep the currenly smallest item found (e.g. the one that needs to // be written next to the output file to maintain the sort order), and the Id of the // chunk this item resides in long[] minItem = null; var minChunkId = -1; // // we start by initializing the cursors and reading the initial parts of all the chunks // into their respective buffer pages for (int i = 0; i < numReadPages; i++) { pageCursors[i] = 0; chunkCursors[i] = new BinaryReader(File.Open(chunkFiles[i], FileMode.Open, FileAccess.Read, FileShare.Read)); ReadToPage(chunkCursors[i], itemLength, buffer[i]); } // // we open a binary writer to write the output (the sorted file) to. note we just // overwrite the existing file. this is possible because all information from the // original file is now duplicated in the sorted chunks anyway. using (var bw = new BinaryWriter(File.Open(file, FileMode.Create, FileAccess.Write, FileShare.None))) { // // entering the main loop of the merge that we will remain in for as long as there // are items in any of the pages used for reading do { // // reset the next item in the sort order to null. this is used to determine // if can leave the main loop. minItem = null; // // here we find the next item in the sort order (the smallest item) in any // of the read pages for (int i = 0; i < numReadPages; i++) { // // fetch the current smallest item in this page. it will always be the // one the respective cursor is pointing to. var t = buffer[i][pageCursors[i]]; // // it's possible the page does not contain (any more) items. if so we // can just ignore it. for this we do assume that if we read a null from // position i at some page, then all positions j > i on that same page are // also null if (t != null) { // // if the current smallest item doesn't exist yet, then the one we've // just read is trivially the new smallest item if (minItem == null) { minItem = t; minChunkId = i; } // // if a smallest item does exist, we need to do a comparison first. // we use the same IComparer that we defined earlier else { var c = sorter.Compare(t, minItem); if (c < 0) { minItem = t; minChunkId = i; } } } } // // checking if a new smallest item has been identified. if it is we need to // write it to the output page. if not, we don't need to do anything and will // exit the main loop. if (minItem != null) { // // we increment the cursor belonging to the page where the next smallest // item resides pageCursors[minChunkId]++; // // check if we have read all the items on this page. if so, read the next // set of items from the chunk file and reset the cursor if (pageCursors[minChunkId] >= pageSize) { ReadToPage(chunkCursors[minChunkId], itemLength, buffer[minChunkId]); pageCursors[minChunkId] = 0; } // // put the next smallest item in the output page buffer[pageOutputId][pageCursors[pageOutputId]] = minItem; // // increment the output page cursor pageCursors[pageOutputId]++; // // check if the output page is full. if so, write its items to the output // file, clear the page, and reset the cursor if (pageCursors[pageOutputId] >= pageSize) { for (int i = 0; i < pageSize; i++) { Write(bw, buffer[pageOutputId][i]); } buffer[pageOutputId].Clear(); pageCursors[pageOutputId] = 0; } } } while (minItem != null); // // the items from all the chunks have been read and sorted, but the last couple // of them may still reside on the output page. here we write these last ones to // the output file. for (int i = 0; i < pageSize; i++) { var t = buffer[pageOutputId][i]; if (t != null) { Write(bw, t); } else { break; } } } // // close the chunk cursors and delete the chunk files for (int i = 0; i < numReadPages; i++) { chunkCursors[i].Dispose(); File.Delete(chunkFiles[i]); } }
private int identify() { verifyLicense(); bool largeTemplate = true; cryptography decrypt = new cryptography(); NMatcher templateMatcher = null; int maxKeyNum = 0; int primKey = 0; try { NBuffer probeTemplateBuffer = null; byte [] probeTemplateArray = null; try { NleDetectionDetails details; // unused if (!createTemplate(globalInsetFaceBmp, largeTemplate, out details)) { return(primKey); } probeTemplateBuffer = facialTemplate.Save(); probeTemplateArray = probeTemplateBuffer.ToByteArray(); } catch (IOException ex) { MessageBox.Show("error reading input file {0}: " + ex); return(primKey); } // extract gallery templates // This code allows for searching a database where rows (users) have been deleted, // causing primaryKeys to not be sequential. int row = 1; maxKeyNum = myDdInterface.maxPrimaryKey(); if (maxKeyNum == 0) { MessageBox.Show("There are no registered users.\nPlease enroll and try again."); return(maxKeyNum); } List <byte []> dbaseTemplates = new List <byte []> (); List <int [, ]> rowKeyList = new List <int [, ]> (); // list of row/primary keys for (int i = 0; i < maxKeyNum; i++) { try { byte [] tempArray = myDdInterface.getTemplateFromKey(i + 1); if (tempArray != null) // skip deleted records { int [,] rowKeyRef = new int [1, 2]; dbaseTemplates.Add(tempArray); // store row/primary key reference rowKeyRef [0, 0] = row; rowKeyRef [0, 1] = i + 1; rowKeyList.Add(rowKeyRef); row++; } } catch (IOException ex) { MessageBox.Show("error reading reference template " + i + ": " + ex); return(primKey); } } templateMatcher = new NMatcher(); templateMatcher.IdentifyStart(probeTemplateArray); try { int numOfTemplates = dbaseTemplates.Count(); int score = 0; int highScore = 0; for (int i = 0; i < numOfTemplates; i++) { score = templateMatcher.IdentifyNext(dbaseTemplates [i]); if (score > highScore) { highScore = score; // get primary key based on row number int [,] tempRef = new int [1, 2]; tempRef = rowKeyList [i]; primKey = tempRef [0, 1]; } } if (primKey == 0) { MessageBox.Show("Sorry, Unable to Identify.\nTry again."); return(primKey); } else { string fName = myDdInterface.getFName(primKey); string lName = myDdInterface.getLName(primKey); Bitmap storedBmp = myDdInterface.getImageFromId(myDdInterface.userIdFromKey(primKey)); // Check for potential errors referencing Primary key. if (enrolledImagePictureBox.InvokeRequired) { enrolledImagePictureBox.Invoke(new Action(() => enrolledImagePictureBox.Image = storedBmp)); enrolledImageNameLabel.Invoke(new Action(() => enrolledImageNameLabel.Text = (fName + " " + lName))); } else { enrolledImagePictureBox.Image = storedBmp; enrolledImageNameLabel.Text = (fName + " " + lName); } if (!enrolledImagePictureBox.Visible) { enrolledPicVisToggle(); } if (tabIndex == 0) // play video only on main tab { playVideoFile(primKey); } return(primKey); } } catch (Exception ex) { MessageBox.Show("" + ex); } finally { templateMatcher.IdentifyEnd(); facialTemplate = null; } return(primKey); } catch (Exception ex) { MessageBox.Show("" + ex); return(primKey); } finally { NLicense.ReleaseComponents(Components); if (templateMatcher != null) { templateMatcher.Dispose(); } } }