protected override void PreQuantization(Emgu.CV.Image<Color, byte> image) { this.image = image; // If only there is one, do nothing if (this.palettes.Length == 1) { base.PreQuantization(image); return; } // Extract a palette from the image removing transparent colors (not approximated) this.compareQuantization.TileSize = this.TileSize; this.compareQuantization.Quantizate(image); Color[] comparePalette = this.compareQuantization.Palette. Where(c => c.Alpha == 255).ToArray(); LabColor[] compareLabPalette = ColorConversion.ToLabPalette<Color>(comparePalette); // Compare all possible palettes to get the similar one double minDistance = Double.MaxValue; for (int i = 0; i < palettes.Length && minDistance > 0; i++) { double distance = PaletteDistance.CalculateDistance( compareLabPalette, this.labPalettes[i]); if (distance < minDistance) { this.SelectedPalette = i; minDistance = distance; } } // Set the palette... this.Palette = this.palettes[this.SelectedPalette]; // ... and run the FixedPaletteQuantization base.PreQuantization(image); }
public static void CalibrationError( Emgu.CV.ExtrinsicCameraParameters ecp, Emgu.CV.IntrinsicCameraParameters icp, System.Drawing.PointF[] image_points, Vector[] reference_points, out double[] deviations, out Vector[] isect_points) { // Shoot rays through image points, // intersect with plane defined by extrinsic // and measure distance to reference points Matrix inv_ecp = Matrix.Identity(4, 4); inv_ecp.SetMatrix(0, 2, 0, 3, ecp.ExtrinsicMatrix.ToParsley()); inv_ecp = inv_ecp.Inverse(); Ray[] rays = Ray.EyeRays(icp, image_points); Plane p = new Plane(ecp); isect_points = new Vector[rays.Length]; deviations = new double[rays.Length]; for (int i = 0; i < rays.Length; ++i) { double t; Intersection.RayPlane(rays[i], p, out t); Vector isect = rays[i].At(t); Vector x = new Vector(new double[]{isect[0],isect[1],isect[2],1}); x = (inv_ecp * x.ToColumnMatrix()).GetColumnVector(0); Vector final = new Vector(new double[]{x[0], x[1], x[2]}); isect_points[i] = final; deviations[i] = (final - reference_points[i]).Norm(); } }
public static Matrix<byte> ExtractBriefFeatureDescriptors(Emgu.CV.Image<Gray, byte> im, MKeyPoint kp) { var f = new VectorOfKeyPoint(); f.Push(new MKeyPoint[] { kp }); //i'm are going to invoke this with a single point because otherwise I cannot tell which points failed to get descriptors return new BriefDescriptorExtractor().ComputeDescriptorsRaw(im, (Emgu.CV.Image<Gray, byte>)null, f); }
public static IEnumerable<MKeyPoint> FastFeatureExtRaw(Emgu.CV.Image<Gray, byte> image, FeatureExtractionOptions options) { return new FastDetector(options.threshold, true) .DetectKeyPointsRaw(image, (Emgu.CV.Image<Gray, byte>) null).ToArray() .OrderByDescending(kp => kp.Response) .Take(options.numPoints); }
public virtual void ProcessImage(Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> image) { Emgu.CV.Image<Gray, byte> gray = image.Convert<Gray, byte>(); gray._ThresholdBinary(new Gray(_threshold), new Gray(255.0)); gray._Not(); Parsley.Core.EllipseDetector ed = new Parsley.Core.EllipseDetector(); ed.MinimumContourCount = _min_contour_count; List < Parsley.Core.DetectedEllipse > ellipses = new List<Parsley.Core.DetectedEllipse>(ed.DetectEllipses(gray)); List < Parsley.Core.DetectedEllipse > finals = new List<Parsley.Core.DetectedEllipse>( ellipses.Where(e => { return e.Rating < _distance_threshold; }) ); finals.Sort( (a, b) => { double dista = a.Ellipse.MCvBox2D.center.X * a.Ellipse.MCvBox2D.center.X + a.Ellipse.MCvBox2D.center.Y * a.Ellipse.MCvBox2D.center.Y; double distb = b.Ellipse.MCvBox2D.center.X * b.Ellipse.MCvBox2D.center.X + b.Ellipse.MCvBox2D.center.Y * b.Ellipse.MCvBox2D.center.Y; return dista.CompareTo(distb); } ); Bgr bgr = new Bgr(0, 255, 0); MCvFont f = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 0.8, 0.8); int count = 1; foreach (Parsley.Core.DetectedEllipse e in finals) { image.Draw(e.Ellipse, bgr, 2); image.Draw(count.ToString(), ref f, new System.Drawing.Point((int)e.Ellipse.MCvBox2D.center.X, (int)e.Ellipse.MCvBox2D.center.Y), bgr); count++; } }
private List<System.Drawing.PointF> ExtractPoints(Emgu.CV.Image<Gray, byte> channel) { int[] max_intensities = new int[channel.Width]; float[] range = new float[channel.Width]; // Note that default float is zero. // Search per row byte[] d = channel.Bytes; int stride = d.Length / channel.Height; int h = channel.Height; // This one here is a huge, HUGE timesaver! int w = channel.Width; // This one here is a huge, HUGE timesaver! unchecked { for (int r = 0; r < h; ++r) { int offset = stride * r; for (int c = 0; c < w; ++c) { byte i = d[offset + c]; if (i > max_intensities[c]) { max_intensities[c] = i; range[c] = r; } } } } // Update output: set -1 for invalid laser line poses List<System.Drawing.PointF> pixels = new List<System.Drawing.PointF>(); for (int i = 0; i < w; ++i) { if (max_intensities[i] >= _threshold) { pixels.Add(new System.Drawing.PointF(i, range[i])); } } return pixels; }
public void addImage( string imageId, string imageType, Emgu.CV.Image<Emgu.CV.Structure.Gray, byte> image ) { ensureImageBoxNamesUpdated( imageType ); ImageBox ib = new ImageBox(); ib.Image = image; ib.Width = 100; ib.Height = 100; ib.SizeMode = PictureBoxSizeMode.Zoom; ib.HorizontalScrollBar.Visible = false; ib.VerticalScrollBar.Visible = false; if ( _imageBoxNames[ 0 ].CompareTo( imageType ) == 0 ) { flowPanel1.Controls.Add( ib ); return; } if ( _imageBoxNames[ 1 ].CompareTo( imageType ) == 0 ) { flowPanel2.Controls.Add( ib ); return; } if ( _imageBoxNames[ 2 ].CompareTo( imageType ) == 0 ) { flowPanel3.Controls.Add( ib ); } return; }
public void ProcessImage(Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> image) { MCvBox2D mybox = new MCvBox2D(new System.Drawing.PointF(100, 100), new System.Drawing.Size(50, 30), 110); MCvBox2D mybox2 = new MCvBox2D(new System.Drawing.PointF(100, 100), new System.Drawing.Size(50, 30), 0); image.Draw(new Ellipse(mybox), new Bgr(0,0,255), 2); image.Draw(new Ellipse(mybox2), new Bgr(0, 255, 0), 2); }
public static Pixbuf ConvertCVImageToPixbuf(Emgu.CV.Image<Bgr, byte> img) { System.Drawing.Bitmap bmp = img.Bitmap; MemoryStream ms = new MemoryStream(); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); return new Pixbuf(ms.GetBuffer()); }
protected override void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { /* if (_take_ref_image) { _ref_image = img.Copy(); _take_ref_image = false; } // 1. Extract laser-line Context.Setup.World.Laser.FindLaserLine(img); PointF[] laser_points = Context.Setup.World.Laser.ValidLaserPoints.ToArray(); if (_acc != null) { img.Draw(_acc.ROI, new Bgr(Color.Green), 1); } if (laser_points.Length < 3 || _ref_image == null || _acc == null) { return; } Core.Ray[] eye_rays = Core.Ray.EyeRays(Context.Setup.World.Camera.Intrinsics, laser_points); Core.Plane laser_plane; if (Context.Setup.World.Laser.LaserPlaneAlgorithm.FindLaserPlane( eye_rays, Context.Setup.World.ReferencePlanes, out laser_plane)) { Vector z = Vector.Create(new double[] { 0, 0, 1 }); if (Math.Abs(laser_plane.Normal.ScalarMultiply(z)) < 0.3) { Console.WriteLine(laser_plane.Normal); return; } lock (Context.Viewer) { for (int i = 0; i < laser_points.Length; ++i) { Point lp = new Point((int)laser_points[i].X, (int)laser_points[i].Y); if (_acc.ROI.Contains(lp)) { double t; Core.Intersection.RayPlane(eye_rays[i], laser_plane, out t); img[lp.Y, lp.X] = new Bgr(Color.Red); Bgr bgr = _ref_image[lp.Y, lp.X]; Vector color = new Vector(new double[] { bgr.Red / 255.0, bgr.Green / 255.0, bgr.Blue / 255.0, 1.0 }); //_pointcloud.AddPoint(final.ToInterop(), color.ToInterop()); Point p_in_roi = _acc.MakeRelativeToROI(lp); bool first; _acc.Accumulate(p_in_roi, eye_rays[i], t, out first); if (first) { _acc.SetId(p_in_roi, _pointcloud.AddPoint(_acc.Extract(p_in_roi).ToInterop(), color.ToInterop())); } else { _pointcloud.UpdatePoint(_acc.GetId(p_in_roi), _acc.Extract(p_in_roi).ToInterop(), color.ToInterop()); } } } } } * */ }
protected override void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { // Constraint checking if (!Context.Setup.Camera.HasIntrinsics) { _on_roi = false; return; } if (_interactor.State == Parsley.UI.InteractionState.Interacting) { _interactor.DrawIndicator(_interactor.Current, img); } else { _interactor.DrawIndicator(_r, img); } if (_on_roi && _pattern != null) { Image<Gray, Byte> gray = img.Convert<Gray, Byte>(); _pattern.IntrinsicParameters = Context.Setup.Camera.Intrinsics; try { _pattern.FindPattern(gray, _r); if (_pattern.PatternFound) { Parsley.Core.ExtrinsicCalibration ec = new Parsley.Core.ExtrinsicCalibration(_pattern.ObjectPoints, Context.Setup.Camera.Intrinsics); ExtrinsicCameraParameters ecp = ec.Calibrate(_pattern.ImagePoints); double[] deviations; Vector[] points; Core.ExtrinsicCalibration.CalibrationError(ecp,Context.Setup.Camera.Intrinsics,_pattern.ImagePoints, _pattern.ObjectPoints,out deviations,out points); double max_error = deviations.Max(); if (max_error < _last_error) { _last_detected_plane = ecp; _last_error = max_error; this.Logger.Info(String.Format("Extrinsics successfully calculated. Maximum error {0:F3}", _last_error)); } } else if (!_pattern.PatternFound & _last_detected_plane == null) { this.Logger.Warn("Pattern not found."); } } catch (System.Exception e) { this.Logger.Warn(String.Format("Failed to determine extrinsic calibration: {0}", e.Message)); } } if (_last_detected_plane != null) { Core.Drawing.DrawCoordinateFrame(img, _last_detected_plane, Context.Setup.Camera.Intrinsics); } }
/// <summary> /// Construct from values. /// </summary> /// <param name="contour"></param> /// <param name="ellipse"></param> /// <param name="rating"></param> public DetectedEllipse( Emgu.CV.Contour<System.Drawing.Point> contour, Emgu.CV.Structure.Ellipse ellipse, double rating) { _contour = contour; _ellipse = ellipse; _rating = rating; }
/// <summary> /// Hough Line Transform, as in OpenCV (EmguCv does not wrap this function as it should be) /// </summary> /// <param name="img">Binary image</param> /// <param name="type">type of hough transform</param> /// <param name="threshold">how many votes is needed to accept line</param> /// <returns>Lines in theta/rho format</returns> public static PointF[] HoughLineTransform(Image<Gray, byte> img, Emgu.CV.CvEnum.HOUGH_TYPE type, int threshold) { using (MemStorage stor = new MemStorage()) { IntPtr linePtr = CvInvoke.cvHoughLines2(img, stor.Ptr, type, 5, Math.PI / 180 * 15, threshold, 0, 0); Seq<PointF> seq = new Seq<PointF>(linePtr, stor); return seq.ToArray(); ; } }
public ExtrinsicCalibration(Vector[] object_points, Emgu.CV.IntrinsicCameraParameters intrinsics) : base(object_points) { _intrinsics = intrinsics; // Since object points remain constant, we can apply their conversion right here _converted_object_points = Array.ConvertAll<Vector, MCvPoint3D32f>( this.ObjectPoints, new Converter<Vector, MCvPoint3D32f>(Extensions.ConvertFromParsley.ToEmguF) ); }
public SURFEngine(Emgu.CV.Image<Gray, byte> roi) { surfDetector = new SURFDetector(500, false); itemImage = roi; itemKP = surfDetector.DetectKeyPointsRaw(itemImage, null); itemDescriptors = surfDetector.ComputeDescriptorsRaw(itemImage, null, itemKP); matcher = new BruteForceMatcher<float>(DistanceType.L2); matcher.Add(itemDescriptors); }
public static Rectangle[] Detect(Image<Bgr, Byte> image, string cascadeFile, double scaleFactor = 1.3, int minNeighbors = 10, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE detectionType = Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, int minSize = 20, int maxSize = 0) { string cascadeFilePath = CascadeManager.GetCascade(cascadeFile); Size minimumSize; if (minSize == 0) { minimumSize = Size.Empty; } else { minimumSize = new Size(minSize, minSize); } Size maximumSize; if (maxSize == 0) { maximumSize = Size.Empty; } else { maximumSize = new Size(maxSize, maxSize); } if (GpuInvoke.HasCuda) { using (GpuCascadeClassifier cascade = new GpuCascadeClassifier(cascadeFilePath)) using (GpuImage<Bgr, Byte> gpuImage = new GpuImage<Bgr, byte>(image)) using (GpuImage<Gray, Byte> gpuGray = gpuImage.Convert<Gray, Byte>()) { return cascade.DetectMultiScale(gpuGray, scaleFactor, minNeighbors, minimumSize); } } else { using (HaarCascade cascade = new HaarCascade(cascadeFilePath)) using (Image<Gray, Byte> gray = image.Convert<Gray, Byte>()) { gray._EqualizeHist(); MCvAvgComp[] detected = cascade.Detect(gray, scaleFactor, minNeighbors, detectionType, minimumSize, maximumSize); return (from x in detected select x.rect).ToArray(); } } }
protected override void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { Core.CalibrationPattern pattern = _pattern; if (pattern != null) { Image<Gray, Byte> gray = img.Convert<Gray, Byte>(); pattern.FindPattern(gray); this.UpdateStatusDisplay(pattern.PatternFound); this.HandleCalibrateRequest(); this.HandleTakeImageRequest(); this.DrawCoordinateFrame(img); pattern.DrawPattern(img, pattern.ImagePoints, pattern.PatternFound); } }
public static bool[][] EmguImage2Bool(Emgu.CV.Image<Gray, byte> img) { bool[][] booleanMap = new bool[img.Height][]; for (int y = 0; y < img.Height; y++) { booleanMap[y] = new bool[img.Width]; for (int x = 0; x < img.Width; x++) { booleanMap[y][x] = (img[x, y].Intensity < 0.3); } } return booleanMap; }
void FrameGrabber_OnFramePrepend(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { UI.I2DInteractor i = _current; if (i != null) { if (i.State == Parsley.UI.InteractionState.Interacting) { _current.DrawIndicator(i.Current, img); } else { GridItem e = _pg_config.SelectedGridItem; GridItem p = e.Parent; if (p != null) { _current.DrawIndicator(e.PropertyDescriptor.GetValue(p.Value), img); } } } }
protected override void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { Core.CalibrationPattern pattern = _pattern; if (pattern != null) { //cari pola kalibrasi jika marker kalibrasi tersedia Image<Gray, Byte> gray = img.Convert<Gray, Byte>(); //convert image to grayscale pattern.FindPattern(gray); //cari pola kalibrasi this.UpdateStatusDisplay(pattern.PatternFound); this.HandleCalibrateRequest(); this.HandleTakeImageRequest(); this.DrawCoordinateFrame(img); pattern.DrawPattern(img, pattern.ImagePoints, pattern.PatternFound); //gambar AR pada marker jika pattern ditemukan } }
override protected void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { Emgu.CV.Image<Emgu.CV.Structure.Bgr, Byte> my_ref = _reference; int my_channel = _channel; if (my_ref != null) { _lle.FindLaserLine(img[my_channel].Sub(my_ref[my_channel])); } else { _lle.FindLaserLine(img[my_channel]); } foreach (System.Drawing.PointF p in _lle.ValidLaserPoints) { img[(int)p.Y, (int)p.X] = new Emgu.CV.Structure.Bgr(255, 0, 0); } }
protected override void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { Core.Bundle b = new Parsley.Core.Bundle(); Core.BundleBookmarks bb = new Parsley.Core.BundleBookmarks(b); bb.Image = img; bb.LaserColor = Context.Setup.Laser.Color; if (!Context.Setup.ScanWorkflow.LaserLineAlgorithm.FindLaserLine(bb.Bundle)) return; if (!Context.Setup.ScanWorkflow.LaserLineFilterAlgorithm.FilterLaserLine(bb.Bundle)) return; SaveLaserData(bb.LaserPixel); foreach (System.Drawing.PointF p in bb.LaserPixel) { img[p.ToNearestPoint()] = new Emgu.CV.Structure.Bgr(System.Drawing.Color.Green); } }
public static BitmapSource ToBitmapSource(Emgu.CV.IImage image) { using (System.Drawing.Bitmap source = image.Bitmap) { IntPtr ptr = source.GetHbitmap(); BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( ptr, IntPtr.Zero, Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); DeleteObject(ptr); return bs; } }
public override Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> GetDifference(Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> frame, IEnumerable<Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte>> frameHistory) { if (frameHistory.Count() != _historySize || _mixtures != NumberOfMixtures.Value || _ratio != BackgroundRatio.Value || _noise != NoiseSigma.Value) { _historySize = frameHistory.Count(); _mixtures = NumberOfMixtures.Value; _ratio = BackgroundRatio.Value; _noise = NoiseSigma.Value; ResetSubstractor(); } Mat mask = new Mat(); _mog.Apply(frame, mask); return mask.ToImage<Bgr, byte>(); }
public static void AddFlannIndex(Emgu.CV.Flann.Index o, string key) { // NOTE: Apply expiration parameters as you see fit. // I typically pull from configuration file. // In this example, I want an absolute // timeout so changes will always be reflected // at that time. Hence, the NoSlidingExpiration. if (TrackSize) _cacheSizeinKb += MemorySize.GetBlobSizeinKb(o); cache.Add( key, o, DateTime.Now.AddMinutes(1440)); }
override protected void OnFrame(Parsley.Core.BuildingBlocks.FrameGrabber fp, Emgu.CV.Image<Emgu.CV.Structure.Bgr, byte> img) { Core.CalibrationPattern pattern = this.Context.CalibrationPattern; Emgu.CV.Image<Gray, Byte> gray = img.Convert<Gray, Byte>(); gray._EqualizeHist(); pattern.FindPattern(gray); if (pattern.PatternFound) { Emgu.CV.ExtrinsicCameraParameters ecp = _ex.Calibrate(pattern.ImagePoints); lock (Context.Viewer) { Matrix m = Matrix.Identity(4, 4); m.SetMatrix(0, 2, 0, 3, ecp.ExtrinsicMatrix.ToParsley()); _board_transform.Matrix = m.ToInterop(); } } pattern.DrawPattern(img, pattern.ImagePoints, pattern.PatternFound); }
public static void VisualizeError( Emgu.CV.Image<Bgr, Byte> img, Emgu.CV.ExtrinsicCameraParameters ecp, Emgu.CV.IntrinsicCameraParameters icp, double[] deviations, Vector[] isect_points) { Bgr bgr = new Bgr(System.Drawing.Color.Green); MCvFont f = new MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_PLAIN, 0.8, 0.8); foreach (Vector p in isect_points) { System.Drawing.PointF[] coords = Emgu.CV.CameraCalibration.ProjectPoints( new MCvPoint3D32f[] { p.ToEmguF() }, ecp, icp ); img.Draw(new CircleF(coords[0], 1), bgr, 1); } }
/// <summary> /// Draw a visual indication of the pattern coordinate frame /// </summary> /// <param name="img">Image to draw to</param> /// <param name="ecp">Extrinsic calibration</param> /// <param name="icp">Intrinsic calibration</param> public static void DrawCoordinateFrame( Emgu.CV.Image<Bgr, Byte> img, Emgu.CV.ExtrinsicCameraParameters ecp, Emgu.CV.IntrinsicCameraParameters icp) { float extension = img.Width / 10; PointF[] coords = Emgu.CV.CameraCalibration.ProjectPoints( new MCvPoint3D32f[] { new MCvPoint3D32f(0, 0, 0), new MCvPoint3D32f(extension, 0, 0), new MCvPoint3D32f(0, extension, 0), new MCvPoint3D32f(0, 0, extension), }, ecp, icp); img.Draw(new LineSegment2DF(coords[0], coords[1]), new Bgr(System.Drawing.Color.Red), 2); img.Draw(new LineSegment2DF(coords[0], coords[2]), new Bgr(System.Drawing.Color.Green), 2); img.Draw(new LineSegment2DF(coords[0], coords[3]), new Bgr(System.Drawing.Color.Blue), 2); }
public ImageProcessor(Emgu.CV.Image<Bgr, byte> source) { sourceImage = source; reducedNoiseImage = new Emgu.CV.Image<Bgr, byte>(sourceImage.Size); grayscaleImage = new Emgu.CV.Image<Gray, byte>(sourceImage.Size); normalizedImage = new Emgu.CV.Image<Gray, byte>(sourceImage.Size); // Размываем изображение для устранения шума Emgu.CV.CvInvoke.cvSmooth(sourceImage.Ptr, reducedNoiseImage.Ptr, Emgu.CV.CvEnum.SMOOTH_TYPE.CV_MEDIAN, 3, 0, 0, 0); // Преобразуем изображение в оттенки серого Emgu.CV.CvInvoke.cvCvtColor(reducedNoiseImage.Ptr, grayscaleImage.Ptr, Emgu.CV.CvEnum.COLOR_CONVERSION.CV_BGR2GRAY); // Нормализация изображения Emgu.CV.CvInvoke.cvNormalize(grayscaleImage.Ptr, normalizedImage.Ptr, 0, 200, Emgu.CV.CvEnum.NORM_TYPE.CV_MINMAX, IntPtr.Zero); }
/// <summary> /// Calculates optical flow for a sparse feature set using iterative Lucas-Kanade method in pyramids /// </summary> /// <param name="prev">First frame, at time t</param> /// <param name="curr">Second frame, at time t + dt </param> /// <param name="prevPyrBuffer">Buffer for the pyramid for the first frame. If it is not NULL, the buffer must have a sufficient size to store the pyramid from level 1 to level #level ; the total size of (image_width+8)*image_height/3 bytes is sufficient</param> /// <param name="currPyrBuffer">Similar to prev_pyr, used for the second frame</param> /// <param name="prevFeatures">Array of points for which the flow needs to be found</param> /// <param name="winSize">Size of the search window of each pyramid level</param> /// <param name="level">Maximal pyramid level number. If 0 , pyramids are not used (single level), if 1 , two levels are used, etc</param> /// <param name="criteria">Specifies when the iteration process of finding the flow for each point on each pyramid level should be stopped</param> /// <param name="flags">Flags</param> /// <param name="currFeatures">Array of 2D points containing calculated new positions of input features in the second image</param> /// <param name="status">Array. Every element of the array is set to 1 if the flow for the corresponding feature has been found, 0 otherwise</param> /// <param name="trackError">Array of double numbers containing difference between patches around the original and moved points</param> public static void PyrLK( Image<Gray, Byte> prev, Image<Gray, Byte> curr, Image<Gray, Byte> prevPyrBuffer, Image<Gray, Byte> currPyrBuffer, System.Drawing.PointF[] prevFeatures, System.Drawing.Size winSize, int level, MCvTermCriteria criteria, Emgu.CV.CvEnum.LKFLOW_TYPE flags, out System.Drawing.PointF[] currFeatures, out Byte[] status, out float[] trackError) { if (prevPyrBuffer == null) { prevPyrBuffer = new Image<Gray, byte>(prev.Width + 8, prev.Height / 3); } if (currPyrBuffer == null) { currPyrBuffer = prevPyrBuffer.CopyBlank(); } status = new Byte[prevFeatures.Length]; trackError = new float[prevFeatures.Length]; currFeatures = new System.Drawing.PointF[prevFeatures.Length]; CvInvoke.cvCalcOpticalFlowPyrLK( prev, curr, prevPyrBuffer, currPyrBuffer, prevFeatures, currFeatures, prevFeatures.Length, winSize, level, status, trackError, criteria, flags); }