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; }