public static Image DrawImageDetectionResult(MultiObjectLocalizationAndLabelingResult res, string image_url, List <string> Categories) { Image originalImage = ImageUtilities.getImageFromURI(image_url); List <Rectangle> rectangles = new List <Rectangle>(); List <Color> colors = new List <Color>(); List <string> ids = new List <string>(); List <bool> dashed = new List <bool>(); for (int j = 0; j < res.objects.Count; j++) { MultiObjectLocalizationAndLabelingResultSingleEntry box = res.objects[j]; int x = box.boundingBox.tlx; int y = box.boundingBox.tly; int width = box.boundingBox.brx - box.boundingBox.tlx; int height = box.boundingBox.bry - box.boundingBox.tly; Rectangle r = new Rectangle(x, y, width, height); rectangles.Add(r); string category = box.Category; int colorIndex = Categories.IndexOf(category); colors.Add(DrawingBoxesAndLinesOnImages.Colors[colorIndex]); string id = j + "-" + category; ids.Add(id); dashed.Add(false); } Image imageWithBoxes = DrawingBoxesAndLinesOnImages.addRectanglesToImage(originalImage, rectangles, colors, ids, dashed); return(imageWithBoxes); }
public static MultiObjectLocalizationAndLabelingResult GetImageDetectionResult(string image_url, List <string> Categories) { MultiObjectLocalizationAndLabelingResult ret = new MultiObjectLocalizationAndLabelingResult(); int height = 0; int width = 0; PredictResponse res = ImageDetectionRequest(image_url, out height, out width); //float score_threshold = int class_counts = res.Outputs["detection_classes"].FloatVal.Count; float[] classes = new float[class_counts]; res.Outputs["detection_classes"].FloatVal.CopyTo(classes, 0); int box_counts = res.Outputs["detection_boxes"].FloatVal.Count; float[] boxes = new float[box_counts]; res.Outputs["detection_boxes"].FloatVal.CopyTo(boxes, 0); int score_counts = res.Outputs["detection_scores"].FloatVal.Count; float[] scores = new float[score_counts]; res.Outputs["detection_scores"].FloatVal.CopyTo(scores, 0); double score_threshold = 0.5; for (int i = 0; i < score_counts; i++) { float s = scores[i]; if (s == 0) { break; } if (s < score_threshold) { continue; } int c = (int)classes[i] - 1; // comes in as ymin, xmin, ymax, xmax int tlx = (int)(boxes[4 * i + 1] * width); int tly = (int)(boxes[4 * i] * height); int brx = (int)(boxes[4 * i + 3] * width); int bry = (int)(boxes[4 * i + 2] * height); MultiObjectLocalizationAndLabelingResultSingleEntry e = new MultiObjectLocalizationAndLabelingResultSingleEntry(); e.boundingBox = new BoundingBox(tlx, tly, brx, bry); e.Category = Categories[c]; ret.objects.Add(e); } ret.imageHeight = height; ret.imageWidth = width; return(ret); }
private static void ValidateSatyamKITTIObjectCountingAggregationResult(List <SatyamAggregatedResultsTableEntry> aggResultEntries, //bool saveImage = false, out double totalError, out double totalGroundTruth, int MinHeight = TaskConstants.OBJECT_COUNTING_VALIDATION_MIN_HEIGHT, int MaxOcclusion = TaskConstants.OBJECT_COUNTING_VALIDATION_MAX_OCCLUSION, double Max_Truncation = TaskConstants.OBJECT_COUNTING_VALIDATION_MIN_TRUNCATION) { List <double> aggResultCounts = new List <double>(); List <int> GroundTruthCounts = new List <int>(); List <double> errors = new List <double>(); foreach (SatyamAggregatedResultsTableEntry aggResultEntry in aggResultEntries) { SatyamSaveAggregatedDataSatyam data = new SatyamSaveAggregatedDataSatyam(aggResultEntry); string fileName = URIUtilities.filenameFromURINoExtension(data.SatyamURI); KITTIDetectionGroundTruth GroundTruthObjects = new KITTIDetectionGroundTruth(KITTIDetectionResultValidation.GroundTruthLabelDirectory + fileName + ".txt", MinHeight, MaxOcclusion, Max_Truncation); string jobGUID = aggResultEntry.JobGUID; int taskID = aggResultEntry.SatyamTaskTableEntryID; String resultString = data.AggregatedResultString; ObjectCountingAggregatedResult result = JSonUtils.ConvertJSonToObject <ObjectCountingAggregatedResult>(resultString); int GroundtruthCount = 0; for (int i = 0; i < GroundTruthObjects.objects.Count; i++) { MultiObjectLocalizationAndLabelingResultSingleEntry obj = GroundTruthObjects.objects[i]; //if (obj.Category == "Car" || obj.Category == "Van" || obj.Category == "DontCare") if (obj.Category == "Car" || obj.Category == "Van") { //if (!GroundTruthObjects.BlackListed[i]) //{ GroundtruthCount++; //} } } aggResultCounts.Add(result.Count); GroundTruthCounts.Add(GroundtruthCount); errors.Add(Math.Abs(GroundtruthCount - result.Count)); } totalError = errors.Sum(); totalGroundTruth = GroundTruthCounts.Sum(); double totalErrorRatio = totalError / totalGroundTruth; Console.WriteLine("Error: {0} / {1} = {2}", totalError, totalGroundTruth, totalErrorRatio); Console.WriteLine("Total Aggregated {0}", aggResultEntries.Count); }
public static void testJSONString() { MultiObjectLocalizationAndLabelingResult res = new MultiObjectLocalizationAndLabelingResult(); res.objects = new List <MultiObjectLocalizationAndLabelingResultSingleEntry>(); MultiObjectLocalizationAndLabelingResultSingleEntry entry = new MultiObjectLocalizationAndLabelingResultSingleEntry(); entry.boundingBox = new BoundingBox(5, 15, 25, 35); entry.Category = "Car"; res.objects.Add(entry); entry = new MultiObjectLocalizationAndLabelingResultSingleEntry(); entry.boundingBox = new BoundingBox(45, 55, 65, 75); entry.Category = "Bus"; res.objects.Add(entry); string jsonString = JSonUtils.ConvertObjectToJSon <MultiObjectLocalizationAndLabelingResult>(res); }
public static MultiObjectLocalizationAndLabelingAggregatedResult getAggregatedResult(List <MultiObjectLocalizationAndLabelingResult> results, int MinResults = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MIN_RESULTS_TO_AGGREGATE, int MaxResults = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MAX_RESULTS_TO_AGGREGATE, double CategoryMajorityThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MAJORITY_CATEGORY_THRESHOLD, double ObjectsCoverageThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_AGGREGATION_TERMINATION, double DeviationPixelThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_DEVIATION_THRESHOLD ) { if (results.Count < MinResults) { return(null); } //if the image was scaled down during display, errors get scaled up //so we need to scale our deviation thresholds double minboxdimension_threshold_x = MIN_BOX_DIMENSION_FOR_CONSIDERATION * results[0].displayScaleReductionX; double minboxdimension_threshold_y = MIN_BOX_DIMENSION_FOR_CONSIDERATION * results[0].displayScaleReductionY; //first use multipartitie wieghted matching to associated the boxes disregarding the labels since //people might make mistake with lables but boxes are usually right List <List <BoundingBox> > allboxes = new List <List <BoundingBox> >(); List <int> noBoxesPerResult = new List <int>(); //how many boxes did each person draw? List <List <bool> > largeBoxes = new List <List <bool> >(); //was this box was bigger than MIN_BOX_DIMENSION_FOR_CONSIDERATION? foreach (MultiObjectLocalizationAndLabelingResult res in results) { allboxes.Add(new List <BoundingBox>()); largeBoxes.Add(new List <bool>()); if (res == null) { noBoxesPerResult.Add(0); continue; } List <BoundingBox> boxList = allboxes[allboxes.Count - 1]; List <bool> largeBoxList = largeBoxes[largeBoxes.Count - 1]; foreach (MultiObjectLocalizationAndLabelingResultSingleEntry entry in res.objects) { boxList.Add(entry.boundingBox); if (entry.boundingBox.getWidth() < minboxdimension_threshold_x && entry.boundingBox.getHeight() < minboxdimension_threshold_y) { largeBoxList.Add(false); } else { largeBoxList.Add(true); } } noBoxesPerResult.Add(boxList.Count); } //now associate boxes across the various results List <MultipartiteWeightedMatch> boxAssociation = BoundingBoxAssociation.computeBoundingBoxAssociations(allboxes); int noBoxes = boxAssociation.Count; int noAssociatedBoxes = 0; int noIgnorable = 0; //how many of the drawn boxes for each result were actually associated by two or more people for each user? SortedDictionary <int, int> noMultipleAssociatedBoxesPerResult = new SortedDictionary <int, int>(); SortedDictionary <int, int> noSmallIgnorableBoxesPerResult = new SortedDictionary <int, int>(); for (int i = 0; i < results.Count; i++) { noMultipleAssociatedBoxesPerResult.Add(i, 0); noSmallIgnorableBoxesPerResult.Add(i, 0); } foreach (MultipartiteWeightedMatch match in boxAssociation) { if (match.elementList.Count > 1) //this has been corroborated by two people { noAssociatedBoxes++; foreach (KeyValuePair <int, int> entry in match.elementList) { noMultipleAssociatedBoxesPerResult[entry.Key]++; } } else { List <int> keys = match.elementList.Keys.ToList(); if (largeBoxes[keys[0]][match.elementList[keys[0]]] == false) //the box was a small box can be ignored { noIgnorable++; noSmallIgnorableBoxesPerResult[keys[0]]++; } } } //count how many people have a high association ratio int noHighAssociationRatio = 0; for (int i = 0; i < results.Count; i++) { if (noBoxesPerResult[i] == 0) { continue; } double ratio = ((double)noMultipleAssociatedBoxesPerResult[i] + (double)noSmallIgnorableBoxesPerResult[i]) / (double)noBoxesPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noHighAssociationRatio++; } } if (noHighAssociationRatio < MinResults) //at least three people should have all their boxes highly corroborated by one other person { return(null); } //now we have to find out if the boxes were drawn well and only take the boxes that are within //a reasonable deviation of each other. //if the image was scaled down during display, errors get scaled up //so we need to scale our deviation thresholds double deviation_threshold_x = DeviationPixelThreshold * results[0].displayScaleReductionX; double deviation_threshold_y = DeviationPixelThreshold * results[0].displayScaleReductionY; int noAcceptedBoxes = 0; int noSmallIgnore = 0; List <List <BoundingBoxGroup> > allBoxGroups = new List <List <BoundingBoxGroup> >(); List <BoundingBox> finalBoxes = new List <BoundingBox>(); //stores the aggregated boxes SortedDictionary <int, List <int> > HighQualityAssociatedBoxPerResult = new SortedDictionary <int, List <int> >(); foreach (MultipartiteWeightedMatch match in boxAssociation) { List <BoundingBox> boxList = new List <BoundingBox>(); List <string> identifiers = new List <string>(); foreach (KeyValuePair <int, int> entry in match.elementList) { boxList.Add(allboxes[entry.Key][entry.Value]); identifiers.Add(entry.Key + "_" + entry.Value); } //List<BoundingBoxGroup> boxGroups = MergeAndGroupBoundingBoxes.GreedyMeanHierarchicalMergeByPixelDeviation(boxList, identifiers, DEVIATION_THRESHOLD); List <BoundingBoxGroup> boxGroups = MergeAndGroupBoundingBoxes.GreedyMeanHierarchicalMergeByPixelDeviation(boxList, identifiers, deviation_threshold_x, deviation_threshold_y); allBoxGroups.Add(boxGroups); int maxCount = 0; int index = -1; getMaxCountGroup(boxGroups, out maxCount, out index); ////find the boxgroup with the maxCount //int maxCount = 0; //int index = -1; //for(int i=0;i<boxGroups.Count;i++) //{ // if(boxGroups[i].boundingBoxList.Count > maxCount) // there are two boxes within acceptance range // { // maxCount = boxGroups[i].boundingBoxList.Count; // index = i; // } //} if (maxCount > 1) { noAcceptedBoxes++; finalBoxes.Add(boxGroups[index].mergedBoundingBox); // count the majority group high associations foreach (string id in boxGroups[index].identifiers) { string[] fields = id.Split('_'); int partId = Convert.ToInt32(fields[0]); int boxId = Convert.ToInt32(fields[1]); if (!HighQualityAssociatedBoxPerResult.ContainsKey(partId)) { HighQualityAssociatedBoxPerResult.Add(partId, new List <int>()); } HighQualityAssociatedBoxPerResult[partId].Add(boxId); } } else { finalBoxes.Add(BoundingBox.NullBoundingBox); //were all the boxes drawn too small? bool small = true; for (int i = 0; i < boxGroups.Count; i++) { string[] parts = boxGroups[i].identifiers[0].Split('_'); int resultNo = Convert.ToInt32(parts[0]); int boxNo = Convert.ToInt32(parts[1]); if (largeBoxes[resultNo][boxNo] == true) { small = false; break; } } if (small) { noSmallIgnore++; } } } if (((double)noAcceptedBoxes + (double)noSmallIgnore) / (double)noAssociatedBoxes < ObjectsCoverageThreshold && results.Count < MaxResults) //this is acceptable { return(null); } //count how many people have a high "quality" association ratio int noResultsWithHighQualityObjectCoverage = 0; for (int i = 0; i < results.Count; i++) { if (noBoxesPerResult[i] == 0) { continue; } if (!HighQualityAssociatedBoxPerResult.ContainsKey(i)) { continue; } double ratio = ((double)HighQualityAssociatedBoxPerResult[i].Count) / (double)noBoxesPerResult[i]; if (ratio > ObjectsCoverageThreshold) { noResultsWithHighQualityObjectCoverage++; } } if (noResultsWithHighQualityObjectCoverage < MinResults && results.Count < MaxResults) //at least three people should have most of their boxes highly corroborated by one other person { return(null); } //now we need to see if the categores have a supermajority List <string> finalCategories = new List <string>(); //stores the aggregated categories int cntr = -1; foreach (MultipartiteWeightedMatch match in boxAssociation) { cntr++; if (BoundingBox.IsNullBoundingBox(finalBoxes[cntr])) //this is not an acceptable box { finalCategories.Add(""); continue; } Dictionary <string, int> categoryNames = new Dictionary <string, int>(); int totalCount = match.elementList.Count; int maxCount = 0; string maxCategory = ""; foreach (KeyValuePair <int, int> entry in match.elementList) { string category = results[entry.Key].objects[entry.Value].Category; if (!categoryNames.ContainsKey(category)) { categoryNames.Add(category, 0); } categoryNames[category]++; if (maxCount < categoryNames[category]) { maxCount = categoryNames[category]; maxCategory = category; } } double probability = ((double)maxCount + 1) / ((double)totalCount + 2); if (probability < CategoryMajorityThreshold && results.Count < MaxResults) //this is not a valid category need more work { return(null); } else { finalCategories.Add(maxCategory); } } //now we have enough information to create the aggregate results MultiObjectLocalizationAndLabelingAggregatedResult aggResult = new MultiObjectLocalizationAndLabelingAggregatedResult(); aggResult.metaData = new MultiObjectLocalizationAndLabelingAggregatedResultMetaData(); aggResult.metaData.TotalCount = results.Count; aggResult.boxesAndCategories = new MultiObjectLocalizationAndLabelingResult(); aggResult.boxesAndCategories.objects = new List <MultiObjectLocalizationAndLabelingResultSingleEntry>(); cntr = -1; foreach (MultipartiteWeightedMatch match in boxAssociation) { cntr++; if (BoundingBox.IsNullBoundingBox(finalBoxes[cntr])) { continue; } MultiObjectLocalizationAndLabelingResultSingleEntry entry = new MultiObjectLocalizationAndLabelingResultSingleEntry(); entry.boundingBox = finalBoxes[cntr]; entry.Category = finalCategories[cntr]; aggResult.boxesAndCategories.objects.Add(entry); } aggResult.boxesAndCategories.displayScaleReductionX = results[0].displayScaleReductionX; aggResult.boxesAndCategories.displayScaleReductionY = results[0].displayScaleReductionY; aggResult.boxesAndCategories.imageHeight = results[0].imageHeight; aggResult.boxesAndCategories.imageWidth = results[0].imageWidth; return(aggResult); }
public static void SaveResultImagesLocally(List <SatyamResultsTableEntry> entries, string directoryName) { if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } directoryName = directoryName + "\\Raw"; if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } for (int i = 0; i < entries.Count; i++) { SatyamResultsTableEntry entry = entries[i]; SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString); SatyamTask task = JSonUtils.ConvertJSonToObject <SatyamTask>(satyamResult.TaskParametersString); SatyamJob job = task.jobEntry; MultiObjectLocalizationAndLabelingResult res = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingResult>(satyamResult.TaskResult); string ofilename = URIUtilities.filenameFromURI(task.SatyamURI); string[] fields = ofilename.Split('.'); string fileName = fields[0]; Image originalImage = ImageUtilities.getImageFromURI(task.SatyamURI); MultiObjectLocalizationAndLabelingSubmittedJob jobDefinition = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingSubmittedJob>(job.JobParameters); Image imageWithBoundary = DrawingBoxesAndLinesOnImages.addLinesToImage(originalImage, jobDefinition.BoundaryLines, Color.Red, true); List <Rectangle> rectangles = new List <Rectangle>(); List <Color> colors = new List <Color>(); List <string> ids = new List <string>(); List <bool> dashed = new List <bool>(); for (int j = 0; j < res.objects.Count; j++) { MultiObjectLocalizationAndLabelingResultSingleEntry box = res.objects[j]; int x = box.boundingBox.tlx; int y = box.boundingBox.tly; int width = box.boundingBox.brx - box.boundingBox.tlx; int height = box.boundingBox.bry - box.boundingBox.tly; Rectangle r = new Rectangle(x, y, width, height); rectangles.Add(r); string category = box.Category; int colorIndex = jobDefinition.Categories.IndexOf(category); colors.Add(DrawingBoxesAndLinesOnImages.Colors[colorIndex]); string id = j + "-" + category; ids.Add(id); dashed.Add(false); } Image imageWithBoxesAndBoundary = DrawingBoxesAndLinesOnImages.addRectanglesToImage(imageWithBoundary, rectangles, colors, ids, dashed); fileName = fileName + "-Result"; if (satyamResult.amazonInfo.AssignmentID != "") { //fileName = fileName + "-" + satyamResult.amazonInfo.AssignmentID + "_" + entry.ID; fileName = fileName + "-" + entry.ID + "_" + satyamResult.PrevResultID; } ImageUtilities.saveImage(imageWithBoxesAndBoundary, directoryName, fileName); } }