private void mainBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { #region Initialization BibDetector.Cleanup(); ProgressReport.Directory = baseDirectory; ProgressReport.UseSubdirs = includeSubdirsCheckbox.Checked; ProgressReport.DataFile = dataFilePath; ProgressReport.Operation = CurrentOperation.Start; ProgressReport.Operation = CurrentOperation.ListingAllPhotos; ProgressReport.TotalPhotos = -1; List <string> files = filesInDirectory(baseDirectory); ProgressReport.TotalPhotos = files.Count; ProgressReport.Operation = CurrentOperation.PhotoListingDone; ProgressReport.Operation = CurrentOperation.ReadingParticipantsData; ProgressReport.TotalParticipants = -1; List <CsvRow> data = CsvManager.ReadAllWithoutHeader(dataFilePath); ProgressReport.TotalParticipants = data.Count; ProgressReport.Operation = CurrentOperation.ParticipantsDataReadingDone; ProgressReport.Operation = CurrentOperation.ProcessingParticipantsBibs; List <string> participantsBibs = new List <string>(); foreach (var part in data) { if (mainBackgroundWorker.CancellationPending) { e.Cancel = true; break; } participantsBibs.Add(part.Columns[bibColumnIndex]); } ProgressReport.Operation = CurrentOperation.ProcessingParticipantsBibsDone; List <CsvRow> report = new List <CsvRow>(); List <TaggableFace> processedFaces = new List <TaggableFace>(); TaggableResult tagResult = new TaggableResult(baseDirectory); if (useSavedProgressCheckbox.Checked) { ProgressReport.Operation = CurrentOperation.ReadingSavedProgress; var savedData = readSavedProgress(); report = savedData.Item1; tagResult = savedData.Item2; } ProgressReport.Configuration = _params; #endregion #region First step procession: detecting bibs if (ProgressReport.Configuration.DetectionSteps == DetectionSteps.DetectionAndRecognition || ProgressReport.Configuration.DetectionSteps == DetectionSteps.Both) { ProgressReport.Operation = CurrentOperation.ProcessingPhotos; for (int i = 0; i < files.Count; i++) { if (mainBackgroundWorker.CancellationPending) { e.Cancel = true; break; } var photo = files[i]; if (tagResult.PhotoExists(photo)) { continue; } ProgressReport.CurrentPhoto = Path.GetFileName(photo); ProgressReport.CurrentPhotoIndex = i; if (i != 0) { Thread.Sleep(_params.Delay); } TaggableImage tagImage = new TaggableImage(baseDirectory, photo); var faces = BibDetector.GetPossibleBibs(photo, _params.FaceRecognition, _params.BibArea, _params.DigitsRecognition, baseDirectory); if (faces == null) { LogManager.Error("Force break and cancellation of bib procession."); break; } else { processedFaces.AddRange(faces); } CsvRow row = new CsvRow(); row.Add(photo); int actualBibs = 0; int totalNum = 0; int resolvedFaces = 0; foreach (var face in faces) { List <string> nums = new List <string>(); bool faceResolved = false; foreach (var num in face.NumericBibs) { totalNum++; if (participantsBibs.Contains(num)) { faceResolved = true; ProgressReport.DetectedBibs++; actualBibs++; nums.Add(num); } } if (faceResolved) { row.Add(nums.ToArray()); string tag = nums.First(); tagImage.AddFace(face.FaceId, tag, face.DetectedBibs); resolvedFaces++; } else { tagImage.AddFace(face.FaceId, face.DetectedBibs); } } //recognized numbers - RN //existing numbers - EN //detected faces - DF //resolved faces - RF string logMsg = string.Format("RN: {0}; EN: {1}; DF: {2}; RF: {3}", totalNum, actualBibs, faces.Length, resolvedFaces); if (actualBibs == 0) { ProgressReport.UnresolvedImages++; row.Add("UNRESOLVED"); } else { ProgressReport.ResolvedImages++; } LogManager.Info(logMsg); report.Add(row); CsvManager.SaveCsv(report, saveReportPath); tagResult.AddImage(tagImage); tagResult.Save(saveDataPath); ProgressReport.CurrentPhotoIndex = i + 1; //TODO: iteration cleanup //BibDetector.IterationCleanup(); } } #endregion #region Second step procession: train faces if (ProgressReport.Configuration.DetectionSteps == DetectionSteps.FacialUnresolved || ProgressReport.Configuration.DetectionSteps == DetectionSteps.Both) { tagResult = readSavedProgress().Item2; ProgressReport.Operation = CurrentOperation.TrainingFaces; Dictionary <string, string> idsAndTags = new Dictionary <string, string>(); for (int i = 0; i < tagResult.Images.Count; i++) { //TODO: set current photo index var image = tagResult.Images[i]; for (int j = 0; j < image.Data.Count; j++) { if (mainBackgroundWorker.CancellationPending) { e.Cancel = true; break; } var face = image.Data[j]; if (face.Resolved) { idsAndTags.Add(face.FaceId, face.ResolvedBib); } } } //train resolved faces LogManager.Info("Starting training resolved faces: " + idsAndTags.Count); //BibDetector.StudyFaces(idsAndTags, ProgressReport.Configuration.Delay); ProgressReport.Operation = CurrentOperation.SearchingUnresolvedFaces; for (int i = 0; i < tagResult.Images.Count; i++) { //TODO: set current photo index var image = tagResult.Images[i]; for (int j = 0; j < image.Data.Count; j++) { var face = image.Data[j]; if (!face.Resolved) { Thread.Sleep(ProgressReport.Configuration.Delay); //search unresolved photo List <FaceSearchModel> samePeople = BibDetector.SearchFace(face.FaceId); if (samePeople != null && samePeople.Count > 0) { int bestIndex = 0; for (int k = bestIndex + 1; i < samePeople.Count; i++) { if (samePeople[i].Confidence > samePeople[bestIndex].Confidence) { bestIndex = i; } } FaceSearchModel bestMatch = samePeople[bestIndex]; face.Resolved = true; face.ResolvedBib = bestMatch.Tag; tagResult.Save(saveDataPath); LogManager.Info("Match \"" + face.FaceId + "\" with BIB \"" + face.ResolvedBib + "\""); } else { LogManager.Warning("No matches for \"" + face.FaceId + "\""); } } } } } #endregion //TODO: saving csv file after detecting each bib number to prevent cancelling and loosing results CsvManager.SaveCsv(report, saveReportPath); }