} // SubsetJsonDetectorOutputbyQuery

        private JsonData SubsetJsonDetectorOutputbyConfidence(JsonData data, SubsetJsonDetectorOutputOptions options)
        {
            if (options.ConfidenceThreshold == -1)
            {
                return(data);
            }

            var          imagesIn  = data.images;
            List <Image> imagesOut = new List <Image>();

            long count      = 0;
            int  maxChanges = 0;
            long totalCount = imagesIn.Count();

            string progressMsg = string.Empty;

            int[] progressPercentagesForDisplay = { 10, 20, 40, 80, 100 };

            progressMsg = string.Format("Subsetting by confidence >= {0}", options.ConfidenceThreshold.ToString());

            foreach (var item in imagesIn)
            {
                count++;

                int percentage = SharedFunctions.GetProgressPercentage(count, totalCount);
                if (progressPercentagesForDisplay.Contains(percentage))
                {
                    SetLabelProgressMsg(progressMsg, count, totalCount, ProgressBarStyle.Blocks);
                }

                dynamic          p;
                dynamic          pOrig      = item.max_detection_conf;
                List <Detection> detections = new List <Detection>();

                // detections = [d for d in im['detections'] if d['conf'] >= options.confidence_threshold]

                // Find all detections above threshold for this image
                foreach (var d in item.detections)
                {
                    dynamic conf = d.conf;
                    if (conf >= options.ConfidenceThreshold)
                    {
                        detections.Add(d);
                    }
                }

                // If there are no detections above threshold, set the max probability
                // to -1, unless it already had a negative probability.
                if (detections.Count == 0)
                {
                    if (pOrig <= 0)
                    {
                        p = pOrig;
                    }
                    else
                    {
                        p = -1;
                    }
                }

                // Otherwise find the maximum confidence
                else
                {
                    p = -1;
                    foreach (var c in detections)
                    {
                        dynamic confidence = c.conf;
                        if (confidence > p)
                        {
                            p = confidence;
                        }
                    }
                }

                item.detections = detections.ToArray();

                // Did this thresholding result in a max-confidence change?
                if (Math.Abs(pOrig - p) > 0.00001)
                {
                    // We should only be *lowering* max confidence values (i.e., making them negative)
                    if (!(pOrig <= 0 || p < pOrig))
                    {
                        string errmsg = string.Format("Confidence changed from {0} to {1}", pOrig, p);

                        // This will get handled by the UI
                        throw new Exception(errmsg);
                    }
                    maxChanges += 1;
                }

                item.max_detection_conf = p;
                imagesOut.Add(item);
            } // for each image

            data.images = imagesOut;

            SetStatusMessage(string.Format("Finished confidence search, found {0} matches (of {1}), {2} max conf changes", data.images.Count().ToString(),
                                           imagesIn.Count().ToString(), maxChanges.ToString()));

            return(data);
        } // SubsetJsonDetectorOutputbyConfidence
        } // SubsetJsonDetectorOutputMain

        private JsonData SubsetJsonDetectorOutputbyQuery(JsonData data, SubsetJsonDetectorOutputOptions options)
        {
            // Subset to images whose filename matches options.query; replace all instances of
            // options.query with options.replacement.
            string progressMsg = string.Empty;

            var          imagesIn  = data.images;
            List <Image> imagesOut = new List <Image>();

            long count      = 0;
            int  percentage = 0;
            long totalCount = imagesIn.Count();

            int[] progressPercentagesForDisplay = { 10, 20, 40, 80, 90, 100 };

            progressMsg = string.Format("Subsetting by query {0}, replacement {1} ...", options.Query, options.Replacement);

            SetLabelProgressMsg(progressMsg, ProgressBarStyle.Marquee);

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            foreach (var image in imagesIn)
            {
                count++;

                string file = image.file.ToString();

                if (!string.IsNullOrEmpty(options.Query) && !file.Contains(options.Query))
                {
                    continue;
                }

                if (!string.IsNullOrEmpty(options.Replacement))
                {
                    if (!string.IsNullOrEmpty(options.Query))
                    {
                        file = file.Replace(options.Query, options.Replacement);
                    }
                    else
                    {
                        file = options.Replacement + file;
                    }
                }
                percentage = SharedFunctions.GetProgressPercentage(count, totalCount);
                if (progressPercentagesForDisplay.Contains(percentage))
                {
                    progressMsg = string.Format("Subsetting by query {0}, replacement {1} processed {2} of {3}...",
                                                options.Query, options.Replacement, count.ToString(), totalCount.ToString());

                    SetLabelProgressPercentageMsg(progressMsg, count, totalCount, ProgressBarStyle.Blocks);
                }

                image.file = file;
                imagesOut.Add(image);
            } // for each image

            data.images = imagesOut;

            SetStatusMessage(string.Format("Finished query search, found {0} matches (of {1})", data.images.Count(), imagesIn.Count()));

            stopwatch.Stop();
            Console.WriteLine(stopwatch.Elapsed.TotalSeconds.ToString());

            return(data);
        } // SubsetJsonDetectorOutputbyQuery