Beispiel #1
0
        public static List <BoundingBoxGroup> GreedyMeanHierarchicalMergeByPixelDeviation(List <BoundingBox> originalBoundingBoxes, List <string> originalIdentifiers, double deviationToleranceThresholdX, double deviationToleranceThresholdY)
        {
            List <BoundingBoxGroup> ret = new List <BoundingBoxGroup>();

            //initialize by creating one group per bounding box
            for (int i = 0; i < originalBoundingBoxes.Count; i++)
            {
                BoundingBox      b      = originalBoundingBoxes[i];
                BoundingBoxGroup bgroup = new BoundingBoxGroup();
                bgroup.mergedBoundingBox = new BoundingBox(b.tlx, b.tly, b.brx, b.bry);
                bgroup.boundingBoxList.Add(b);
                bgroup.identifiers.Add(originalIdentifiers[i]);
                ret.Add(bgroup);
            }

            bool changed = false;

            do
            {
                changed = false;
                //find the closest mergable bouding box group pair and merge by averaging
                int index1 = -1;
                int index2 = -1;
                //double bestSimilarity = 0;
                double      bestDeviation         = 10000000000;
                BoundingBox bestMergedBoundingBox = null;
                for (int i = 0; i < ret.Count - 1; i++)
                {
                    for (int j = i + 1; j < ret.Count; j++)
                    {
                        //compute the merged bouding box
                        BoundingBox meanB        = computeMeanBoudingBoxFromTwoGroups(ret[i].boundingBoxList, ret[j].boundingBoxList);
                        double      deviation1   = meanB.ComputeNormalizedMaxDeviationMetric(ret[i].mergedBoundingBox, deviationToleranceThresholdX, deviationToleranceThresholdY);
                        double      deviation2   = meanB.ComputeNormalizedMaxDeviationMetric(ret[j].mergedBoundingBox, deviationToleranceThresholdX, deviationToleranceThresholdY);
                        double      maxDeviation = Math.Max(deviation1, deviation2);
                        if (maxDeviation <= 1)
                        {
                            if (maxDeviation < bestDeviation)
                            {
                                bestDeviation         = maxDeviation;
                                index1                = i;
                                index2                = j;
                                bestMergedBoundingBox = meanB;
                                changed               = true;
                            }
                        }
                    }
                }

                if (changed) //there is something worth merging
                {
                    //merge 2 into 1
                    for (int i = 0; i < ret[index2].boundingBoxList.Count; i++)
                    {
                        ret[index1].boundingBoxList.Add(ret[index2].boundingBoxList[i]);
                        ret[index1].identifiers.Add(ret[index2].identifiers[i]);
                    }
                    ret[index1].mergedBoundingBox = bestMergedBoundingBox;

                    //remove 2
                    ret.RemoveAt(index2);
                }
                if (ret.Count == 1)
                {
                    break;
                }
            } while (changed);

            return(ret);
        }
Beispiel #2
0
        public static double ACCEPTANCE_NUMBER_OF_BOXES_THRESHOLD = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_PAYMENT; //the person must have made at least 80% of the boxes
        public static bool IsAcceptable(SatyamAggregatedResultsTableEntry aggResultEntry, SatyamResultsTableEntry resultEntry,
                                        double DeviationPixelThreshold = TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_DEVIATION_THRESHOLD_FOR_PAYMENT)
        {
            //most boxes should be within limits
            //most categories should be right
            SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(aggResultEntry.ResultString);
            MultiObjectLocalizationAndLabelingAggregatedResult aggresult = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingAggregatedResult>(satyamAggResult.AggregatedResultString);
            SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(resultEntry.ResultString);
            MultiObjectLocalizationAndLabelingResult result = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingResult>(satyamResult.TaskResult);

            if (result == null)
            {
                return(false);
            }

            //first check if the number of boxes are within limit
            int boxLimit = (int)Math.Ceiling((double)aggresult.boxesAndCategories.objects.Count * ACCEPTANCE_NUMBER_OF_BOXES_THRESHOLD);

            if (result.objects.Count < boxLimit)
            {
                return(false);
            }

            double minboxdimension_threshold_x = MIN_BOX_DIMENSION_FOR_CONSIDERATION * result.displayScaleReductionX;
            double minboxdimension_threshold_y = MIN_BOX_DIMENSION_FOR_CONSIDERATION * result.displayScaleReductionY;
            //We fist do a bipartitte matching to find the best assocaition for the boxes
            List <List <BoundingBox> > allboxes = new List <List <BoundingBox> >();

            allboxes.Add(new List <BoundingBox>());
            foreach (MultiObjectLocalizationAndLabelingResultSingleEntry entry in result.objects)
            {
                allboxes[0].Add(entry.boundingBox);
            }
            allboxes.Add(new List <BoundingBox>());
            List <bool> tooSmallToIgnore = new List <bool>();

            foreach (MultiObjectLocalizationAndLabelingResultSingleEntry entry in aggresult.boxesAndCategories.objects)
            {
                allboxes[1].Add(entry.boundingBox);
                if (entry.boundingBox.getWidth() < minboxdimension_threshold_x && entry.boundingBox.getHeight() < minboxdimension_threshold_y)
                {
                    tooSmallToIgnore.Add(true);
                }
                else
                {
                    tooSmallToIgnore.Add(false);
                }
            }
            List <MultipartiteWeightedMatch> boxAssociation = BoundingBoxAssociation.computeBoundingBoxAssociations(allboxes);

            //now find how many of the results match aggregated results
            int noAccepted = 0;

            double deviation_threshold_x = DeviationPixelThreshold * result.displayScaleReductionX;
            double deviation_threshold_y = DeviationPixelThreshold * result.displayScaleReductionY;

            int noIgnorable = 0;

            foreach (MultipartiteWeightedMatch match in boxAssociation)
            {
                if (match.elementList.ContainsKey(1))     // this contains an aggregated box
                {
                    if (match.elementList.ContainsKey(0)) // a result box has been associated
                    {
                        BoundingBox aggregatedBoundingBox = allboxes[1][match.elementList[1]];
                        BoundingBox resultBoundingBox     = allboxes[0][match.elementList[0]];
                        //double deviation = aggregatedBoundingBox.ComputeMaxDeviationMetric(resultBoundingBox);
                        double deviation = aggregatedBoundingBox.ComputeNormalizedMaxDeviationMetric(resultBoundingBox, deviation_threshold_x, deviation_threshold_y);
                        if (deviation <= 1) //deviation test passed
                        {
                            //now check category
                            if (result.objects[match.elementList[0]].Category == aggresult.boxesAndCategories.objects[match.elementList[1]].Category)
                            {
                                //both category and bounding box tests have passed
                                noAccepted++;
                            }
                        }
                        else
                        {
                            if (tooSmallToIgnore[match.elementList[1]])
                            {
                                noIgnorable++;
                            }
                        }
                    }
                }
            }

            if (noAccepted >= boxLimit - noIgnorable)
            {
                return(true);
            }

            return(false);
        }