private static Tuple <Image <Bgr, byte>, Rectangle, double> btnCalcBackProjectPatch(Image <Gray, byte> model, Image <Gray, byte> observed, Image <Bgr, byte> result) { Stopwatch sw = new Stopwatch(); sw.Start(); Image <Bgr, Byte> imageSource = observed.Convert <Bgr, byte>(); double scale = GetScale(); Image <Bgr, Byte> imageSource2 = imageSource.Resize(scale, INTER.CV_INTER_LINEAR); Image <Bgr, Byte> imageTarget = model.Convert <Bgr, byte>(); Image <Bgr, Byte> imageTarget2 = imageTarget.Resize(scale, INTER.CV_INTER_LINEAR); Image <Gray, Single> imageDest = null; int edgeX = imageTarget2.Size.Width; int edgeY = imageTarget2.Size.Height; Size patchSize = new Size(edgeX, edgeY); string colorSpace = "Gray"; double normalizeFactor = 1d; Image <Gray, Byte>[] imagesSource; int[] bins; RangeF[] ranges; string[] captions; Color[] colors; // Get all the color bins from the source images. GetImagesBinsAndRanges(imageSource2, colorSpace, out imagesSource, out bins, out ranges, out captions, out colors); // Histogram calculation. DenseHistogram histTarget = CalcHist(imageTarget2.Bitmap); // Backproject compare method. HISTOGRAM_COMP_METHOD compareMethod = GetHistogramCompareMethod(); imageDest = BackProjectPatch <Byte>(imagesSource, patchSize, histTarget, compareMethod, (float)normalizeFactor); // Best-match value. double bestValue; Point bestPoint; FindBestMatchPointAndValue(imageDest, compareMethod, out bestValue, out bestPoint); // Draw a rectangle with the same size of the template at the best-match point Rectangle rect = new Rectangle(bestPoint, patchSize); result = imageDest.Convert <Bgr, byte>(); sw.Stop(); // Disposal imageSource.Dispose(); imageSource2.Dispose(); imageTarget.Dispose(); imageTarget2.Dispose(); if (imageDest != null) { imageDest.Dispose(); } foreach (Image <Gray, Byte> image in imagesSource) { image.Dispose(); } histTarget.Dispose(); return(new Tuple <Image <Bgr, byte>, Rectangle, double>(result, rect, bestValue)); }
// Histogram compare method. private static HISTOGRAM_COMP_METHOD GetHistogramCompareMethod() { HISTOGRAM_COMP_METHOD compareMethod = HISTOGRAM_COMP_METHOD.CV_COMP_CORREL; compareMethod = HISTOGRAM_COMP_METHOD.CV_COMP_CORREL; return(compareMethod); }
// Find the best match point and its value. private static void FindBestMatchPointAndValue(Image <Gray, Single> image, HISTOGRAM_COMP_METHOD compareMethod, out double bestValue, out Point bestPoint) { bestValue = 0d; bestPoint = new Point(0, 0); double[] minValues, maxValues; Point[] minLocations, maxLocations; image.MinMax(out minValues, out maxValues, out minLocations, out maxLocations); if (compareMethod == HISTOGRAM_COMP_METHOD.CV_COMP_CHISQR || compareMethod == HISTOGRAM_COMP_METHOD.CV_COMP_BHATTACHARYYA) { bestValue = minValues[0]; bestPoint = minLocations[0]; } else { bestValue = maxValues[0]; bestPoint = maxLocations[0]; } }
// Compares histogram over each possible rectangular patch of the specified size in the input images, and stores the results to the output map dst. // Destination back projection image of the same type as the source images public static Image <Gray, Single> BackProjectPatch <TDepth>(Image <Gray, TDepth>[] srcs, Size patchSize, DenseHistogram hist, HISTOGRAM_COMP_METHOD method, double factor) where TDepth : new() { Debug.Assert(srcs.Length == hist.Dimension, "The number of the source image and the dimension of the histogram must be the same."); IntPtr[] imgPtrs = Array.ConvertAll <Image <Gray, TDepth>, IntPtr>( srcs, delegate(Image <Gray, TDepth> img) { return(img.Ptr); }); Size size = srcs[0].Size; size.Width = size.Width - patchSize.Width + 1; size.Height = size.Height - patchSize.Height + 1; Image <Gray, Single> res = new Image <Gray, float>(size); CvInvoke.cvCalcBackProjectPatch(imgPtrs, res.Ptr, patchSize, hist.Ptr, method, factor); return(res); }
private int hack(DenseHistogram[] referenceHistogram, IEnumerable<DenseHistogram[]> testHistograms, HISTOGRAM_COMP_METHOD method, bool printHigh) { var comparisons = testHistograms.Select(x => GetHistogramComparison(x, referenceHistogram, method)); var multiplied = comparisons.Select(x => Math.Abs(x[0] * x[1] * x[2])); var i = 0; foreach (var x in comparisons) { Console.WriteLine("{0,1}: {1:E4} {2:E4} {3:E4} --- {4:E4}", i, x[0], x[1], x[2], multiplied.ToList()[i]); i++; } var minAndMax = findMinAndMax(multiplied); return printHigh ? minAndMax[1] : minAndMax[0]; }