Пример #1
0
        /// <summary>
        /// Matches the provided pyramids of templates against the linearized memory maps pyramid.
        /// </summary>
        /// <param name="linPyr">Linearized memory pyramid.</param>
        /// <param name="templPyrs">Pyramids of templates.</param>
        /// <param name="minMatchingPercentage">Minimum matching percentage [0..100].</param>
        /// <param name="inParallel">True to match each template pyramid in parallel, sequentially otherwise.</param>
        /// <returns>List of found matches.</returns>
        public static List <Match> MatchTemplates(this LinearizedMapPyramid linPyr, IEnumerable <ITemplatePyramid> templPyrs, int minMatchingPercentage = 85, bool inParallel = true)
        {
            List <Match> matches = new List <Match>();

            if (inParallel)
            {
                object syncObj = new object();

                Parallel.ForEach(templPyrs, (templPyr) =>
                {
                    List <Match> templateMatches = MatchTemplate(linPyr, templPyr, minMatchingPercentage);
                    lock (syncObj) matches.AddRange(templateMatches);
                });
            }
            else
            {
                foreach (var templPyr in templPyrs)
                {
                    List <Match> templateMatches = MatchTemplate(linPyr, templPyr, minMatchingPercentage);
                    matches.AddRange(templateMatches);
                }
            }

            return(matches);
        }
Пример #2
0
        /// <summary>
        /// Matches the provided template pyramid against the linearized memory maps pyramid.
        /// </summary>
        /// <param name="linPyr">Linearized memory pyramid.</param>
        /// <param name="templPyr">Template pyramid.</param>
        /// <param name="minMatchingPercentage">Minimum matching percentage [0..100].</param>
        /// <returns>List of found matches.</returns>
        public static List <Match> MatchTemplate(this LinearizedMapPyramid linPyr, ITemplatePyramid templPyr, int minMatchingPercentage = 85)
        {
            if (linPyr.PyramidalMaps.Length != templPyr.Templates.Length)
            {
                throw new Exception("Number of pyramids in linear pyramid must match the number of templates in template pyramid!" + "\n" +
                                    "Check if the number of neighborhood per level is the same as the number of features per level for template!");
            }

            List <Match>[] pyrMatches = new List <Match> [linPyr.PyramidalMaps.Length];

            //match at the lowest level
            int lowestLevelIdx = linPyr.PyramidalMaps.Length - 1;
            var searchArea     = new Rectangle(new Point(), linPyr.PyramidalMaps[lowestLevelIdx].ImageSize); //search whole image

            pyrMatches[lowestLevelIdx] = matchTemplate(linPyr.PyramidalMaps[lowestLevelIdx], templPyr.Templates[lowestLevelIdx], searchArea, minMatchingPercentage, true);

            //refine matches
            for (int pyrLevel = (lowestLevelIdx - 1); pyrLevel >= 0; pyrLevel--)
            {
                LinearizedMaps maps           = linPyr.PyramidalMaps[pyrLevel];
                ITemplate      template       = templPyr.Templates[pyrLevel];
                Size           imageValidSize = maps.ImageValidSize;
                pyrMatches[pyrLevel] = new List <Match>();

                int previousNeigborhood = linPyr.PyramidalMaps[pyrLevel + 1].NeigborhoodSize;

                for (int candidateIdx = 0; candidateIdx < pyrMatches[pyrLevel + 1].Count; candidateIdx++) //for every candidate of previous pyramid level...
                {
                    //translate match to lower pyrmaid level
                    Match canidate = pyrMatches[pyrLevel + 1][candidateIdx];
                    canidate.X        = canidate.X * 2 + 1;
                    canidate.Y        = canidate.Y * 2 + 1;
                    canidate.Template = template;

                    //translate search area to lower pyramid level
                    searchArea = new Rectangle //in originalImageSize coordinate system
                    {
                        X      = System.Math.Max(0, canidate.X - previousNeigborhood),
                        Y      = System.Math.Max(0, canidate.Y - previousNeigborhood),
                        Width  = previousNeigborhood * 2,
                        Height = previousNeigborhood * 2
                    };
                    searchArea = searchArea.Intersect(imageValidSize);

                    var foundCandidates = matchTemplate(linPyr.PyramidalMaps[pyrLevel], template, searchArea, minMatchingPercentage, pyrLevel != 0 /*filter partial object for all levels except for the original one*/);
                    pyrMatches[pyrLevel].AddRange(foundCandidates);
                }
            }

            return(pyrMatches[0]); //matches of the highest pyr level
        }