private void initalizeHistograms() { int[] binSizes = new int[] { 32, 32 }; //X bins per channel IntRange[] ranges = new IntRange[] { new IntRange(0, 180), //Hue (for 8bpp image hue>> range is (0-180) otherwise (0-360) new IntRange(0, 255) }; originalObjHist = new DenseHistogram(binSizes, ranges); backgroundHist = originalObjHist.CopyBlank(); }
/// <summary> /// Finds humps in contour. Hump scale is determined by <paramref name="scale"/>. /// <para>For each peak a closest valley is found. Next for that valley a closet point is found. Those three point make hump.</para> /// <para>Hump searching will be successful even when only one peak and one valley are found; it can be successful where peak and valley search against convex hull does not give good results.</para> /// <para></para>Peaks and valleys can be obtained by using <see cref="FindExtremaIndices"/>. /// </summary> /// <param name="contour">Contour.</param> /// <param name="peaks">Peaks.</param> /// <param name="valeys">Valleys.</param> /// <param name="scale">Used for <see cref="GetClosestPoint"/>. A good value is ~20. A specified region will be searched every time to avoid local minimum.</param> /// <param name="humpPeaks">Found hump peaks.</param> /// <returns>Humps contour indexes.</returns> public static List <Range> GetHumps(this IList <Point> contour, List <int> peaks, List <int> valeys, int scale, out List <int> humpPeaks) { List <Range> humps = new List <Range>(); humpPeaks = new List <int>(); if (valeys.Count == 0) { return(humps); } foreach (var peak in peaks) { var closestValey = valeys.MinBy(valey => System.Math.Abs(valey - peak)); var searchDirection = ((peak - closestValey) > 0) ? 1 : -1; int closestPtToValey = contour.GetClosestPoint(closestValey, peak, searchDirection, scale); if (closestPtToValey == closestValey) //skip "humps" with zero elements { continue; } Range hump; if (searchDirection < 0) { hump = new Range(closestPtToValey, closestValey); } else { hump = new Range(closestValey, closestPtToValey); } //check if a hump contain some other peaks and valey; classify it as a bad hump if (hump.IsInside(peaks).Count(x => x == true) > 1 ||/*discard the current peak*/ hump.IsInside(valeys).Count(x => x == true) > 1) { } else { humps.Add(hump); humpPeaks.Add(peak); } } return(humps); }
/// <summary> /// Gets closest point to the <paramref name="ptIdx"/>. /// </summary> /// <param name="contour">Contour.</param> /// <param name="ptIdx">Point index for which to find the closest point.</param> /// <param name="searchSegment">Contour segment to search.</param> /// <param name="distance">Distance from <paramref name="ptIdx"/> to returned point index.</param> /// <returns>Closest point index regarding <paramref name="ptIdx"/>.</returns> public static int GetClosestPoint(this IList <Point> contour, int ptIdx, Range searchSegment, out double distance) { double minDist = Double.MaxValue; int closestPt = -1; Point pt = contour[ptIdx]; int idx = (int)searchSegment.Min; while (idx != (int)searchSegment.Max) { var dist = ((PointF)pt).DistanceTo(contour[idx]); if (dist < minDist) { minDist = dist; closestPt = idx; } idx = (idx + 1) % contour.Count; } distance = minDist; return(closestPt); }
/// <summary> /// Finds humps in contour. Hump scale is determined by <paramref name="scale"/>. /// <para>For each peak a closest valley is found. Next for that valley a closet point is found. Those three point make hump.</para> /// <para>Hump searching will be successful even when only one peak and one valley are found; it can be successful where peak and valley search against convex hull does not give good results.</para> /// <para></para>Peaks and valleys can be obtained by using <see cref="FindExtremaIndices"/>. /// </summary> /// <param name="contour">Contour.</param> /// <param name="peaks">Peaks.</param> /// <param name="valeys">Valleys.</param> /// <param name="scale">Used for <see cref="GetClosestPoint"/>. A good value is ~20. A specified region will be searched every time to avoid local minimum.</param> /// <param name="humpPeaks">Found hump peaks.</param> /// <returns>Humps contour indexes.</returns> public static List<Range> GetHumps(this IList<Point> contour, List<int> peaks, List<int> valeys, int scale, out List<int> humpPeaks) { List<Range> humps = new List<Range>(); humpPeaks = new List<int>(); if (valeys.Count == 0) return humps; foreach (var peak in peaks) { var closestValey = valeys.MinBy(valey => System.Math.Abs(valey - peak)); var searchDirection = ((peak - closestValey) > 0) ? 1 : -1; int closestPtToValey = contour.GetClosestPoint(closestValey, peak, searchDirection, scale); if (closestPtToValey == closestValey) //skip "humps" with zero elements continue; Range hump; if (searchDirection < 0) hump = new Range(closestPtToValey, closestValey); else hump = new Range(closestValey, closestPtToValey); //check if a hump contain some other peaks and valey; classify it as a bad hump if (hump.IsInside(peaks).Count(x => x == true) > 1 ||/*discard the current peak*/ hump.IsInside(valeys).Count(x => x == true) > 1) { } else { humps.Add(hump); humpPeaks.Add(peak); } } return humps; }
/// <summary> /// Gets closest point to the <paramref name="ptIdx"/>. /// </summary> /// <param name="contour">Contour.</param> /// <param name="ptIdx">Point index for which to find the closest point.</param> /// <param name="searchSegment">Contour segment to search.</param> /// <param name="distance">Distance from <paramref name="ptIdx"/> to returned point index.</param> /// <returns>Closest point index regarding <paramref name="ptIdx"/>.</returns> public static int GetClosestPoint(this IList<Point> contour, int ptIdx, Range searchSegment, out double distance) { double minDist = Double.MaxValue; int closestPt = -1; Point pt = contour[ptIdx]; int idx = (int)searchSegment.Min; while (idx != (int)searchSegment.Max) { var dist = ((PointF)pt).DistanceTo(contour[idx]); if (dist < minDist) { minDist = dist; closestPt = idx; } idx = (idx + 1) % contour.Count; } distance = minDist; return closestPt; }