Exemplo n.º 1
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
        }
Exemplo n.º 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
        }