public void GetDiffFrame(int width, int height, out double[] buf) { buf = new double[width * height]; var frame = new Mat(); var diff = new Mat(); var rotatedrect = new RotatedRect(); if (capture.Read(frame)) { frame = frame.Resize(new Size(width, height)); Cv2.CvtColor(frame, frame, ColorConversionCodes.BGR2GRAY); if (PrevFrame != null) { Cv2.Absdiff(frame, PrevFrame, diff); double weight = 1; Mat[] contours; for (int r = 0; r < 2; r++) { Cv2.Threshold(diff, diff, byte.MaxValue / 8, byte.MaxValue, ThresholdTypes.Otsu); var nonzerocnt = Cv2.CountNonZero(diff); weight = (0.25 - ((double)nonzerocnt) / (width * height)) / (0.25); weight = weight < 0 ? 0 : weight; if (weight > 0.5) { Mat h = new Mat(); Cv2.FindContours(diff, out contours, new Mat(), RetrievalModes.External, ContourApproximationModes.ApproxTC89KCOS); diff = new Mat(new Size(width, height), MatType.CV_8UC1, new Scalar(0)); if (contours.Length > 0) { var areaave = contours.Average(x => Cv2.ContourArea(x)); for (int i = 0; i < contours.Length; i++) { if (Cv2.ContourArea(contours[i]) > areaave) { Cv2.DrawContours(diff, contours, i, new Scalar(byte.MaxValue), -1); } } } } else { diff = new Mat(new Size(width, height), MatType.CV_8UC1, new Scalar(0)); } } Point[][] contourspoint; HierarchyIndex[] hierarchyIndexes; Cv2.FindContours(diff.Clone(), out contourspoint, out hierarchyIndexes, RetrievalModes.External, ContourApproximationModes.ApproxTC89KCOS); if (contourspoint.Length > 0) { var points = new List <Point>(); for (int idx_cnt = 0; idx_cnt < contourspoint.GetLength(0); ++idx_cnt) { if (hierarchyIndexes[idx_cnt].Parent != -1) { continue; } points.AddRange(contourspoint[idx_cnt]); } if (points.Count > 5) { diff = new Mat(new Size(width, height), MatType.CV_8UC1, new Scalar(0)); rotatedrect = Cv2.FitEllipse(points); float rho = 0.25f; rotatedrect.Angle = (rho * rotatedrect.Angle + (1 - rho) * PrevRect.Angle); rotatedrect.Size.Width = (rho * rotatedrect.Size.Width + (1 - rho) * PrevRect.Size.Width); rotatedrect.Size.Height = (rho * rotatedrect.Size.Height + (1 - rho) * PrevRect.Size.Height); Cv2.Ellipse(diff, rotatedrect, new Scalar(byte.MaxValue), -1); } } double w = 0.8; Cv2.AddWeighted(PrevDiffFrame, w, diff, 1 - w, 0, diff); Mat result = diff.Clone(); //Cv2.Threshold(diff, result, byte.MaxValue / 8, byte.MaxValue, ThresholdTypes.Binary); Cv2.Dilate(result, result, new Mat(), new Point(-1, -1), 8); //frame.CopyTo(result, result); unsafe { byte *rslt = (byte *)result.Data; byte *f = (byte *)frame.Data; for (int i = 0; i < width * height; i++) { double r = (double)rslt[i] / byte.MaxValue; if (r > 0.25) { buf[i] = ((double)f[i] / byte.MaxValue) + 0.25; } } } } if (PrevFrame == null) { PrevFrame = frame.Clone(); PrevDiffFrame = new Mat(PrevFrame.Size(), PrevFrame.Type(), new Scalar(0)); PrevRect = new RotatedRect(); } else { double weight = 0.5; Cv2.AddWeighted(PrevFrame, weight, frame, 1 - weight, 0, PrevFrame); PrevDiffFrame = diff.Clone(); PrevRect = rotatedrect; } } }
public void GetDiffFrame(int width, int height, out double[] buf) { buf = new double[width * height]; var frame = new Mat(); var diff = new Mat(); if (capture.Read(frame)) { frame = frame.Resize(new Size(width, height)); Cv2.CvtColor(frame, frame, ColorConversionCodes.BGR2GRAY); if (PrevFrame != null) { diff = frame.Clone(); Cv2.Absdiff(frame, PrevFrame, diff); Cv2.Threshold(diff, diff, byte.MaxValue * 0.25, byte.MaxValue, ThresholdTypes.Binary); Point[][] contours; HierarchyIndex[] hierarchyIndexes; Cv2.FindContours(diff.Clone(), out contours, out hierarchyIndexes, RetrievalModes.List, ContourApproximationModes.ApproxTC89KCOS); if (contours.Length > 0) { var points = new List <Point>(); for (int idx_cnt = 0; idx_cnt < contours.GetLength(0); ++idx_cnt) { if (hierarchyIndexes[idx_cnt].Parent != -1) { continue; } points.AddRange(contours[idx_cnt]); } Cv2.DrawContours(diff, new List <List <Point> >(new List <Point>[] { new List <Point>(Cv2.ConvexHull(points.ToArray())) }), 0, new Scalar(byte.MaxValue), -1); } var masked = diff.Clone(); frame.CopyTo(masked, diff); Cv2.BitwiseOr(diff, PrevDiffFrame, diff); Cv2.AddWeighted(masked, 0.5, diff, 0.5, 0, diff); if (PrevFrame != null) { unsafe { byte *p = (byte *)frame.Data; byte *pv = (byte *)diff.Data; for (int i = 0; i < width * height; i++) { buf[i] = (double)pv[i] / byte.MaxValue; } } } } if (PrevFrame == null) { PrevFrame = frame.Clone(); PrevDiffFrame = new Mat(PrevFrame.Size(), PrevFrame.Type()); } else { double weight = 0.75; Cv2.AddWeighted(PrevFrame, weight, frame, 1 - weight, 0, PrevFrame); PrevDiffFrame = diff.Clone(); } } }