/// <summary> /// Creates template from the input image by using provided parameters. /// </summary> /// <param name="sourceImage">Input image.</param> /// <param name="minFeatureStrength">Minimum gradient value for the feature.</param> /// <param name="maxNumberOfFeatures">Maximum number of features per template. The features will be extracted so that their locations are semi-uniformly spread.</param> /// <param name="classLabel">Template class label.</param> public override void Initialize(Image<Gray, byte> sourceImage, int minFeatureStrength, int maxNumberOfFeatures, string classLabel) { base.Initialize(sourceImage, minFeatureStrength, maxNumberOfFeatures, classLabel); this.BinaryMask = sourceImage.GetSubRect(BoundingRect).Clone(); if (this.BinaryMask[0, 0].Intensity != 0) //background should be black BinaryMask = this.BinaryMask.Not(); this.BinaryMask = this.BinaryMask.ThresholdToZero(255 * 0.75, 255); //if Gauss kernel was applied... }
void videoCapture_NewFrame(object sender, EventArgs e) { frame = videoCapture.ReadAs<Bgr, byte>(); if (frame == null) return; long preprocessTime, matchTime; var bestRepresentatives = findObjects(frame, out preprocessTime, out matchTime); /************************************ drawing ****************************************/ foreach (var m in bestRepresentatives) { frame.Draw(m.BoundingRect, new Bgr(0, 0, 255), 1); if (m.Template is ImageTemplateWithMask) { var mask = ((ImageTemplateWithMask)m.Template).BinaryMask; if (mask == null) continue; //just draw bounding boxes var area = new Rectangle(m.X, m.Y, mask.Width, mask.Height); if (area.X < 0 || area.Y < 0 || area.Right >= frame.Width || area.Bottom >= frame.Height) continue; //must be fully inside using (var someImage = new Image<Bgr, byte>(mask.Width, mask.Height, Bgr8.Red)) { someImage.CopyTo(frame.GetSubRect(area), mask); } } else { frame.Draw(m, Bgr8.Blue, 3, true, Bgr8.Red); } Console.WriteLine("Best template: " + m.Template.ClassLabel + " score: " + m.Score); } frame.Draw(String.Format("Matching {0} templates in: {1} ms", templPyrs.Count, matchTime), font, new PointF(5, 10), new Bgr(0, 255, 0)); /************************************ drawing ****************************************/ this.pictureBox.Image = frame.ToBitmap(); //it will be just casted (data is shared) 24bpp color //frame.Save(String.Format("C:/probaImages/imgMarked_{0}.jpg", i)); b.Save(String.Format("C:/probaImages/img_{0}.jpg", i)); i++; GC.Collect(); }
private static Rectangle process(Image<Gray, byte> probabilityMap, Rectangle roi, TermCriteria termCriteria, out CentralMoments centralMoments) { Rectangle imageArea = new Rectangle(0, 0, probabilityMap.Width, probabilityMap.Height); Rectangle searchWindow = roi; RawMoments moments = new RawMoments(order: 1); // Mean shift with fixed number of iterations int i = 0; double shift = Byte.MaxValue; while (termCriteria.ShouldTerminate(i, shift) == false && !searchWindow.IsEmptyArea()) { // Locate first order moments moments.Compute(probabilityMap.GetSubRect(searchWindow)); int shiftX = (int)(moments.CenterX - searchWindow.Width / 2f); int shiftY = (int)(moments.CenterY - searchWindow.Height / 2f); // Shift the mean (centroid) searchWindow.X += shiftX; searchWindow.Y += shiftY; // Keep the search window inside the image searchWindow.Intersect(imageArea); shift = System.Math.Abs((double)shiftX) + System.Math.Abs((double)shiftY); //for term criteria only i++; } if (searchWindow.IsEmptyArea() == false) { // Locate second order moments and perform final shift moments.Order = 2; moments.Compute(probabilityMap.GetSubRect(searchWindow)); searchWindow.X += (int)(moments.CenterX - searchWindow.Width / 2f); searchWindow.Y += (int)(moments.CenterY - searchWindow.Height / 2f); // Keep the search window inside the image searchWindow.Intersect(imageArea); } centralMoments = new CentralMoments(moments); // moments to be used by camshift return searchWindow; }