/// <summary> /// Performs object detection with increasing detection window. /// </summary> /// <param name="image">The image to search in</param> /// <param name="hitThreshold"> /// Threshold for the distance between features and SVM classifying plane. /// Usually it is 0 and should be specified in the detector coefficients (as the last free coefficient). /// But if the free coefficient is omitted (which is allowed), you can specify it manually here. ///</param> /// <param name="winStride">Window stride. Must be a multiple of block stride.</param> /// <param name="padding"></param> /// <param name="scale">Coefficient of the detection window increase.</param> /// <param name="finalThreshold">After detection some objects could be covered by many rectangles. This coefficient regulates similarity threshold. 0 means don't perform grouping. Should be an integer if not using meanshift grouping. Use 2.0 for default</param> /// <param name="useMeanshiftGrouping">If true, it will use meanshift grouping.</param> /// <returns>The regions where positives are found</returns> public MCvObjectDetection[] DetectMultiScale( IInputArray image, double hitThreshold = 0, Size winStride = new Size(), Size padding = new Size(), double scale = 1.05, double finalThreshold = 2.0, bool useMeanshiftGrouping = false) { using (Util.VectorOfRect vr = new VectorOfRect()) using (Util.VectorOfDouble vd = new VectorOfDouble()) using (InputArray iaImage = image.GetInputArray()) { CvHOGDescriptorDetectMultiScale(_ptr, iaImage, vr, vd, hitThreshold, ref winStride, ref padding, scale, finalThreshold, useMeanshiftGrouping); Rectangle[] location = vr.ToArray(); double[] weight = vd.ToArray(); MCvObjectDetection[] result = new MCvObjectDetection[location.Length]; for (int i = 0; i < result.Length; i++) { MCvObjectDetection od = new MCvObjectDetection(); od.Rect = location[i]; od.Score = (float)weight[i]; result[i] = od; } return(result); } }
/// <summary> /// Get the item in the specific index /// </summary> /// <param name="index">The index</param> /// <returns>The item in the specific index</returns> public MCvObjectDetection this[int index] { get { MCvObjectDetection result = new MCvObjectDetection(); VectorOfObjectDetectionGetItem(_ptr, index, ref result); return(result); } }
/// <summary> /// Find the pedestrian in the image /// </summary> /// <param name="image">The image</param> /// <returns>The image with pedestrian highlighted.</returns> public void Detect(Image <Bgr, Byte> image) { Rectangle[] people = _detector.DetectMultiScale(image); _objects = new MCvObjectDetection[people.Length]; for (int i = 0; i < _objects.Length; ++i) { _objects[i].Rect = people[i]; } }
/// <summary> /// Convert the standard vector to an array of ObjectDetection /// </summary> /// <returns>An array of ObjectDetection</returns> public MCvObjectDetection[] ToArray() { MCvObjectDetection[] res = new MCvObjectDetection[Size]; if (res.Length > 0) { GCHandle handle = GCHandle.Alloc(res, GCHandleType.Pinned); VectorOfObjectDetectionCopyData(_ptr, handle.AddrOfPinnedObject()); handle.Free(); } return(res); }
/// <summary> /// Normalize detected regions by combining nearby ones and ensuring they were already present in previous frames. /// This will reduce false-positives. /// </summary> /// <param name="regions">Newly detected regions.</param> /// <param name="previousPeople">Previously confirmed people.</param> /// <param name="history">History of detected regions of multiple previous frames.</param> /// <returns></returns> public MCvObjectDetection[] Normalize(MCvObjectDetection[] regions, MCvObjectDetection[] previousPeople, List <MCvObjectDetection[]> history) { List <MCvObjectDetection> origin = new List <MCvObjectDetection>(regions); List <MCvObjectDetection> results = new List <MCvObjectDetection>(); // normalize overlapping regions while (origin.Count() > 0) { MCvObjectDetection region = origin.ElementAt(0); origin.Remove(region); // check if it intersects with another one bool intersects = false; for (int i = 0; i < results.Count; i++) { // enlarge rect to group close ones MCvObjectDetection result = results[i]; Rectangle enlargedResult = EnlargeRectangle(result.Rect); if (region.Rect.IntersectsWith(enlargedResult)) { intersects = true; int maxRight = Math.Max(result.Rect.Right, region.Rect.Right); int maxBottom = Math.Max(result.Rect.Bottom, region.Rect.Bottom); // update existing region with merged bounds result.Rect.X = Math.Min(result.Rect.X, region.Rect.X); result.Rect.Y = Math.Min(result.Rect.Y, region.Rect.Y); result.Rect.Width = maxRight - result.Rect.X; result.Rect.Height = maxBottom - result.Rect.Y; results[i] = result; } } if (!intersects) { results.Add(region); } } if (previousPeople == null) { return(results.ToArray()); } // to reduce false-positives, only return regions where a person was already previously in or it is persistent in the history return(FilterNewPeople(results, previousPeople, history)); }
/// <summary> /// Performs object detection with increasing detection window. /// </summary> /// <param name="image">The CudaImage to search in</param> /// <returns>The regions where positives are found</returns> public MCvObjectDetection[] DetectMultiScale(IInputArray image) { using (Util.VectorOfRect vr = new VectorOfRect()) using (Util.VectorOfDouble vd = new VectorOfDouble()) { DetectMultiScale(image, vr, vd); Rectangle[] location = vr.ToArray(); double[] weight = vd.ToArray(); MCvObjectDetection[] result = new MCvObjectDetection[location.Length]; for (int i = 0; i < result.Length; i++) { MCvObjectDetection od = new MCvObjectDetection(); od.Rect = location[i]; od.Score = (float)weight[i]; result[i] = od; } return(result); } }
/// <summary> /// /// </summary> /// <param name="image"></param> /// <param name="overlapThreshold"></param> /// <param name="scoreThreshold"></param> protected void Detect(Image <Bgr, Byte> image, float overlapThreshold, float scoreThreshold) { int objectIndex = 0; int objectCount = 0; var objects = _detector.Detect(image, overlapThreshold); foreach (var detected in objects) { if (detected.score > scoreThreshold) { ++objectCount; } } _objects = new MCvObjectDetection[objectCount]; foreach (var detected in objects) { if (detected.score > scoreThreshold) { _objects[objectIndex] = detected; ++objectIndex; } } }
internal static extern void VectorOfObjectDetectionGetItem(IntPtr vec, int index, ref MCvObjectDetection element);