Exemplo n.º 1
0
        /// <summary>
        /// Matches the provided templates against the linear memory maps.
        /// </summary>
        /// <param name="linMaps">Linear maps.</param>
        /// <param name="templates">Collections of templates.</param>
        /// <param name="minMatchingPercentage">Minimum matching percentage [0..100].</param>
        /// <param name="inParallel">True to match each template in parallel, sequentially otherwise.</param>
        /// <returns>List of found matches.</returns>
        public static List <Match> MatchTemplates(this LinearizedMaps linMaps, IEnumerable <ITemplate> templates, int minMatchingPercentage = 85, bool inParallel = true)
        {
            var searchArea = new Rectangle(new Point(), linMaps.ImageSize);

            List <Match> matches = new List <Match>();

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

                Parallel.ForEach(templates, (template) =>
                {
                    List <Match> templateMatches = matchTemplate(linMaps, template, searchArea, minMatchingPercentage);
                    lock (syncObj) matches.AddRange(templateMatches);
                });
            }
            else
            {
                foreach (var template in templates)
                {
                    List <Match> templateMatches = matchTemplate(linMaps, template, searchArea, minMatchingPercentage);
                    matches.AddRange(templateMatches);
                }
            }

            return(matches);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Matches the provided template against the linear memory maps.
        /// </summary>
        /// <param name="linMaps">Linear maps.</param>
        /// <param name="template">Template.</param>
        /// <param name="searchArea">Search area in the image.</param>
        /// <param name="minMatchingPercentage">Minimum matching percentage [0..100].</param>
        /// <returns>List of found matches.</returns>
        public static List <Match> MatchTemplate(this LinearizedMaps linMaps, ITemplate template, Rectangle searchArea, int minMatchingPercentage = 85)
        {
            if (searchArea.IntersectionPercent(new Rectangle(new Point(), linMaps.ImageSize)) < 1)
            {
                throw new Exception("Search area must be within image size!");
            }

            return(matchTemplate(linMaps, template, searchArea, minMatchingPercentage));
        }
Exemplo n.º 3
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.º 4
0
        private static Gray <short>[,] calculateSimilarityMap(ITemplate template, LinearizedMaps maps, Rectangle searchArea)
        {
            Debug.Assert(searchArea.Right <= maps.ImageSize.Width &&
                         searchArea.Bottom <= maps.ImageSize.Height);
            Debug.Assert(template.Size.Width + searchArea.X < maps.ImageSize.Width &&
                         template.Size.Height + searchArea.Y < maps.ImageSize.Height);

            int width  = searchArea.Width / maps.NeigborhoodSize;
            int height = searchArea.Height / maps.NeigborhoodSize;

            Gray <short>[,] similarityMap = new Gray <short> [height, width]; //performance penalty (alloc, dealloc)!!!
            Gray <byte>[,] buffer         = new Gray <byte> [height, width];

            using (var uSimilarityMap = similarityMap.Lock())
                using (var uBuffer = buffer.Lock())
                {
                    int nAddsInBuffer = 0;
                    foreach (var feature in template.Features)
                    {
                        var position = new Point(feature.X + searchArea.X, feature.Y + searchArea.Y); //shifted position

                        Point mapPoint;
                        var   neighbourMap = maps.GetMapElement(position, feature.AngleIndex, out mapPoint);

                        neighbourMap.AddTo(uBuffer, mapPoint);
                        nAddsInBuffer++;

                        if (nAddsInBuffer / GlobalParameters.MAX_SUPPORTED_NUM_OF_FEATURES_ADDDED_AS_BYTE != 0)
                        {
                            uBuffer.AddTo(uSimilarityMap);
                            buffer.Clear(); //clear buffer

                            nAddsInBuffer = 0;
                        }
                    }

                    bool finalAdd = (template.Features.Length % GlobalParameters.MAX_SUPPORTED_NUM_OF_FEATURES_ADDDED_AS_BYTE != 0);
                    if (finalAdd)
                    {
                        uBuffer.AddTo(uSimilarityMap);
                    }
                }

            return(similarityMap);
        }
        /// <summary>
        /// Creates linearized maps pyramid.
        /// </summary>
        /// <param name="sourceImage">Source image.</param>
        /// <param name="orientationImgCalc">Orientation image calculation function.</param>
        /// <param name="neigborhoodPerLevel">Neighborhood per level. If null default neighborhood is going to be used.</param>
        /// <returns>Pyramid of linearized maps.</returns>
        public static LinearizedMapPyramid CreatePyramid <TColor>(TColor[,] sourceImage, Func <TColor[, ], Gray <int> [, ]> orientationImgCalc, params int[] neigborhoodPerLevel)
            where TColor : struct, IColor <byte>
        {
            neigborhoodPerLevel = (neigborhoodPerLevel == null || neigborhoodPerLevel.Length == 0) ? DEFAULT_NEGBORHOOD_PER_LEVEL : neigborhoodPerLevel;

            int nPyramids = neigborhoodPerLevel.Length;

            LinearizedMaps[] responseMaps = new LinearizedMaps[nPyramids];
            var image = sourceImage;

            for (int pyrLevel = 0; pyrLevel < nPyramids; pyrLevel++)
            {
                if (pyrLevel > 0)
                {
                    image = image.PyrDown();
                }

                Gray <int>[,] orientationImg = orientationImgCalc(sourceImage);
                responseMaps[pyrLevel]       = new LinearizedMaps(orientationImg, neigborhoodPerLevel[pyrLevel]);
            }

            return(new LinearizedMapPyramid(responseMaps));
        }
Exemplo n.º 6
0
        private static List <Match> matchTemplate(this LinearizedMaps linMaps, ITemplate template, Rectangle searchArea, int minMatchingPercentage, bool filterPartialObjects = true)
        {
            //just do matching for templates that can fit into query image
            if (template.Size.Width > linMaps.ImageValidSize.Width ||
                template.Size.Height > linMaps.ImageValidSize.Height)
            {
                return(new List <Match>());
            }

            var similarityMap = calculateSimilarityMap(template, linMaps, searchArea);

            float rawScoreScale       = 100f / (GlobalParameters.MAX_FEATURE_SIMILARITY * template.Features.Length);
            short minMatchingRawScore = (short)System.Math.Round(minMatchingPercentage * (1 / rawScoreScale));

            List <short> rawScores;
            var          foundMatchPoints = searchSimilarityMap(similarityMap, minMatchingRawScore, out rawScores);

            var offset          = new Point(searchArea.X, searchArea.Y);
            var foundCandidates = createMatches(template, linMaps.NeigborhoodSize, foundMatchPoints, offset, rawScores, rawScoreScale);

            filterPartialShownObjects(ref foundCandidates, linMaps.ImageSize);

            return(foundCandidates);
        }
Exemplo n.º 7
0
        private static Image <Gray, short> calculateSimilarityMap(ITemplate template, LinearizedMaps maps, Rectangle searchArea)
        {
            Debug.Assert(searchArea.Right <= maps.ImageSize.Width &&
                         searchArea.Bottom <= maps.ImageSize.Height);
            Debug.Assert(template.Size.Width + searchArea.X < maps.ImageSize.Width &&
                         template.Size.Height + searchArea.Y < maps.ImageSize.Height);

            int width  = searchArea.Width / maps.NeigborhoodSize;
            int height = searchArea.Height / maps.NeigborhoodSize;

            Image <Gray, short> similarityMap = new Image <Gray, short>(width, height, LinearizedMaps.MAP_STRIDE_ALLIGNMENT); //performance penalty (alloc, dealloc)!!!

            using (var buffer = new Image <Gray, byte>(width, height, LinearizedMaps.MAP_STRIDE_ALLIGNMENT))                  //performance penalty (alloc, dealloc)!!!
            {
                int nAddsInBuffer = 0;

                foreach (var feature in template.Features)
                {
                    var position = new Point(feature.X + searchArea.X, feature.Y + searchArea.Y); //shifted position

                    Point mapPoint;
                    var   neighbourMap = maps.GetMapElement(position, feature.AngleIndex, out mapPoint);

                    neighbourMap.AddTo(buffer, mapPoint);
                    nAddsInBuffer++;

                    if (nAddsInBuffer / GlobalParameters.MAX_SUPPORTED_NUM_OF_FEATURES_ADDDED_AS_BYTE != 0)
                    {
                        buffer.AddTo(similarityMap);
                        buffer.Clear();

                        nAddsInBuffer = 0;
                    }
                }

                bool finalAdd = (template.Features.Length % GlobalParameters.MAX_SUPPORTED_NUM_OF_FEATURES_ADDDED_AS_BYTE != 0) ? true : false;
                if (finalAdd)
                {
                    buffer.AddTo(similarityMap);
                }
            }

            return(similarityMap);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Matches the provided template against the linear memory maps.
        /// </summary>
        /// <param name="linMaps">Linear maps.</param>
        /// <param name="template">Template.</param>
        /// <param name="minMatchingPercentage">Minimum matching percentage [0..100].</param>
        /// <returns>List of found matches.</returns>
        public static List <Match> MatchTemplate(this LinearizedMaps linMaps, ITemplate template, int minMatchingPercentage)
        {
            var searchArea = new Rectangle(new Point(), linMaps.ImageSize);

            return(matchTemplate(linMaps, template, searchArea, minMatchingPercentage));
        }
Exemplo n.º 9
0
        private static Gray<short>[,] calculateSimilarityMap(ITemplate template, LinearizedMaps maps, Rectangle searchArea)
        {
            Debug.Assert(searchArea.Right <= maps.ImageSize.Width && 
                         searchArea.Bottom <= maps.ImageSize.Height);
            Debug.Assert(template.Size.Width + searchArea.X < maps.ImageSize.Width &&
                         template.Size.Height + searchArea.Y < maps.ImageSize.Height);

            int width = searchArea.Width / maps.NeigborhoodSize;
            int height = searchArea.Height / maps.NeigborhoodSize;

            Gray<short>[,] similarityMap = new Gray<short>[height, width]; //performance penalty (alloc, dealloc)!!!
            Gray<byte>[,] buffer = new Gray<byte>[height, width];

            using (var uSimilarityMap = similarityMap.Lock())
            using(var uBuffer = buffer.Lock())
            {
                int nAddsInBuffer = 0;
                foreach (var feature in template.Features)
                {
                    var position = new Point(feature.X + searchArea.X, feature.Y + searchArea.Y); //shifted position

                    Point mapPoint;
                    var neighbourMap = maps.GetMapElement(position, feature.AngleIndex, out mapPoint);

                    neighbourMap.AddTo(uBuffer, mapPoint);
                    nAddsInBuffer++;

                    if (nAddsInBuffer / GlobalParameters.MAX_SUPPORTED_NUM_OF_FEATURES_ADDDED_AS_BYTE != 0)
                    {
                        uBuffer.AddTo(uSimilarityMap);
                        buffer.Clear(); //clear buffer

                        nAddsInBuffer = 0;
                    }
                }

                bool finalAdd = (template.Features.Length % GlobalParameters.MAX_SUPPORTED_NUM_OF_FEATURES_ADDDED_AS_BYTE != 0) ? true : false;
                if (finalAdd)
                {
                    uBuffer.AddTo(uSimilarityMap);
                }
            }

            return similarityMap;
        }