예제 #1
0
        //public static string GetAggregatedResultString(List<SatyamResultsTableEntry> results,
        //    int MinResults = TaskConstants.OBJECT_COUNTING_MTURK_MIN_RESULTS_TO_AGGREGATE,
        //    int MaxResults = TaskConstants.OBJECT_COUNTING_MTURK_MAX_RESULTS_TO_AGGREGATE,
        //    double MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND = TaskConstants.OBJECT_COUNTING_MTURK_MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND,
        //    double MAX_DEVIATION_FRACTION = TaskConstants.OBJECT_COUNTING_MTURK_MAX_DEVIATION_FRACTION,
        //    double SUPER_MAJORITY_VALUE = TaskConstants.OBJECT_COUNTING_MTURK_SUPER_MAJORITY_VALUE)
        //{
        //    string resultString = null;
        //    List<ObjectCountingResult> resultList = new List<ObjectCountingResult>();
        //    foreach (SatyamResultsTableEntry entry in results)
        //    {
        //        SatyamResult res = JSonUtils.ConvertJSonToObject<SatyamResult>(entry.ResultString);
        //        ObjectCountingResult taskr = JSonUtils.ConvertJSonToObject<ObjectCountingResult>(res.TaskResult);
        //        resultList.Add(taskr);
        //    }
        //    ObjectCountingAggregatedResult r = getAggregatedResult(resultList, MinResults, MaxResults, MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND, MAX_DEVIATION_FRACTION, SUPER_MAJORITY_VALUE);
        //    if (r != null)
        //    {
        //        string rString = JSonUtils.ConvertObjectToJSon<ObjectCountingAggregatedResult>(r);
        //        SatyamAggregatedResult aggResult = new SatyamAggregatedResult();
        //        aggResult.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
        //        aggResult.AggregatedResultString = rString;
        //        SatyamResult res = JSonUtils.ConvertJSonToObject<SatyamResult>(results[0].ResultString);
        //        aggResult.TaskParameters = res.TaskParametersString;
        //        resultString = JSonUtils.ConvertObjectToJSon<SatyamAggregatedResult>(aggResult);
        //    }
        //    return resultString;
        //}


        public static bool IsAcceptable(SatyamAggregatedResultsTableEntry aggResult, SatyamResultsTableEntry result,
                                        double MAX_ABSOLUTE_COUNT_DEVIATION = TaskConstants.OBJECT_COUNTING_MTURK_MAX_ABSOLUTE_COUNT_DEVIATION_FOR_PAYMENT,
                                        double MAX_DEVIATION_FRACTION       = TaskConstants.OBJECT_COUNTING_MTURK_MAX_DEVIATION_FRACTION_FOR_PAYMENT)
        {
            SatyamResult           res    = JSonUtils.ConvertJSonToObject <SatyamResult>(result.ResultString);
            SatyamAggregatedResult aggres = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(aggResult.ResultString);

            ObjectCountingResult           r    = JSonUtils.ConvertJSonToObject <ObjectCountingResult>(res.TaskResult);
            ObjectCountingAggregatedResult ragg = JSonUtils.ConvertJSonToObject <ObjectCountingAggregatedResult>(aggres.AggregatedResultString);

            double maxdev = MAX_ABSOLUTE_COUNT_DEVIATION;

            if (ragg.Count * MAX_DEVIATION_FRACTION > maxdev)
            {
                maxdev = ragg.Count * MAX_DEVIATION_FRACTION;
            }

            if (Math.Abs(ragg.Count - r.Count) <= maxdev)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #2
0
        public static string GetAggregatedResultString(List <SatyamResultsTableEntry> results)
        {
            if (results.Count == 0)
            {
                return(null);
            }

            string resultString = null;
            List <ImageSegmentationResult> resultList = new List <ImageSegmentationResult>();
            List <string> WorkersPerTask = new List <string>();

            SatyamResult res0      = JSonUtils.ConvertJSonToObject <SatyamResult>(results[0].ResultString);
            SatyamTask   task      = JSonUtils.ConvertJSonToObject <SatyamTask>(res0.TaskParametersString);
            string       SatyamURL = task.SatyamURI;
            string       guid      = results[0].JobGUID;

            foreach (SatyamResultsTableEntry entry in results)
            {
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString);

                // remove duplicate workers result
                string workerID = res.amazonInfo.WorkerID;
                if (WorkersPerTask.Contains(workerID))
                {
                    continue;
                }

                string assignmentID = res.amazonInfo.AssignmentID;
                if (assignmentID == "" || assignmentID == "ASSIGNMENT_ID_NOT_AVAILABLE")
                {
                    continue;
                }

                //enclose only non-duplicate results, one per each worker.
                if (workerID != "" && workerID != TaskConstants.AdminID)
                {
                    // make a pass for test and admins
                    WorkersPerTask.Add(workerID);
                }


                ImageSegmentationResult taskr = JSonUtils.ConvertJSonToObject <ImageSegmentationResult>(res.TaskResult);
                resultList.Add(taskr);
            }


            ImageSegmentationAggregatedResult r = getAggregatedResult(resultList, SatyamURL, guid);

            if (r != null)
            {
                string rString = JSonUtils.ConvertObjectToJSon <ImageSegmentationAggregatedResult>(r);
                SatyamAggregatedResult aggResult = new SatyamAggregatedResult();
                aggResult.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
                aggResult.AggregatedResultString = rString;
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(results[0].ResultString);
                aggResult.TaskParameters = res.TaskParametersString;
                resultString             = JSonUtils.ConvertObjectToJSon <SatyamAggregatedResult>(aggResult);
            }
            return(resultString);
        }
예제 #3
0
        public static string GetAggregatedResultString(List <SatyamResultsTableEntry> results,
                                                       int MinResults = TaskConstants.OBJECT_COUNTING_MTURK_MIN_RESULTS_TO_AGGREGATE,
                                                       int MaxResults = TaskConstants.OBJECT_COUNTING_MTURK_MAX_RESULTS_TO_AGGREGATE,
                                                       double MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND = TaskConstants.OBJECT_COUNTING_MTURK_MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND,
                                                       double MAX_DEVIATION_FRACTION = TaskConstants.OBJECT_COUNTING_MTURK_MAX_DEVIATION_FRACTION,
                                                       double SUPER_MAJORITY_VALUE   = TaskConstants.OBJECT_COUNTING_MTURK_SUPER_MAJORITY_VALUE)
        {
            Console.WriteLine("Aggregating");
            string resultString = null;
            List <ObjectCountingResult> resultList       = new List <ObjectCountingResult>();
            List <SatyamResult>         SatyamResultList = new List <SatyamResult>();

            foreach (SatyamResultsTableEntry entry in results)
            {
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString);
                SatyamResultList.Add(res);
                ObjectCountingResult taskr = JSonUtils.ConvertJSonToObject <ObjectCountingResult>(res.TaskResult);
                resultList.Add(taskr);
            }
            //ObjectCountingAggregatedResult r = getAggregatedResult(resultList, MinResults, MaxResults, MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND, MAX_DEVIATION_FRACTION, SUPER_MAJORITY_VALUE);
            ObjectCountingAggregatedResult r = getAggregatedResultUsingWorkerStatistics(SatyamResultList, MinResults, MaxResults, MAX_ABSOLUTE_COUNT_DEVIATION_LOWERBOUND, MAX_DEVIATION_FRACTION, SUPER_MAJORITY_VALUE);

            if (r != null)
            {
                string rString = JSonUtils.ConvertObjectToJSon <ObjectCountingAggregatedResult>(r);
                SatyamAggregatedResult aggResult = new SatyamAggregatedResult();
                aggResult.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
                aggResult.AggregatedResultString = rString;
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(results[0].ResultString);
                aggResult.TaskParameters = res.TaskParametersString;
                resultString             = JSonUtils.ConvertObjectToJSon <SatyamAggregatedResult>(aggResult);
            }
            return(resultString);
        }
        public static string GetAggregatedResultString(List <SatyamResultsTableEntry> results,
                                                       int MinResults = TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MIN_RESULTS_TO_AGGREGATE,
                                                       int MaxResults = TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MAX_RESULTS_TO_AGGREGATE,
                                                       double probabilityThreshold = TaskConstants.SINGLE_OBJECT_LABLING_MTURK_MAJORITY_THRESHOLD)
        {
            string resultString = null;
            List <SingleObjectLabelingResult> resultList = new List <SingleObjectLabelingResult>();

            foreach (SatyamResultsTableEntry entry in results)
            {
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString);
                SingleObjectLabelingResult taskr = JSonUtils.ConvertJSonToObject <SingleObjectLabelingResult>(res.TaskResult);
                resultList.Add(taskr);
            }


            SingleObjectLabelingAggregatedResult r = getAggregatedResult(resultList, MinResults, MaxResults, probabilityThreshold);

            if (r != null)
            {
                string rString = JSonUtils.ConvertObjectToJSon <SingleObjectLabelingAggregatedResult>(r);
                SatyamAggregatedResult aggResult = new SatyamAggregatedResult();
                aggResult.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
                aggResult.AggregatedResultString = rString;
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(results[0].ResultString);
                aggResult.TaskParameters = res.TaskParametersString;
                resultString             = JSonUtils.ConvertObjectToJSon <SatyamAggregatedResult>(aggResult);
            }
            return(resultString);
        }
        public static bool IsAcceptable(SatyamAggregatedResultsTableEntry aggResult, SatyamResultsTableEntry result)
        {
            SatyamResult           res    = JSonUtils.ConvertJSonToObject <SatyamResult>(result.ResultString);
            SatyamAggregatedResult aggres = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(aggResult.ResultString);

            SingleObjectLabelingResult           r    = JSonUtils.ConvertJSonToObject <SingleObjectLabelingResult>(res.TaskResult);
            SingleObjectLabelingAggregatedResult ragg = JSonUtils.ConvertJSonToObject <SingleObjectLabelingAggregatedResult>(aggres.AggregatedResultString);

            if (r.Category == ragg.Category)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #6
0
        public static bool IsAcceptable(
            SatyamAggregatedResultsTableEntry aggResultEntry,
            SatyamResultsTableEntry resultEntry,
            double ACCEPTANCE_NUMBER_OF_POLYGONS_THRESHOLD = TaskConstants.IMAGE_SEGMENTATION_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_PAYMENT, //the person must have made at least 80% of the boxes
            double POLYGON_IOU_THRESHOLD = TaskConstants.IMAGE_SEGMENTATION_MTURK_POLYGON_IOU_THRESHOLD_FOR_PAYMENT
            )
        {
            //most boxes should be within limits
            //most categories should be right
            SatyamAggregatedResult satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(aggResultEntry.ResultString);
            ImageSegmentationAggregatedResult_NoHoles aggresult = JSonUtils.ConvertJSonToObject <ImageSegmentationAggregatedResult_NoHoles>(satyamAggResult.AggregatedResultString);
            SatyamResult satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(resultEntry.ResultString);
            ImageSegmentationResult_NoHoles result = JSonUtils.ConvertJSonToObject <ImageSegmentationResult_NoHoles>(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_POLYGONS_THRESHOLD);

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


            //We fist do a bipartitte matching to find the best assocaition for the boxes
            List <List <GenericPolygon> > allPolygons = new List <List <GenericPolygon> >();

            allPolygons.Add(new List <GenericPolygon>());
            foreach (ImageSegmentationResultSingleEntry_NoHoles entry in result.objects)
            {
                allPolygons[0].Add(entry.polygon);
            }
            allPolygons.Add(new List <GenericPolygon>());
            List <bool> tooSmallToIgnore = new List <bool>();

            foreach (ImageSegmentationResultSingleEntry_NoHoles entry in aggresult.boxesAndCategories.objects)
            {
                allPolygons[1].Add(entry.polygon);
            }
            List <MultipartiteWeightedMatch> polygonAssociation = PolygonAssociation.computeGenericPolygonAssociations(allPolygons);

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

            foreach (MultipartiteWeightedMatch match in polygonAssociation)
            {
                if (match.elementList.ContainsKey(1))     // this contains an aggregated box
                {
                    if (match.elementList.ContainsKey(0)) // a result box has been associated
                    {
                        GenericPolygon aggregatedGenericPolygon = allPolygons[1][match.elementList[1]];
                        GenericPolygon resultGenericPolygon     = allPolygons[0][match.elementList[0]];

                        //double IoU = GenericPolygon.computeIntersectionOverUnion(aggregatedGenericPolygon, resultGenericPolygon);
                        double IoU = 1;

                        if (IoU >= POLYGON_IOU_THRESHOLD)
                        {
                            //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++;
                            }
                        }
                    }
                }
            }

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

            return(false);
        }
예제 #7
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);
        }
예제 #8
0
        public static string GetAggregatedResultString(List <SatyamResultsTableEntry> results)
        {
            if (results.Count == 0)
            {
                return(null);
            }

            List <MultiObjectLocalizationAndLabelingResult> resultList = new List <MultiObjectLocalizationAndLabelingResult>();
            List <string> WorkersPerTask = new List <string>();

            foreach (SatyamResultsTableEntry entry in results)
            {
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(entry.ResultString);

                // remove duplicate workers result
                // "" works for internal test!!!
                string workerID = res.amazonInfo.WorkerID;
                if (workerID != "" && WorkersPerTask.Contains(workerID))
                {
                    continue;
                }
                //enclose only non-duplicate results, one per each worker.
                WorkersPerTask.Add(workerID);

                MultiObjectLocalizationAndLabelingResult taskr = JSonUtils.ConvertJSonToObject <MultiObjectLocalizationAndLabelingResult>(res.TaskResult);
                resultList.Add(taskr);
            }

            /// Store Progressive results in progressive table, for consensus loading on turker task pages.
            // check  if there are any new valid results first
            SatyamAggregatedProgressiveResultsTableAccess progDBtemp = new SatyamAggregatedProgressiveResultsTableAccess();
            int LatestResultsAggregated = progDBtemp.getLatestNoResultsAggregatedByTaskID(results[0].SatyamTaskTableEntryID);// default value is -1

            progDBtemp.close();

            if (LatestResultsAggregated >= resultList.Count)
            {
                return(null);
            }
            /// safely return null here, since if it's aggregated by standard, it won't be executed again.
            /// it will be only executed when there is no standard aggregation result.
            /// so return null when no new results came in to even produce a progress aggregation result.


            int MaxCount = Math.Min(resultList.Count, TaskConstants.MULTI_OBJECT_LOCALIZATION_AND_LABLING_MTURK_MAX_RESULTS_TO_AGGREGATE);
            MultiObjectLocalizationAndLabelingAggregatedResult tempr = getAggregatedResult(resultList, MinResults: 2);

            if (tempr != null)
            {
                string rString = JSonUtils.ConvertObjectToJSon <MultiObjectLocalizationAndLabelingAggregatedResult>(tempr);
                SatyamAggregatedResult aggResult = new SatyamAggregatedResult();
                aggResult.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
                aggResult.AggregatedResultString = rString;
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(results[0].ResultString);
                aggResult.TaskParameters = res.TaskParametersString;
                string resultString = JSonUtils.ConvertObjectToJSon <SatyamAggregatedResult>(aggResult);

                // create progressive entry
                SatyamAggregatedProgressiveResultsTableEntry aggProgEntry = new SatyamAggregatedProgressiveResultsTableEntry();
                aggProgEntry.JobGUID                = results[0].JobGUID;
                aggProgEntry.JobTemplateType        = results[0].JobTemplateType;
                aggProgEntry.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
                aggProgEntry.UserID            = results[0].UserID;
                aggProgEntry.ResultString      = resultString;
                aggProgEntry.ResultsAggregated = resultList.Count; // use the actual valid non-duplicate results number here.
                SatyamAggregatedProgressiveResultsTableAccess aggProgDB = new SatyamAggregatedProgressiveResultsTableAccess();
                aggProgDB.AddEntry(aggProgEntry);
                aggProgDB.close();
            }
            else
            {
                return(null);
            }


            MultiObjectLocalizationAndLabelingAggregatedResult r = getAggregatedResult(resultList);

            if (r != null)
            {
                string rString = JSonUtils.ConvertObjectToJSon <MultiObjectLocalizationAndLabelingAggregatedResult>(r);
                SatyamAggregatedResult aggResult = new SatyamAggregatedResult();
                aggResult.SatyamTaskTableEntryID = results[0].SatyamTaskTableEntryID;
                aggResult.AggregatedResultString = rString;
                SatyamResult res = JSonUtils.ConvertJSonToObject <SatyamResult>(results[0].ResultString);
                aggResult.TaskParameters = res.TaskParametersString;
                string resultString = JSonUtils.ConvertObjectToJSon <SatyamAggregatedResult>(aggResult);
                return(resultString);
            }
            else
            {
                return(null);
            }
        }
예제 #9
0
        public static bool IsAcceptable(
            SatyamAggregatedResultsTableEntry aggResultEntry,
            SatyamResultsTableEntry resultEntry,
            double APPROVAL_RATIO_OF_POLYGONS_THRESHOLD = TaskConstants.IMAGE_SEGMENTATION_MTURK_OBJECT_COVERAGE_THRESHOLD_FOR_PAYMENT, //the person must have made at least 80% of the polygon
            double POLYGON_IOU_THRESHOLD = TaskConstants.IMAGE_SEGMENTATION_MTURK_POLYGON_IOU_THRESHOLD_FOR_PAYMENT
            )
        {
            //most boxes should be within limits
            //most categories should be right
            SatyamAggregatedResult            satyamAggResult = JSonUtils.ConvertJSonToObject <SatyamAggregatedResult>(aggResultEntry.ResultString);
            ImageSegmentationAggregatedResult aggresult       = JSonUtils.ConvertJSonToObject <ImageSegmentationAggregatedResult>(satyamAggResult.AggregatedResultString);
            SatyamResult            satyamResult = JSonUtils.ConvertJSonToObject <SatyamResult>(resultEntry.ResultString);
            ImageSegmentationResult result       = JSonUtils.ConvertJSonToObject <ImageSegmentationResult>(satyamResult.TaskResult);

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

            //first check if the number of boxes are within limit
            // the objects are dummy polygons just for counting
            int boxLimit = (int)Math.Ceiling((double)aggresult.boxesAndCategories.objects.Count * APPROVAL_RATIO_OF_POLYGONS_THRESHOLD);

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


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

            byte[] resPNG = ImageSegmentationResult.PolygonResult2Bitmap(result);

            int width = -1; int height = -1;

            byte[] aggPNG = ImageUtilities.readPNGRawDataFromURL(aggresult.metaData.PNG_URL, out width, out height);

            if (resPNG.Length != aggPNG.Length)
            {
                Console.WriteLine("res and agg res are different size");
                return(false);
            }

            SortedDictionary <int, SortedDictionary <int, int> > overlapping = new SortedDictionary <int, SortedDictionary <int, int> >();
            SortedDictionary <int, int> resObjectArea = new SortedDictionary <int, int>();
            SortedDictionary <int, int> aggObjectArea = new SortedDictionary <int, int>();

            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    int idx      = j * width + i;
                    int resObjID = resPNG[idx];
                    int aggObjID = aggPNG[idx];
                    if (!overlapping.ContainsKey(resObjID))
                    {
                        overlapping.Add(resObjID, new SortedDictionary <int, int>());
                    }
                    if (!overlapping[resObjID].ContainsKey(aggObjID))
                    {
                        overlapping[resObjID].Add(aggObjID, 0);
                    }

                    overlapping[resObjID][aggObjID]++;

                    if (!resObjectArea.ContainsKey(resObjID))
                    {
                        resObjectArea.Add(resObjID, 0);
                    }
                    resObjectArea[resObjID]++;

                    if (!aggObjectArea.ContainsKey(aggObjID))
                    {
                        aggObjectArea.Add(aggObjID, 0);
                    }
                    aggObjectArea[aggObjID]++;
                }
            }

            foreach (int id in resObjectArea.Keys)
            {
                if (id == 0)
                {
                    continue;
                }

                int maxOverlap         = -1;
                int maxOverlapAggObjID = -1;


                SortedDictionary <int, int> overlapArea = overlapping[id];
                foreach (int aggid in overlapArea.Keys)
                {
                    if (aggid == 0)
                    {
                        continue;
                    }
                    if (overlapArea[aggid] > maxOverlap)
                    {
                        maxOverlap         = overlapArea[aggid];
                        maxOverlapAggObjID = aggid;
                    }
                }

                if (maxOverlapAggObjID == -1)
                {
                    continue;
                }

                double iou = (double)maxOverlap / (double)(resObjectArea[id] + aggObjectArea[maxOverlapAggObjID] - maxOverlap);

                if (iou >= POLYGON_IOU_THRESHOLD)
                {
                    noAccepted++;
                    ////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

                    //}
                }
            }



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

            return(false);
        }