private Rect GetFaceRoi(Mat mask, Rect roi, int size, out double faceRatio) { var maxI = -1; var maxJ = -1; var max = 0.0; for (var i = roi.Y; i < roi.Y + roi.Height - size; i += 4) { for (var j = roi.X; j < roi.X + roi.Width - size; j += 4) { var newIm = new Mat(mask, new Rect(j, i, size, size)); var count = Cv2.CountNonZero(newIm); var ratio = count * 1.0 / (size * size); if (ratio > max) { max = ratio; maxI = i; maxJ = j; } } } faceRatio = max; if (maxI == -1) { return(Rect.Empty); } return(new Rect(maxJ, maxI, size, size)); }
/// <summary> /// Detect the eye state of the face on camera. /// </summary> /// <param name="shape">The detected facial landmark points.</param> /// <returns>The surface area of both eyes.</returns> private bool AreEyesOpen(FullObjectDetection shape) { // get all landmark points of the left eye var leftEye = from i in Enumerable.Range(36, 6) let p = shape.GetPart((uint)i) select new OpenCvSharp.Point(p.X, p.Y); // get all landmark points of the right eye var rightEye = from i in Enumerable.Range(42, 6) let p = shape.GetPart((uint)i) select new OpenCvSharp.Point(p.X, p.Y); // create a mask of the eye areas using (var mask = new Mat(new OpenCvSharp.Size(640, 480), MatType.CV_8UC1)) { mask.SetTo(0); Cv2.FillConvexPoly(mask, leftEye, Scalar.White); Cv2.FillConvexPoly(mask, rightEye, Scalar.White); // count the number of pixels in the eye area var pixels = Cv2.CountNonZero(mask); // the maximum possible area is 40% of the surface area of both eyeballs int r1 = (shape.GetPart(39).X - shape.GetPart(36).X) / 2; int r2 = (shape.GetPart(45).X - shape.GetPart(42).X) / 2; double normalizedArea = 0.4 * Math.PI * r1 * r1 + 0.4 * Math.PI * r2 * r2; // calculate fractional area and normalize on a 0-100 scale var value = (int)(100 * pixels / normalizedArea - 20); var eyeState = value >= 0 && value <= 100 ? value : 0; // return result return(eyeState > 30); } }
private void surfrecog(int thre, double deltaz) { MotorControler mc = MotorControler.GetInstance(parameterManager); Camera camera = Camera.GetInstance(); bool flag = true; while (flag) { mc.MoveDistance(deltaz, VectorId.Z); mc.Join(); Thread.Sleep(100); byte[] b = camera.ArrayImage; Mat src = new Mat(440, 512, MatType.CV_8U, b); Mat mat = src.Clone(); Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); Mat gau = mat.Clone(); Cv2.GaussianBlur(gau, gau, Cv.Size(17, 17), -1); Cv2.Subtract(gau, mat, mat); Cv2.Threshold(mat, mat, 10, 1, ThresholdType.Binary); int brightness = Cv2.CountNonZero(mat); if (brightness > thre) { flag = false; } } }
static public int HitPixCount(byte[] b, int width, int height, int kernel, int thre = 10) { Mat mat0 = new Mat(height, width, MatType.CV_8U, b); Mat mat = mat0.Clone(); Cv2.Threshold(mat, mat, thre, 1, ThresholdType.Binary); int brightness = Cv2.CountNonZero(mat); return(brightness); }
/// <summary> /// この関数を実行すると,カメラから画像を取得し,グリッドマークを検出しその座標を返します. /// 実行時のレンズはx50対物であることを前提とします. /// </summary> /// <returns>グリッドマークを検出したピクセル座標。検出できなかった時は(-1,-1)が返される</returns> public Vector2 SearchGridMarkx50() { // レンズが50倍に設定されていない場合は例外を返すようにしたいがやり方が分からん(20140724) //if (parameterManager.Magnification != ParameterManager.) { // throw new LensTypeException(ParameterManager.LensMagnificationOfGridMarkSearch); //} Camera c = Camera.GetInstance(); byte[] b = c.ArrayImage; Mat mat = new Mat(440, 512, MatType.CV_8U, b); //mat.ImWrite(String.Format(@"c:\img\{0}_g.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"))); Cv2.GaussianBlur(mat, mat, Cv.Size(5, 5), -1); Cv2.Threshold(mat, mat, 60, 255, ThresholdType.BinaryInv); //mat.ImWrite(String.Format(@"c:\img\{0}_t.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"))); Moments mom = new Moments(mat); if (mom.M00 < 1000 * 255) { return(new Vector2(-1.0, -1.0)); } double cx = mom.M10 / mom.M00; double cy = mom.M01 / mom.M00; Mat innercir = Mat.Zeros(440, 512, MatType.CV_8UC1); Cv2.Circle(innercir, new Point(cx, cy), 30, new Scalar(255, 255, 255), 3); int innerpath = Cv2.CountNonZero(innercir); Cv2.BitwiseAnd(innercir, mat, innercir); int innersum = Cv2.CountNonZero(innercir); Mat outercir = Mat.Zeros(440, 512, MatType.CV_8UC1); Cv2.Circle(outercir, new Point(cx, cy), 200, new Scalar(255, 255, 255), 3); int outerpath = Cv2.CountNonZero(outercir); Cv2.BitwiseAnd(outercir, mat, outercir); int outersum = Cv2.CountNonZero(outercir); double innerratio = innersum * 1.0 / innerpath * 1.0; double outerratio = outersum * 1.0 / outerpath * 1.0; if (innerratio < 0.8) { return(new Vector2(-1.0, -1.0)); } if (outerratio > 0.2) { return(new Vector2(-1.0, -1.0)); } return(new Vector2(cx, cy)); }
static void Main(string[] args) { string[] files = Directory.GetFiles(@"C:\Users\Laptop\Desktop\asd2"); Window show = new Window("", WindowMode.FreeRatio); Window show2 = new Window("asds", WindowMode.FreeRatio); Mat[] splitMat = new Mat[3]; Mat image = new Mat(); Mat imageTrue = new Mat(); foreach (var file in files) { image = Cv2.ImRead(file); image.CopyTo(imageTrue); Cv2.CvtColor(image, image, ColorConversion.RgbToHsv); Cv2.Split(image, out splitMat); //Cv2.CvtColor(splitMat[1], image, ColorConversion.RgbToGray); Cv2.BitwiseNot(splitMat[1], image); Cv2.Threshold(image, image, 210, 255, ThresholdType.Binary); int total = image.Cols * image.Rows; int black = Cv2.CountNonZero(image); float debesuotumas = (float)black / (float)total; string oroSalygos = ""; if (debesuotumas != 0 && debesuotumas < 0.01) { oroSalygos = "Giedra su mazais debesimis"; } else if (0.01 < debesuotumas && debesuotumas < 0.45) { oroSalygos = "Lengvas Debesuotumas"; } else if (0.45 < debesuotumas && debesuotumas < 0.8) { oroSalygos = "Debesuota"; } else if (0.8 < debesuotumas) { oroSalygos = "Labai Debesuota"; } else { oroSalygos = "Giedra"; } Console.WriteLine(debesuotumas); Point vieta = new Point(100, 100); Cv2.PutText(imageTrue, oroSalygos, vieta, FontFace.Italic, 3, Scalar.Red, 5); show.Image = image; show2.Image = imageTrue; Cv2.WaitKey(); } }
public void MorphologyExDilate() { using Mat src = new Mat(100, 100, MatType.CV_8UC1, 255); using Mat dst = new Mat(); Cv2.Rectangle(src, new Rect(30, 30, 40, 40), Scalar.Black, 1); Cv2.MorphologyEx(src, dst, MorphTypes.Dilate, null); ShowImagesWhenDebugMode(src, dst); Assert.Equal(src.Rows * src.Cols, Cv2.CountNonZero(dst)); }
public void MorphologyExErode() { using Mat src = Mat.Zeros(100, 100, MatType.CV_8UC1); using Mat dst = new Mat(); Cv2.Rectangle(src, new Rect(30, 30, 40, 40), Scalar.White, 1); Cv2.MorphologyEx(src, dst, MorphTypes.Erode, null); ShowImagesWhenDebugMode(src, dst); Assert.Equal(0, Cv2.CountNonZero(dst)); }
public static int SearchImagePercentage(Bitmap source, Tuple <double, double, double> lower, Tuple <double, double, double> upper) { var sourceMat = BitmapConverter.ToMat(source); var colorMat = sourceMat.CvtColor(ColorConversionCodes.RGB2HSV); var thresholded = new Mat(); Cv2.InRange(colorMat, new Scalar(lower.Item3, lower.Item1, lower.Item2), new Scalar(upper.Item3, upper.Item1, upper.Item2), thresholded); return(Cv2.CountNonZero(thresholded) / (source.Width * source.Height)); }
private List <Mat> getIndividualBoxes(Mat unwarped) { int pixelnum = 3; List <Mat> boxes = new List <Mat>(); Point[][] contours; HierarchyIndex[] hierarchyIndex; int inc = unwarped.Rows / 9; for (int x = 0; x < 9; x += 1) { for (int y = 0; y < 9; y += 1) { int xind = x * inc; int yind = y * inc; var num = unwarped.SubMat(xind + pixelnum, xind - pixelnum + inc, yind + pixelnum, yind - pixelnum + inc); if (Cv2.CountNonZero(num) < 100) { boxes.Add(null); } else { num.FindContours(out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxSimple); Point[] LargestContour = new Point[1]; double maxArea = 0; foreach (var c in contours) { double tempArea = Cv2.ContourArea(c); if (tempArea > maxArea) { maxArea = tempArea; LargestContour = c; } } int w = 25; Rect rec = Cv2.BoundingRect(LargestContour); Mat numbox = new Mat(w, w, MatType.CV_8UC1); var dest = new Point2f[] { new Point2f(0, 0), new Point2f(0, w), new Point2f(w, w), new Point2f(w, 0) }; var transform = Cv2.GetPerspectiveTransform(rect2Contour(rec), dest); Cv2.WarpPerspective(num, numbox, transform, new Size(w, w)); boxes.Add(numbox); } } } return(boxes); }
/// <summary> /// 現在撮影している画像をDiffence of Gaussianm→二値化し、hitピクセルの数を数えます。 /// </summary> /// <returns>hitピクセルの数</returns> public int CountHitPixels() { Camera camera = Camera.GetInstance(); byte[] b = camera.ArrayImage; Mat mat0 = new Mat(440, 512, MatType.CV_8U, b); Mat mat = mat0.Clone(); Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); Mat gau = mat.Clone(); Cv2.GaussianBlur(gau, gau, Cv.Size(31, 31), -1); Cv2.Subtract(gau, mat, mat); Cv2.Threshold(mat, mat, BinarizeThreshold, 1, ThresholdType.Binary); brightness = Cv2.CountNonZero(mat); return(brightness); }
private void PictureBox1_MouseUp(object sender, MouseEventArgs e) { if (e.Button != MouseButtons.Left) { return; } ldrag = false; if (_mask != null) { _tmp = _mask & (byte)GrabCutClasses.FGD; var c = Cv2.CountNonZero(_tmp); if (c > 0) { _mask.CopyTo(_gcut); Cv2.GrabCut(_src, _gcut, new Rect(), _bgd, _fgd, 1, GrabCutModes.InitWithMask); show(); } } }
protected static void ImageEquals(Mat img1, Mat img2) { if (img1 == null && img2 == null) { return; } Assert.NotNull(img1); Assert.NotNull(img2); #pragma warning disable CS8602 #pragma warning disable CA1062 Assert.Equal(img1.Type(), img2.Type()); #pragma warning restore CS8602 #pragma warning restore CA1062 using (var comparison = new Mat()) { Cv2.Compare(img1, img2, comparison, CmpTypes.NE); if (img1.Channels() == 1) { Assert.Equal(0, Cv2.CountNonZero(comparison)); } else { var channels = Cv2.Split(comparison); try { foreach (var channel in channels) { Assert.Equal(0, Cv2.CountNonZero(channel)); } } finally { foreach (var channel in channels) { channel.Dispose(); } } } } }
/// <summary> /// Detect the eye state from the landmark points. /// </summary> /// <param name="frame">The current video frame.</param> /// <param name="shape">The current landmark points.</param> private void DetectEyeState(System.Drawing.Bitmap frame, FullObjectDetection shape) { // get all landmark points of the left eye var leftEye = from i in Enumerable.Range(36, 6) let p = shape.GetPart((uint)i) select new OpenCvSharp.Point(p.X, p.Y); // get all landmark points of the right eye var rightEye = from i in Enumerable.Range(42, 6) let p = shape.GetPart((uint)i) select new OpenCvSharp.Point(p.X, p.Y); // draw the eye areas into a new image using (var mask = new Mat(new Size(frame.Width, frame.Height), MatType.CV_8UC1)) { mask.SetTo(0); Cv2.FillConvexPoly(mask, leftEye, Scalar.White); Cv2.FillConvexPoly(mask, rightEye, Scalar.White); // calculate surface area of both eyes int area = Cv2.CountNonZero(mask); // the maximum possible area is 40% of the surface area of both eyeballs int r1 = (shape.GetPart(39).X - shape.GetPart(36).X) / 2; int r2 = (shape.GetPart(45).X - shape.GetPart(42).X) / 2; double normalizedArea = 0.4 * Math.PI * r1 * r1 + 0.4 * Math.PI * r2 * r2; // calculate fractional area and normalize on a 0-100 scale var value = (int)(100 * area / normalizedArea - 20); eyeStateValue = value >= 0 && value <= 100 ? value : 0; // calculate bounding box around eyes var rect = Cv2.BoundingRect(Enumerable.Union(leftEye, rightEye)); rect.Inflate(30, 30); // copy the eye image to the picturebox var maskImg = BitmapConverter.ToBitmap(mask.Clone(rect)); eyeBox.Image = maskImg; } }
/// <summary> /// 霍夫变换,再反复迭代找出合适的线。效果hin差 /// </summary> /// <param name="input_img"></param> private void H_ough(Mat input_img) { ///<霍夫变换> int dianshu_threshold = Cv2.CountNonZero(input_img) / 100; //以白色点数为锚确定霍夫变换threshold LineSegmentPoint[] lineSegmentPoint; //创建接收数组 while (true) //循环找出合适的阈值 { lineSegmentPoint = Cv2.HoughLinesP(input_img, 1.0, Cv2.PI / 180, dianshu_threshold, 0, 0); //进行霍夫变换直线检测 //int line_number = lineSegmentPoint.Length; if (lineSegmentPoint.Length < 4) { dianshu_threshold -= 2; } else if (lineSegmentPoint.Length > 8) { dianshu_threshold += 1; } else { Console.WriteLine("线貌似可以了"); Console.WriteLine(lineSegmentPoint.Length); break; } break; } using (Mat SeeLines = new Mat("D:/XD/1-dis/pic/1.jpg", ImreadModes.Color)) { Cv2.Resize(SeeLines, SeeLines, new OpenCvSharp.Size(SeeLines.Width * 0.25, SeeLines.Height * 0.25)); for (int i = 0; i < lineSegmentPoint.Length; i++) { Cv2.Line(SeeLines, lineSegmentPoint[i].P1, lineSegmentPoint[i].P2, Scalar.RandomColor(), 3); } using (new Window("lines", SeeLines)) { Cv2.WaitKey(0); } } }
protected void ImageEquals(Mat img1, Mat img2) { if (img1 == null && img2 == null) { return; } Assert.NotNull(img1); Assert.NotNull(img2); Assert.AreEqual(img1.Type(), img2.Type()); using (var comparison = new Mat()) { Cv2.Compare(img1, img2, comparison, CmpTypes.NE); if (img1.Channels() == 1) { Assert.Zero(Cv2.CountNonZero(comparison)); } else { var channels = Cv2.Split(comparison); try { foreach (var channel in channels) { Assert.Zero(Cv2.CountNonZero(channel)); } } finally { foreach (var channel in channels) { channel.Dispose(); } } } } }
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; } } }
/// <summary> /// /// </summary> /// <param name="img"></param> /// <param name="rho"></param> /// <param name="theta"></param> /// <param name="threshold"></param> /// <param name="minLineLength"></param> /// <param name="maxLineGap"></param> /// <param name="thetaMin"></param> /// <param name="thetaMax"></param> /// <returns></returns> public static LineSegmentPoint[] HoughLinesProbabilisticEx(this Mat img, double rho, double theta, int threshold, double minLineLength, double maxLineGap, double thetaMin = 0, double thetaMax = Math.PI) { if (img == null) { throw new ArgumentNullException(nameof(img)); } if (img.Type() != MatType.CV_8UC1) { throw new ArgumentException("The source matrix must be 8-bit, single-channel image."); } if (rho <= 0) { throw new ArgumentOutOfRangeException(nameof(rho)); } if (theta <= 0) { throw new ArgumentOutOfRangeException(nameof(theta)); } if (threshold <= 0) { throw new ArgumentOutOfRangeException(nameof(threshold)); } if (minLineLength <= 0) { throw new ArgumentOutOfRangeException(nameof(minLineLength)); } if (thetaMax < thetaMin) { throw new ArgumentException("thetaMax < thetaMin"); } if (thetaMax > Math.PI) { throw new ArgumentOutOfRangeException(nameof(thetaMax), "thetaMax <= pi"); } if (thetaMin < 0) { throw new ArgumentOutOfRangeException(nameof(thetaMin), "thetaMin >= 0"); } unsafe { // 画像パラメータの収集 byte *data = (byte *)img.DataStart; int width = img.Cols; int height = img.Rows; int step = (int)img.Step(); // sin, cosのLUTを作っておく double numAngleAll = Math.PI / theta; int angleMin = (int)Math.Round(numAngleAll * (thetaMin / Math.PI)); //(int)Math.Round(thetaMin * 180 / Cv.PI); int angleMax = (int)Math.Round(numAngleAll * (thetaMax / Math.PI)); int numAngle = angleMax - angleMin; int numRho = (int)Math.Round(((width + height) * 2 + 1) / rho); double[] sin = new double[angleMax]; // 大きめに作成。angleMinより手前の要素は使わない double[] cos = new double[angleMax]; { double rad = thetaMin; double irho = 1 / rho; for (int t = angleMin; t < angleMax; t++, rad += theta) { sin[t] = Math.Sin(rad * irho); cos[t] = Math.Cos(rad * irho); } } // 1. 非0の点を収集 Point[] points = new Point[Cv2.CountNonZero(img)]; bool[] mask = new bool[width * height]; int i = 0; for (int y = 0; y < height; y++) { byte *p = data + y * step; int offset = y * width; for (int x = 0; x < width; x++) { if (p[x] != 0) { mask[offset + x] = true; points[i++] = new Point(x, y); } else { mask[offset + x] = false; } } } // ランダムな順に並び変え Shuffle(points); // 2. 画素をランダムに選択し処理 var accum = new int[numAngle * numRho]; var result = new List <LineSegmentPoint>(); for (int count = 0; count < points.Length; count++) { Point pt = points[count]; // 画素データが更新されているのは除外 if (!mask[pt.Y * width + pt.X]) { continue; } // 2.1 [θ,ρ]空間で投票し、投票値が最大値となるθを求める int maxR = threshold - 1; int maxT = 0; fixed(int *paccum = accum) { int *adata = paccum; for (int t = angleMin; t < angleMax; t++, adata += numRho) { int r = (int)Math.Round(pt.X * cos[t] + pt.Y * sin[t]); r += (numRho - 1) / 2; int val = ++adata[r]; if (maxR < val) { maxR = val; maxT = t; } } } if (maxR < threshold) { continue; } // 2.2 追尾用の増分値 (dx0,dy0) の設定 double a = -sin[maxT]; double b = cos[maxT]; int x0 = pt.X; int y0 = pt.Y; int dx0, dy0; bool xflag; const int shift = 16; if (Math.Abs(a) > Math.Abs(b)) { xflag = true; dx0 = a > 0 ? 1 : -1; dy0 = (int)Math.Round(b * (1 << shift) / Math.Abs(a)); y0 = (y0 << shift) + (1 << (shift - 1)); } else { xflag = false; dy0 = b > 0 ? 1 : -1; dx0 = (int)Math.Round(a * (1 << shift) / Math.Abs(b)); x0 = (x0 << shift) + (1 << (shift - 1)); } // 2.3 線分画素を両端方向に追尾し、線分を抽出 Point[] lineEnd = { new Point(), new Point() }; for (int k = 0; k < 2; k++) { int gap = 0; int x = x0, y = y0, dx = dx0, dy = dy0; if (k > 0) { dx = -dx; dy = -dy; } // walk along the line using fixed-point arithmetics, // stop at the image border or in case of too big gap for (; ; x += dx, y += dy) { int x1, y1; if (xflag) { x1 = x; y1 = y >> shift; } else { x1 = x >> shift; y1 = y; } if (x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) { break; } // for each non-zero point: // update line end, // clear the mask element // reset the gap if (mask[y1 * width + x1]) { gap = 0; lineEnd[k].X = x1; lineEnd[k].Y = y1; } else if (++gap > maxLineGap) { break; } } } // lineLengthより長いものを線分候補とする bool goodLine = Math.Abs(lineEnd[1].X - lineEnd[0].X) >= minLineLength || Math.Abs(lineEnd[1].Y - lineEnd[0].Y) >= minLineLength; // 2.4 追尾した画素を削除し、次回以降は処理されないようにする //if (processOnce) { for (int k = 0; k < 2; k++) { int x = x0, y = y0, dx = dx0, dy = dy0; if (k > 0) { dx = -dx; dy = -dy; } // walk along the line using fixed-point arithmetics, // stop at the image border or in case of too big gap for (; ; x += dx, y += dy) { int x1, y1; if (xflag) { x1 = x; y1 = y >> shift; } else { x1 = x >> shift; y1 = y; } // for each non-zero point: // update line end, // clear the mask element // reset the gap if (mask[y1 * width + x1]) { if (goodLine) { fixed(int *paccum = accum) { int *adata = paccum; for (int t = angleMin; t < angleMax; t++, adata += numRho) { int r = (int)Math.Round(x1 * cos[t] + y1 * sin[t]); r += (numRho - 1) / 2; adata[r]--; } } } mask[y1 * width + x1] = false; } if (y1 == lineEnd[k].Y && x1 == lineEnd[k].X) { break; } } } } if (goodLine) { result.Add(new LineSegmentPoint(lineEnd[0], lineEnd[1])); } } return(result.ToArray()); } }
private void task() { MotorControler mc = MotorControler.GetInstance(parameterManager); Surface sur = Surface.GetInstance(parameterManager); Camera camera = Camera.GetInstance(); Led led = Led.GetInstance(); CoordManager cm = new CoordManager(parameterManager); Vector3 InitPoint = mc.GetPoint(); List <Vector2> list_grid_pred = new List <Vector2>(); List <Vector2> list_grid_meas = new List <Vector2>(); List <Vector2> list_grid_part = new List <Vector2>(); List <Vector2> list_grid_meas2 = new List <Vector2>(); /* * list_grid_pred.Add(new Vector2( 0.0, 0.0)); * list_grid_pred.Add(new Vector2(30.0, 0.0)); * list_grid_pred.Add(new Vector2( 0.0, 30.0)); * list_grid_pred.Add(new Vector2(30.0, 30.0)); * * list_grid_pred.Add(new Vector2(60.0, 0.0)); * list_grid_pred.Add(new Vector2(0.0, 60.0)); * list_grid_pred.Add(new Vector2(60.0, 60.0)); * * * * * //list_grid_pred.Add(new Vector2(0.0, 10.0)); * //list_grid_pred.Add(new Vector2(10.0, 0.0)); * //list_grid_pred.Add(new Vector2(10.0, 10.0)); * * //list_grid_pred.Add(new Vector2(20.0, 0.0)); * //list_grid_pred.Add(new Vector2(0.0, 20.0)); * //list_grid_pred.Add(new Vector2(20.0, 20.0)); * * //list_grid_pred.Add(new Vector2(20.0, 10.0)); * //list_grid_pred.Add(new Vector2(30.0, 0.0)); * //list_grid_pred.Add(new Vector2(30.0, 10.0)); * //list_grid_pred.Add(new Vector2(10.0, 20.0)); * //list_grid_pred.Add(new Vector2(30.0, 20.0)); * //list_grid_pred.Add(new Vector2(10.0, 30.0)); * //list_grid_pred.Add(new Vector2(20.0, 30.0)); * * camera.Start(); * * Affine ap = new Affine(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); * for (int i = 0; i < list_grid_pred.Count; i++) { * Vector2 predpoint = ap.Trance(list_grid_pred[i]); * //mc.MovePoint(predpoint.X, predpoint.Y, InitPoint.Z + 0.030); * mc.MoveTo(new Vector3(predpoint.X, predpoint.Y, InitPoint.Z + 0.030), new Vector3(0, 0, 0), new Vector3(0, 0, 0)); * mc.Join(); * * led.AdjustLight(parameterManager); * * * bool flag = true; * while (flag) { * mc.MoveDistance(-0.003, VectorId.Z); * mc.Join(); * * * byte[] b = camera.ArrayImage; * Mat src = new Mat(440, 512, MatType.CV_8U, b); * Mat mat = src.Clone(); * * Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); * Mat gau = mat.Clone(); * Cv2.GaussianBlur(gau, gau, Cv.Size(7, 7), -1); * Cv2.Subtract(gau, mat, mat); * Cv2.Threshold(mat, mat, 4, 1, ThresholdType.Binary); * int brightness = Cv2.CountNonZero(mat); * * if (brightness > 5000 ) flag = false; * } * * Thread.Sleep(100); * * mc.SetSpiralCenterPoint(); * flag = true; * int counter = 0; * while (flag) { * if(counter!=0){ * mc.MoveInSpiral(true); * mc.Join(); * } * counter++; * * Camera c = Camera.GetInstance(); * byte[] b = c.ArrayImage; * Mat mat = new Mat(440, 512, MatType.CV_8U, b); * Cv2.GaussianBlur(mat, mat, Cv.Size(7, 7), -1); * * Cv2.Threshold(mat, mat, 60, 255, ThresholdType.BinaryInv); * * Moments mom = new Moments(mat); * if (mom.M00 < 1000 * 255) continue; * * double cx = mom.M10 / mom.M00; * double cy = mom.M01 / mom.M00; * Mat innercir = Mat.Zeros(440, 512, MatType.CV_8UC1); * Cv2.Circle(innercir, new Point(cx, cy), 10, new Scalar(255, 255, 255), 3); * int innerpath = Cv2.CountNonZero(innercir); * Cv2.BitwiseAnd(innercir, mat, innercir); * int innersum = Cv2.CountNonZero(innercir); * * Mat outercir = Mat.Zeros(440, 512, MatType.CV_8UC1); * Cv2.Circle(outercir, new Point(cx, cy), 100, new Scalar(255, 255, 255), 3); * int outerpath = Cv2.CountNonZero(outercir); * Cv2.BitwiseAnd(outercir, mat, outercir); * int outersum = Cv2.CountNonZero(outercir); * * double innerratio = innersum * 1.0 / innerpath * 1.0; * double outerratio = outersum * 1.0 / outerpath * 1.0; * * if (innerratio < 0.8) continue; * if (outerratio > 0.2) continue; * * flag = false; * * * // * Vector2 grid_meas = cm.TransToEmulsionCoord((int)(cx), (int)(cy)); * * Vector3 to = new Vector3(grid_meas.X, grid_meas.Y, mc.GetPoint().Z); * mc.MoveTo(to, new Vector3(0, 0, 0), new Vector3(0, 0, 0)); * mc.Join(); * * b = c.ArrayImage; * mat = new Mat(440, 512, MatType.CV_8U, b); * Cv2.GaussianBlur(mat, mat, Cv.Size(7, 7), -1); * * Cv2.Threshold(mat, mat, 60, 255, ThresholdType.BinaryInv); * * mom = new Moments(mat); * if (mom.M00 < 1000 * 255) continue; * * cx = mom.M10 / mom.M00; * cy = mom.M01 / mom.M00; * innercir = Mat.Zeros(440, 512, MatType.CV_8UC1); * Cv2.Circle(innercir, new Point(cx, cy), 10, new Scalar(255, 255, 255), 3); * innerpath = Cv2.CountNonZero(innercir); * Cv2.BitwiseAnd(innercir, mat, innercir); * innersum = Cv2.CountNonZero(innercir); * * outercir = Mat.Zeros(440, 512, MatType.CV_8UC1); * Cv2.Circle(outercir, new Point(cx, cy), 100, new Scalar(255, 255, 255), 3); * outerpath = Cv2.CountNonZero(outercir); * Cv2.BitwiseAnd(outercir, mat, outercir); * outersum = Cv2.CountNonZero(outercir); * * innerratio = innersum * 1.0 / innerpath * 1.0; * outerratio = outersum * 1.0 / outerpath * 1.0; * * if (innerratio < 0.8) continue; * if (outerratio > 0.2) continue; * * grid_meas = cm.TransToEmulsionCoord((int)(cx), (int)(cy)); * System.Diagnostics.Debug.WriteLine(string.Format("gridmark {0} {1}", grid_meas.X, grid_meas.Y)); * * * list_grid_meas.Add(grid_meas); * list_grid_part.Add(list_grid_pred[i]); * if (i >= 3) { * ap = Affine.CreateAffineBy(list_grid_part, list_grid_meas); * } * } * * * }//for(int i = 0; i < list_grid_pred.Count; i++) */ Affine ap = new Affine(1.00055550, -0.00152264, 0.00174182, 1.00096792, 12.7498, -62.5798); string txtfileName = string.Format(@"c:\img\grid_g.txt"); StreamWriter twriter = File.CreateText(txtfileName); for (int x = 0; x < 6; x++) { for (int y = 0; y < 6; y++) { //if (x == 0 && y == 5) continue; //if (x == 1 && y == 5) continue; Vector2 predpoint = ap.Trance(new Vector2(x * 10, y * 10)); mc.MoveTo(new Vector3(predpoint.X, predpoint.Y, InitPoint.Z + 0.030)); mc.Join(); led.AdjustLight(parameterManager); bool flag = true; while (flag) { mc.MoveDistance(-0.003, VectorId.Z); mc.Join(); byte[] b = camera.ArrayImage; Mat src = new Mat(440, 512, MatType.CV_8U, b); Mat mat = src.Clone(); Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); Mat gau = mat.Clone(); Cv2.GaussianBlur(gau, gau, Cv.Size(7, 7), -1); Cv2.Subtract(gau, mat, mat); Cv2.Threshold(mat, mat, 4, 1, ThresholdType.Binary); int brightness = Cv2.CountNonZero(mat); if (brightness > 5000) { flag = false; } } Thread.Sleep(100); byte[] b2 = camera.ArrayImage; Mat src2 = new Mat(440, 512, MatType.CV_8U, b2); Mat mat2 = src2.Clone(); string FileName = string.Format(@"C:\img\x{0}_y{1}.bmp", x, y); Cv2.ImWrite(FileName, mat2); Cv2.GaussianBlur(mat2, mat2, Cv.Size(7, 7), -1); Cv2.Threshold(mat2, mat2, 60, 255, ThresholdType.BinaryInv); Moments mom2 = new Moments(mat2); double cx2 = mom2.M10 / mom2.M00; double cy2 = mom2.M01 / mom2.M00; /* Mat innercir = Mat.Zeros(440, 512, MatType.CV_8UC1); * Cv2.Circle(innercir, new Point(cx2, cy2), 10, new Scalar(255, 255, 255), 3); * int innerpath = Cv2.CountNonZero(innercir); * Cv2.BitwiseAnd(innercir, mat2, innercir); * int innersum = Cv2.CountNonZero(innercir); * * Mat outercir = Mat.Zeros(440, 512, MatType.CV_8UC1); * Cv2.Circle(outercir, new Point(cx2, cy2), 100, new Scalar(255, 255, 255), 3); * int outerpath = Cv2.CountNonZero(outercir); * Cv2.BitwiseAnd(outercir, mat2, outercir); * int outersum = Cv2.CountNonZero(outercir); * * double innerratio = innersum * 1.0 / innerpath * 1.0; * double outerratio = outersum * 1.0 / outerpath * 1.0; */ Vector2 grid_meas2 = cm.TransToEmulsionCoord((int)(cx2), (int)(cy2)); FileName = string.Format(@"C:\img\after_x{0}_y{1}.bmp", x, y); Cv2.ImWrite(FileName, mat2); string stlog = ""; stlog += String.Format("{0} {1} {2:f4} {3:f4} {4:f4} {5:f4}\n", x * 10, y * 10, predpoint.X, predpoint.Y, grid_meas2.X, grid_meas2.Y); twriter.Write(stlog); } //for y } //for x twriter.Close(); }
public Mat Run(Mat img1, Mat img2) { Mat img3 = new Mat(Math.Max(img1.Height, img2.Height), img2.Width + img1.Width, MatType.CV_8UC3).SetTo(0); using (var descriptors1 = new Mat()) using (var descriptors2 = new Mat()) using (var matcher = new BFMatcher(NormTypes.L2SQR)) using (var kaze = KAZE.Create()) { kaze.DetectAndCompute(img1, null, out keypoints1, descriptors1); kaze.DetectAndCompute(img2, null, out keypoints2, descriptors2); if (descriptors1.Width > 0 && descriptors2.Width > 0) { DMatch[][] matches = matcher.KnnMatch(descriptors1, descriptors2, 2); using (Mat mask = new Mat(matches.Length, 1, MatType.CV_8U)) { mask.SetTo(Scalar.White); int nonZero = Cv2.CountNonZero(mask); VoteForUniqueness(matches, mask); nonZero = Cv2.CountNonZero(mask); nonZero = VoteForSizeAndOrientation(keypoints2, keypoints1, matches, mask, 1.5f, 10); List <Point2f> obj = new List <Point2f>(); List <Point2f> scene = new List <Point2f>(); List <DMatch> goodMatchesList = new List <DMatch>(); //iterate through the mask only pulling out nonzero items because they're matches MatIndexer <byte> maskIndexer = mask.GetGenericIndexer <byte>(); for (int i = 0; i < mask.Rows; i++) { if (maskIndexer[i] > 0) { obj.Add(keypoints1[matches[i][0].QueryIdx].Pt); scene.Add(keypoints2[matches[i][0].TrainIdx].Pt); goodMatchesList.Add(matches[i][0]); } } List <Point2d> objPts = obj.ConvertAll(Point2fToPoint2d); List <Point2d> scenePts = scene.ConvertAll(Point2fToPoint2d); if (nonZero >= 4) { Mat homography = Cv2.FindHomography(objPts, scenePts, HomographyMethods.Ransac, 1.5, mask); nonZero = Cv2.CountNonZero(mask); if (homography != null && homography.Width > 0) { Point2f[] objCorners = { new Point2f(0, 0), new Point2f(img1.Cols, 0), new Point2f(img1.Cols, img1.Rows), new Point2f(0, img1.Rows) }; Point2d[] sceneCorners = MyPerspectiveTransform3(objCorners, homography); //This is a good concat horizontal using (Mat left = new Mat(img3, new Rect(0, 0, img1.Width, img1.Height))) using (Mat right = new Mat(img3, new Rect(img1.Width, 0, img2.Width, img2.Height))) { img1.CopyTo(left); img2.CopyTo(right); byte[] maskBytes = new byte[mask.Rows * mask.Cols]; mask.GetArray(out maskBytes); Cv2.DrawMatches(img1, keypoints1, img2, keypoints2, goodMatchesList, img3, Scalar.All(-1), Scalar.All(-1), maskBytes, DrawMatchesFlags.NotDrawSinglePoints); List <List <Point> > listOfListOfPoint2D = new List <List <Point> >(); List <Point> listOfPoint2D = new List <Point>(); listOfPoint2D.Add(new Point(sceneCorners[0].X + img1.Cols, sceneCorners[0].Y)); listOfPoint2D.Add(new Point(sceneCorners[1].X + img1.Cols, sceneCorners[1].Y)); listOfPoint2D.Add(new Point(sceneCorners[2].X + img1.Cols, sceneCorners[2].Y)); listOfPoint2D.Add(new Point(sceneCorners[3].X + img1.Cols, sceneCorners[3].Y)); listOfListOfPoint2D.Add(listOfPoint2D); img3.Polylines(listOfListOfPoint2D, true, Scalar.LimeGreen, 2); //This works too //Cv2.Line(img3, scene_corners[0] + new Point2d(img1.Cols, 0), scene_corners[1] + new Point2d(img1.Cols, 0), Scalar.LimeGreen); //Cv2.Line(img3, scene_corners[1] + new Point2d(img1.Cols, 0), scene_corners[2] + new Point2d(img1.Cols, 0), Scalar.LimeGreen); //Cv2.Line(img3, scene_corners[2] + new Point2d(img1.Cols, 0), scene_corners[3] + new Point2d(img1.Cols, 0), Scalar.LimeGreen); //Cv2.Line(img3, scene_corners[3] + new Point2d(img1.Cols, 0), scene_corners[0] + new Point2d(img1.Cols, 0), Scalar.LimeGreen); } } } } } return(img3); } }
static void Main(string[] args) { if (!Directory.Exists(Settings.Images.Output)) { Directory.CreateDirectory(Settings.Images.Output); } if (!Directory.Exists(Settings.Images.Dump)) { Directory.CreateDirectory(Settings.Images.Dump); } var listOfImages = Directory.GetFiles(Settings.Images.Source, "*.jpg").ToList(); //!Uncomment next line for select images by freq listOfImages = listOfImages.Where(x => x.Contains("940")).ToList(); //! Comment from this to dump loading for dump load, lol //? get list of all filenames without .jpg and generate cntr PalmsList listOfImages.ForEach(x => { x = x.Remove(0, x.LastIndexOf('\\') + 1).Replace(".jpg", ""); var owner = x.Substring(0, x.Length - 3); PalmsList.Add(new PalmModel() { Id = x.Substring(x.Length - 2), Owner = owner, FileName = x, Directory = $@"{Settings.Images.Output}{owner}" }); }); //? get names and create name collection //? create dirs for saving data var userNames = PalmsList.DistinctBy(x => x.Owner); userNames.ForEach(x => { UsersList.Add(new UserModel() { Name = x.Owner, Patterns = new List <Mat> (), Directory = x.Directory }); if (Directory.Exists(x.Directory) && Directory.GetFiles(x.Directory).Length > 0) { Directory.Delete(x.Directory, true); // recursive } Directory.CreateDirectory(x.Directory); }); Console.WriteLine($"Total users: {UsersList.Count}"); Console.WriteLine($"Total palm collection: {PalmsList.Count}"); var totalROIExtractionTime = new Stopwatch(); totalROIExtractionTime.Start(); //! ROI extraction Console.WriteLine($"[{DateTime.Now}] ROI extraction"); var ROITask = Task.Factory.StartNew(() => { PalmsList.ForEach(x => { Task.Factory.StartNew(() => { var path = $@"{Settings.Images.Source}\{x.FileName}.jpg"; x.SourceImage = Cv2.ImRead(path, ImreadModes.Color); x.Height = x.SourceImage.Size().Height; x.Width = x.SourceImage.Size().Width; //! apply threshold Cv2.CvtColor(x.SourceImage, x.SourceImage, ColorConversionCodes.BGR2GRAY); // 0, 255 x.ThresholdImage = x.SourceImage.Threshold(5, 255, ThresholdTypes.Otsu); // save for debug #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\binary_{x.Id}.jpg", x.ThresholdImage); #endif //! ROI extraction var i1 = x.Height - 50; var i2 = x.Width - 50; var radius = 50; int pX = 0; int pY = 0; for (int i = 50; i != i1; i++) { for (int j = 50; j != i2; j++) { if (x.ThresholdImage.Get <byte> (i, j) == Settings.COLOR_WHITE) { int a = 0; for (a = 1; a < 360; a++) { var y1 = Convert.ToInt16(j + radius * Math.Cos(a * Math.PI / 180)); var x1 = Convert.ToInt16(i - radius * Math.Sin(a * Math.PI / 180)); if (x1 < 1 || x1 > i1 || y1 < 1 || y1 > i2 || x.ThresholdImage.Get <byte> (x1, y1) == Settings.COLOR_BLACK) { break; } } if (a == 360) { radius += 10; pX = i; pY = j; } } } } radius -= 10; var x0 = Convert.ToInt16(pY - Math.Sqrt(2) * radius / 2); var y0 = Convert.ToInt16(pX - Math.Sqrt(2) * radius / 2); var wsize = Convert.ToInt16(Math.Sqrt(2) * radius); var rect = new Rect(x0, y0, wsize, wsize); // for visual debug Mat drawROIImage = new Mat(); x.SourceImage.CopyTo(drawROIImage); drawROIImage.Rectangle(rect, Scalar.White); x.ROI = new Mat(x.SourceImage, rect) .Resize(new Size(216, 216)); Cv2.Rotate(x.ROI, x.ROI, RotateFlags.Rotate90Counterclockwise); #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\ROIOnSource_{x.Id}.jpg", drawROIImage); Cv2.ImWrite($@"{x.Directory}\ROI_{x.Id}.jpg", x.ROI); #endif }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.RunContinuationsAsynchronously); }); }); ROITask.Wait(); totalROIExtractionTime.Stop(); Console.WriteLine($"[{DateTime.Now}] Total ROI extracton time: {totalROIExtractionTime.Elapsed}"); //! Create dump Dump.ROI.Create(Settings.Images.Dump, PalmsList); //! Uncomment next block for loading images from dump and comment all lines before this // PalmsList = Dump.ROI.Load(Settings.Images.Dump, listOfImages); // var countFrom = 0; // var countTo = PalmsList.Count; // ------------------------------ //! Apply filters Console.WriteLine($"[{DateTime.Now}] Apply filters to ROI image"); totalROIExtractionTime.Reset(); totalROIExtractionTime.Start(); var filtersTask = Task.Factory.StartNew(() => { PalmsList.ForEach(x => { Task.Factory.StartNew(() => { //! Reduce noise Cv2.MedianBlur(x.ROI, x.ROI, 5); #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\ROI_Median_{x.Id}.jpg", x.ROI); #endif // Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.BGR2GRAY); Cv2.FastNlMeansDenoising(x.ROI, x.ROI); Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.GRAY2BGR); #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\reduce_noise_{x.Id}.jpg", x.ROI); #endif //! Equalize hist var element = Cv2.GetStructuringElement(MorphShapes.Cross, Settings.ElementSize); // new Mat(7, 7, MatType.CV_8U); Cv2.MorphologyEx(x.ROI, x.ROI, MorphTypes.Open, element); Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.BGR2YUV); // Cv2.EqualizeHist(x.ROI, x.ROI); var RGB = Cv2.Split(x.ROI); RGB[0] = RGB[0].EqualizeHist(); RGB[1] = RGB[1].EqualizeHist(); RGB[2] = RGB[2].EqualizeHist(); Cv2.Merge(RGB, x.ROI); Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.YUV2BGR); #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\equalized_hist_{x.Id}.jpg", x.ROI); #endif //! Invert image Cv2.BitwiseNot(x.ROI, x.ROI); #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\inverted_{x.Id}.jpg", x.ROI); #endif //! Erode image Cv2.CvtColor(x.ROI, x.ROI, ColorConversionCodes.BGR2GRAY); Cv2.Erode(x.ROI, x.ROI, element); #if SAVEALLRESULTS Cv2.ImWrite($@"{x.Directory}\eroded_{x.Id}.jpg", x.ROI); #endif //! Skeletonize var skel = new Mat(x.ROI.Size(), MatType.CV_8UC1, new Scalar(0)); var temp = new Mat(); var eroded = new Mat(); do { Cv2.MorphologyEx(x.ROI, eroded, MorphTypes.Erode, element); Cv2.MorphologyEx(eroded, temp, MorphTypes.Dilate, element); Cv2.Subtract(x.ROI, temp, temp); Cv2.BitwiseOr(skel, temp, skel); eroded.CopyTo(x.ROI); } while (Cv2.CountNonZero(x.ROI) != 0); //! Threshold skeletonized image var thr = skel.Threshold(0, 255, ThresholdTypes.Binary); //! Remove contours thr.Line(new Point(0, 0), new Point(0, thr.Height), Scalar.Black, 2); // rm left contour thr.Line(new Point(0, 0), new Point(thr.Width, 0), Scalar.Black, 2); // rm top contour thr.Line(new Point(thr.Width, thr.Height), new Point(thr.Width, 0), Scalar.Black, 2); // rm right contour thr.Line(new Point(thr.Width, thr.Height), new Point(0, thr.Height), Scalar.Black, 2); // rm bot contour //! Normalize contours element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(6, 6)); Cv2.Dilate(thr, thr, element); Cv2.Erode(thr, thr, element); Cv2.MorphologyEx(thr, thr, MorphTypes.Gradient, element); Cv2.ImWrite($@"{x.Directory}\{x.Id}.jpg", thr); var owner = UsersList.Find(u => u.Name == x.Owner); owner.Patterns.Add(thr); // add thresholded image to user patterns }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.RunContinuationsAsynchronously); }); }); filtersTask.Wait(); totalROIExtractionTime.Stop(); Console.WriteLine($"[{DateTime.Now}] Total apply filters time: {totalROIExtractionTime.Elapsed}"); //! Create dump with users and they patterns Dump.Patterns.Create(Settings.Images.Dump, UsersList); //! Create CSV file Dump.CSV.Create(Settings.Images.CSV, PalmsList); }
/// <summary> /// 识别棋子坐标&颜色 /// </summary> public List <Tuple <int, int, int> > GetChessCoorinate(Bitmap wzqBoardImage) { //把Bitmap转换成Mat Mat boardMat = BitmapConverter.ToMat(wzqBoardImage); //因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做) Mat blurBoardMat = new Mat(); Cv2.MedianBlur(boardMat, blurBoardMat, 9); //转为灰度图像 Mat grayBoardMat = new Mat(); Cv2.CvtColor(blurBoardMat, grayBoardMat, ColorConversionCodes.BGR2GRAY); //3:霍夫圆检测:使用霍夫变换查找灰度图像中的圆。 CircleSegment[] circleSegments = Cv2.HoughCircles( grayBoardMat, HoughMethods.Gradient, 1, chessStep * 0.4, 70, 30, (int)(chessStep * 0.3), (int)(chessStep * 0.5)); //判断棋子位置,遍历棋盘上的每个位置 List <Tuple <int, int, int> > chessPointList = new List <Tuple <int, int, int> >(); //行 for (int i = 0; i < rows; i++) { //列 for (int j = 0; j < rows; j++) { //棋盘棋子坐标 Point2f point = new Point2f(j * chessStep + 0.5f * chessStep, i * chessStep + 0.5f * chessStep); foreach (var circleSegment in circleSegments) { //有棋子 if (circleSegment.Center.DistanceTo(point) < 0.5 * chessStep) { //检查棋子的颜色 //以棋子中心为中心点,截取一部分图片(圆内切正方形),来计算图片颜色 //r^2 = a^2 + a^2 //--> a= ((r^2)/2)^-2 double len = Math.Sqrt(circleSegment.Radius * circleSegment.Radius / 2); Rect rect = new Rect((int)(circleSegment.Center.X - len), (int)(circleSegment.Center.Y - len), (int)(len * 2), (int)(len * 2)); Mat squareMat = new Mat(grayBoardMat, rect); //计算颜色 Mat calculatedMat = new Mat(); Cv2.InRange(squareMat, scalarLower, scalarUpper, calculatedMat); float result = 100f * Cv2.CountNonZero(calculatedMat) / (calculatedMat.Width * calculatedMat.Height); chessPointList.Add(new Tuple <int, int, int>(i + 1, j + 1, result < 50 ? 1 : 2)); break; } } } } return(chessPointList); }
/// <summary> /// グリッドマークを入力中の映像から探し出し,その座標を返します. /// <para>発見に失敗した場合はGridMakrNotFoundExceptionが投げられます.</para> /// </summary> /// <returns>グリッドマークの座標</returns> /// <exception cref="LensTypeException">レンズが10倍に設定されていない場合</exception> /// <exception cref="GridMarkNotFoundException">グリッドマークの探索に失敗した場合</exception> public Vector2 SearchGridMark() { int status = 0; // レンズが10倍に設定されていない場合は例外を返す if (parameterManager.Magnification != ParameterManager.LensMagnificationOfGridMarkSearch) { throw new LensTypeException(ParameterManager.LensMagnificationOfGridMarkSearch); } Camera c = Camera.GetInstance(); byte[] b = c.ArrayImage; Mat mat0 = new Mat(440, 512, MatType.CV_8U, b); Mat mat = mat0.Clone(); Cv2.GaussianBlur(mat, mat, Cv.Size(121, 121), -1); mat.ImWrite(String.Format(@"c:\img\{0}_b.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"))); Mat gau = mat.Clone(); Cv2.GaussianBlur(gau, gau, Cv.Size(231, 231), -1); Cv2.Subtract(gau, mat, mat); mat.ImWrite(String.Format(@"c:\img\{0}_d.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"))); Cv2.Threshold(mat, mat, 22, 255, ThresholdType.Binary); mat.ImWrite(String.Format(@"c:\img\{0}_t.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"))); Moments mom = new Moments(mat); if (mom.M00 == 0) { status++; } if (mom.M00 > 4000 * 255) { status++; //面積分布のヒストグラムから設定。面積4000pix以内。2015Dec } if (status != 0) { throw new GridMarkNotFoundException(); } double cx = mom.M10 / mom.M00; double cy = mom.M01 / mom.M00; Mat innercir = Mat.Zeros(440, 512, MatType.CV_8UC1); Cv2.Circle(innercir, new Point(cx, cy), 10, new Scalar(255, 255, 255), 3); int innerpath = Cv2.CountNonZero(innercir); Cv2.BitwiseAnd(innercir, mat, innercir); int innersum = Cv2.CountNonZero(innercir); //Cv2.ImShow("inner", innercir); Mat outercir = Mat.Zeros(440, 512, MatType.CV_8UC1); Cv2.Circle(outercir, new Point(cx, cy), 40, new Scalar(255, 255, 255), 3); int outerpath = Cv2.CountNonZero(outercir); Cv2.BitwiseAnd(outercir, mat, outercir); int outersum = Cv2.CountNonZero(outercir); //Cv2.ImShow("outer", outercir); double innerratio = innersum * 1.0 / innerpath * 1.0; double outerratio = outersum * 1.0 / outerpath * 1.0; if (innerratio < 0.7) { status++; } if (outerratio > 0.2) { status++; } //System.Diagnostics.Debug.WriteLine(String.Format("{0}, {1}, {2}", innerratio, outerratio, mom.M00)); if (status != 0) { throw new GridMarkNotFoundException(); } return(new Vector2(cx, cy)); //#if !NoHardware // int gridMarkSize = (int)parameterManager.GridMarkSize; // int status = new CameraUtil().MarkCenter(ref x, ref y, gridMarkSize); // if (status != 0) { // throw new GridMarkNotFoundException(); // } //#endif }
private void Holes1(Mat cropped_image) { try { Holecount = 0; Mat hole_crop = new Mat(); OpenCvSharp.Point[][] contour; HierarchyIndex[] hier; OpenCvSharp.Rect rect1 = new OpenCvSharp.Rect(); OpenCvSharp.Size ksize = new OpenCvSharp.Size(3, 3); OpenCvSharp.Size kksize = new OpenCvSharp.Size(5, 5); Mat element = Cv2.GetStructuringElement(MorphShapes.Cross, ksize); Mat element1 = Cv2.GetStructuringElement(MorphShapes.Cross, kksize); cropped_image.CopyTo(hole_crop); if (hole_crop.Channels() == 1) { Cv2.CvtColor(hole_crop, hole_crop, ColorConversionCodes.GRAY2BGR); } OpenCvSharp.Rect roi1 = new OpenCvSharp.Rect(47, 320, 180, 236); //47,340,180,220 47, 338, 180, 220 Cv2.Rectangle(hole_crop, roi1, Scalar.Green, 3); //3 OpenCvSharp.Point pnt1 = new OpenCvSharp.Point(roi1.X, roi1.Y); Cv2.PutText(hole_crop, 1.ToString(), pnt1, HersheyFonts.HersheyPlain, 8, Scalar.Red, 5); OpenCvSharp.Rect roi2 = new OpenCvSharp.Rect(430, 27, 200, 215); //370,25,200,200 //430,30,200,210 Cv2.Rectangle(hole_crop, roi2, Scalar.Green, 3); //3 OpenCvSharp.Point pnt2 = new OpenCvSharp.Point(roi2.X - 80, roi2.Y + 80); Cv2.PutText(hole_crop, 2.ToString(), pnt2, HersheyFonts.HersheyPlain, 8, Scalar.Red, 5); OpenCvSharp.Rect roi3 = new OpenCvSharp.Rect(881, 320, 202, 250); //870,320,200,250 877, 320, 200, 250 Cv2.Rectangle(hole_crop, roi3, Scalar.Green, 3); //3 OpenCvSharp.Point pnt3 = new OpenCvSharp.Point(roi3.X, roi3.Y); Cv2.PutText(hole_crop, 3.ToString(), pnt3, HersheyFonts.HersheyPlain, 8, Scalar.Red, 5); OpenCvSharp.Rect roi4 = new OpenCvSharp.Rect(550, 780, 185, 220); //580,800,200,200 550, 790, 170, 210 550, 800, 170, 200 Cv2.Rectangle(hole_crop, roi4, Scalar.Green, 3); //3 OpenCvSharp.Point pnt4 = new OpenCvSharp.Point(roi4.X, roi4.Y); Cv2.PutText(hole_crop, 4.ToString(), pnt4, HersheyFonts.HersheyPlain, 8, Scalar.Red, 5); hole_crop.CopyTo(crop1); if (crop1.Channels() > 1) { Cv2.CvtColor(crop1, crop1, ColorConversionCodes.BGR2GRAY); } for (int a = 0; a < 4; a++) { if (a == 0) { Mat tempcrop = new Mat(crop1, roi1); Cv2.Threshold(tempcrop, tempcrop, 90, 255, ThresholdTypes.Otsu); //110 Cv2.Dilate(tempcrop, tempcrop, element1, null, 1); //1 Cv2.Erode(tempcrop, tempcrop, element, null, 4); //6 Cv2.FindContours(tempcrop, out contour, out hier, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple); for (int b = 0; b < contour.Length; b++) { rect1 = Cv2.BoundingRect(contour[b]); if (Cv2.ContourArea(contour[b]) > 800 && Cv2.ContourArea(contour[b]) < 3000)//300,4000 { rect1 = Cv2.BoundingRect(contour[b]); Mat spot_img = new Mat(tempcrop, rect1); int white_pix = Cv2.CountNonZero(spot_img); int black_pix = spot_img.Width * spot_img.Height - white_pix; double aspectratio = Convert.ToDouble(rect1.Width) / Convert.ToDouble(rect1.Height); if (aspectratio > 0.83 && aspectratio < 1.65 && black_pix > white_pix) // 0.83,1.80 { //if (rect1.Height > 25 && rect1.Height < 250 & rect1.Width > 30 && rect1.Width < 200)//10,200,200,10//25,250,30,200 //{ OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(rect1.X + roi1.X, rect1.Y + roi1.Y, rect1.Width, rect1.Height); Cv2.Rectangle(hole_crop, hole_rect, Scalar.LimeGreen, 5); Cv2.DrawContours(tempcrop, contour, b, Scalar.Blue, 3); Holecount++; Hole_absent = true; break; //} } } } if (!Hole_absent == true) { OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(47, 320, 180, 236); Cv2.Rectangle(hole_crop, hole_rect, Scalar.Red, 5); } Hole_absent = false; //Cv2.NamedWindow("color", WindowFlags.Normal); //Cv2.ImShow("color", tempcrop); } if (a == 1) { Mat tempcrop1 = new Mat(crop1, roi2); Cv2.AdaptiveThreshold(tempcrop1, tempcrop1, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 89, 58); //89,58 Cv2.Erode(tempcrop1, tempcrop1, element1, null, 4); //6 Cv2.FindContours(tempcrop1, out contour, out hier, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple); for (int b = 0; b < contour.Length; b++) { if (Cv2.ContourArea(contour[b]) > 500 && Cv2.ContourArea(contour[b]) < 4000)// //600,12000 { rect1 = Cv2.BoundingRect(contour[b]); Mat spot_img = new Mat(tempcrop1, rect1); //Cv2.NamedWindow("con", WindowFlags.Normal); //Cv2.ImShow("con", spot_img); //Cv2.ImWrite("con1.bmp", spot_img); int white_pix = Cv2.CountNonZero(spot_img); int black_pix = spot_img.Width * spot_img.Height - white_pix + 10; double aspectratio = Convert.ToDouble(rect1.Width) / Convert.ToDouble(rect1.Height); if (aspectratio < 1.55 && aspectratio > 0.80 /*&& black_pix > white_pix*/) //1.38 0.80 1.45,0.80 { if (rect1.Height > 25 && rect1.Height < 80 & rect1.Width < 80 && rect1.Width > 25) //22,80,80,25 { OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(rect1.X + roi2.X, rect1.Y + roi2.Y, rect1.Width, rect1.Height); Cv2.Rectangle(hole_crop, hole_rect, Scalar.LimeGreen, 5); Cv2.DrawContours(tempcrop1, contour, b, Scalar.Blue, 3); Holecount++; Hole_absent = true; break; } } } } if (!Hole_absent == true) { OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(430, 27, 200, 215); Cv2.Rectangle(hole_crop, hole_rect, Scalar.Red, 5); } Hole_absent = false; //Cv2.NamedWindow("color1", WindowFlags.Normal); //Cv2.ImShow("color1", tempcrop1); } if (a == 2) { Mat tempcrop = new Mat(crop1, roi3); Cv2.AdaptiveThreshold(tempcrop, tempcrop, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 71, 19); Cv2.MorphologyEx(tempcrop, tempcrop, MorphTypes.Close, element); Cv2.FindContours(tempcrop, out contour, out hier, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple); for (int b = 0; b < contour.Length; b++) { if (Cv2.ContourArea(contour[b]) > 500 && Cv2.ContourArea(contour[b]) < 10000)//300,4000 300,6000 { rect1 = Cv2.BoundingRect(contour[b]); Mat spot_img = new Mat(tempcrop, rect1); int white_pix = Cv2.CountNonZero(spot_img); int black_pix = spot_img.Width * spot_img.Height - white_pix; double aspectratio = Convert.ToDouble(rect1.Width) / Convert.ToDouble(rect1.Height); if (aspectratio < 1.55 && aspectratio > 0.75 && black_pix > white_pix /*|| white_pix < 2000 || black_pix > 500*/)//1.43 0.75 { //if (rect1.Height > 28 && rect1.Height < 200 & rect1.Width < 300 && rect1.Width > 30)//30,200,300,30 //{ OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(rect1.X + roi3.X, rect1.Y + roi3.Y, rect1.Width, rect1.Height); Cv2.Rectangle(hole_crop, hole_rect, Scalar.LimeGreen, 5); Cv2.DrawContours(tempcrop, contour, b, Scalar.Blue, 3); Holecount++; Hole_absent = true; break; //} } } } if (!Hole_absent == true) { OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(881, 320, 202, 250); Cv2.Rectangle(hole_crop, hole_rect, Scalar.Red, 5); } Hole_absent = false; //Cv2.NamedWindow("color2", WindowFlags.Normal); //Cv2.ImShow("color2", tempcrop); } if (a == 3) { Mat tempcrop = new Mat(crop1, roi4); Cv2.Threshold(tempcrop, tempcrop, 90, 255, ThresholdTypes.Otsu); //60//98 Cv2.Dilate(tempcrop, tempcrop, element1, null, 1); //1 Cv2.AdaptiveThreshold(tempcrop, tempcrop, 255, AdaptiveThresholdTypes.MeanC, ThresholdTypes.Binary, 75, 171); //71,171 Cv2.Erode(tempcrop, tempcrop, element1, null, 3); //4 Cv2.FindContours(tempcrop, out contour, out hier, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple); for (int b = 0; b < contour.Length; b++) { rect1 = Cv2.BoundingRect(contour[b]); if (Cv2.ContourArea(contour[b]) > 1000 && Cv2.ContourArea(contour[b]) < 4000)//1000,4000 { rect1 = Cv2.BoundingRect(contour[b]); Mat spot_img = new Mat(tempcrop, rect1); int white_pix = Cv2.CountNonZero(spot_img); int black_pix = spot_img.Width * spot_img.Height - white_pix; double aspectratio = Convert.ToDouble(rect1.Width) / Convert.ToDouble(rect1.Height); if (aspectratio > 0.40 && aspectratio < 1.50 && black_pix > white_pix)//1.10 0.80 0.40,1.40 { //if (rect1.Height > 30 && rect1.Height < 300 && rect1.Width >20 && rect1.Width < 200)//30,90,90,30 30,300,20,200 //{ OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(rect1.X + roi4.X, rect1.Y + roi4.Y, rect1.Width, rect1.Height); Cv2.Rectangle(hole_crop, hole_rect, Scalar.LimeGreen, 5); Cv2.DrawContours(tempcrop, contour, b, Scalar.Blue, 3); Holecount++; Hole_absent = true; break; //} } } } if (!Hole_absent == true) { OpenCvSharp.Rect hole_rect = new OpenCvSharp.Rect(550, 780, 185, 220); Cv2.Rectangle(hole_crop, hole_rect, Scalar.Red, 5); } Hole_absent = false; //Cv2.NamedWindow("color3", WindowFlags.Normal); //Cv2.ImShow("color3", tempcrop); } hole_crop.CopyTo(finalimg); } } catch (Exception Ex) { //MessageBox.Show(Ex.Message.ToString()); log.Error("Error Message: " + Ex.Message.ToString(), Ex); } }
private void task() { MotorControler mc = MotorControler.GetInstance(parameterManager); Surface sur = Surface.GetInstance(parameterManager); Camera camera = Camera.GetInstance(); Led led = Led.GetInstance(); Vector3 InitPoint = mc.GetPoint(); Vector3 p = new Vector3(); double emthickness = sur.UpTop - sur.UpBottom; int nshot = (int)(emthickness / 0.003); int blockXCounter = 0; int blockYCounter = 0; while (blockYCounter < nyView) { while (blockXCounter < nxView) { string txtfileName = string.Format(@"{0}\{1}.txt" , direcotryPath , System.DateTime.Now.ToString("yyyyMMdd_HHmmss_ffff") ); StreamWriter twriter = File.CreateText(txtfileName); //Vector3 InitPointofThisBlock = new Vector3( // InitPoint.X + blockXCounter * 4.350, // InitPoint.Y + blockYCounter * 4.390, // InitPoint.Z // ); //Vector3 SurfPointofThisBlock = new Vector3( // InitPointofThisBlock.X + 2.200, // InitPointofThisBlock.Y + 2.200, // InitPoint.Z // ); Vector3 InitPointofThisBlock = new Vector3( InitPoint.X + (double)(blockXCounter) * ((0.210 - 0.01) * 10 - 0.030), //if x40 -> 2.150, InitPoint.Y - (double)(blockYCounter) * ((0.180 - 0.01) * 10 - 0.030), //if x40 -> 2.170, InitPoint.Z ); Vector3 SurfPointofThisBlock = new Vector3( InitPointofThisBlock.X + 1.000, InitPointofThisBlock.Y - 1.000, InitPoint.Z ); //go to surface measurement mc.MovePoint(SurfPointofThisBlock.X, SurfPointofThisBlock.Y, sur.UpTop + 0.050);//above 50micron mc.Join(); //surface landing bool flag = true; int layercounter = 0; camera.Start(); while (flag) { mc.MoveDistance(-0.003, VectorId.Z); mc.Join(); byte[] b = camera.ArrayImage; Mat src = new Mat(440, 512, MatType.CV_8U, b); Mat mat = src.Clone(); Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); Mat gau = mat.Clone(); Cv2.GaussianBlur(gau, gau, Cv.Size(31, 31), -1); Cv2.Subtract(gau, mat, mat); Cv2.Threshold(mat, mat, 10, 1, ThresholdType.Binary); int brightness = Cv2.CountNonZero(mat); layercounter++; if (brightness > 10000 || layercounter > 30) { flag = false; } } led.AdjustLight(parameterManager); camera.Stop(); //surface double surfacetopz = mc.GetPoint().Z; double surfacebottomz = surfacetopz - emthickness; //data taking int rowcounter = 0; int colcounter = 0; //while (rowcounter < 24) { // while (colcounter < 20) { while (rowcounter < 12) { while (colcounter < 10) { string stlog = ""; byte[] bb = new byte[440 * 512 * nshot]; double startZ = 0.0; PlusMinus plusminus; if (colcounter % 2 == 0) { //camera.Start(); //led.AdjustLight(parameterManager); //camera.Stop(); startZ = surfacetopz + 0.012; plusminus = PlusMinus.Minus; } else { startZ = surfacebottomz - 0.009; plusminus = PlusMinus.Plus; } double prev_z = startZ; mc.MovePoint( InitPointofThisBlock.X + (0.210 - 0.01) * colcounter, //x40, 0.230-0.01 //parameterManager.SpiralShiftX InitPointofThisBlock.Y - (0.180 - 0.01) * rowcounter, //x40, 0.195-0.01 //parameterManager.SpiralShiftY startZ); mc.Join(); p = mc.GetPoint(); DateTime starttime = System.DateTime.Now; string datfileName = string.Format(@"{0}\{1}_x{2}_y{3}_xi{4}_yi{5}.dat", direcotryPath, starttime.ToString("yyyyMMdd_HHmmss"), (int)(p.X * 1000), (int)(p.Y * 1000), colcounter, rowcounter ); BinaryWriter writer = new BinaryWriter(File.Open(datfileName, FileMode.Create)); mc.Inch(plusminus, 0.15, VectorId.Z); int viewcounter = 0; while (viewcounter < nshot + 3) { byte[] b = Ipt.CaptureMain(); p = mc.GetPoint(); TimeSpan ts = System.DateTime.Now - starttime; stlog += String.Format("{0} {1} {2} {3} {4} {5} {6} {7}\n", colcounter % 2, System.DateTime.Now.ToString("HHmmss\\.fff"), ts.ToString("s\\.fff"), (p.X * 1000).ToString("0.0"), (p.Y * 1000).ToString("0.0"), (p.Z * 1000).ToString("0.0"), (prev_z * 1000 - p.Z * 1000).ToString("0.0"), viewcounter); prev_z = p.Z; if (viewcounter >= 3) { b.CopyTo(bb, 440 * 512 * (viewcounter - 3)); } viewcounter++; }//view viewcounter = 0; mc.SlowDownStop(VectorId.Z); twriter.Write(stlog); writer.Write(bb); writer.Flush(); writer.Close(); colcounter++; }//col colcounter = 0; rowcounter++; }//row rowcounter = 0; twriter.Close(); blockXCounter++; }//blockX blockXCounter = 0; blockYCounter++; }//blockY blockYCounter = 0; camera.Start(); }//end of task()
private void thread(Mat inimg) { try { threadcount = 0; Mat thread = new Mat(); Mat thread_copy = new Mat(); OpenCvSharp.Point[][] contour1; HierarchyIndex[] hier1; OpenCvSharp.Rect rect3 = new OpenCvSharp.Rect(); OpenCvSharp.Size kksize = new OpenCvSharp.Size(1, 1); Mat element = Cv2.GetStructuringElement(MorphShapes.Cross, kksize); if (crop.Channels() > 1) { Cv2.CvtColor(crop, crop, ColorConversionCodes.BGR2GRAY); } OpenCvSharp.Rect rectan = new OpenCvSharp.Rect(205, 200, 700, 700); //Cv2.Rectangle(crop, rectan, Scalar.White, 2); Mat thread_crop = new Mat(crop, rectan); Cv2.NamedWindow("tempcrop", WindowFlags.Normal); Cv2.ImShow("tempcrop", thread_crop); template_matching(crop, temp_match); //template_matching(thread_crop, temp_match); resizeimg.CopyTo(thread); //Cv2.NamedWindow("templete", WindowFlags.Normal); //Cv2.ImShow("templete", resizeimg); if (thread.Channels() > 1) { Cv2.CvtColor(thread, thread, ColorConversionCodes.BGR2GRAY); } OpenCvSharp.Rect thread_roi1 = new OpenCvSharp.Rect(50, 90, 33, 23); //48, 84, 33, 23 Cv2.Rectangle(thread, thread_roi1, Scalar.Black, -1); OpenCvSharp.Rect final_rect = new OpenCvSharp.Rect(20, 23, 105, 80); //20,23,105,80 Cv2.Rectangle(thread, final_rect, Scalar.Green, 1); thread = new Mat(thread, final_rect); //Cv2.NamedWindow("mask", WindowFlags.Normal); //Cv2.ImShow("mask", thread); thread.CopyTo(thread_copy); Cv2.Sobel(thread, thread, MatType.CV_8UC1, 0, 1, 1); Cv2.Threshold(thread, thread, 120, 255, ThresholdTypes.Otsu); //Cv2.NamedWindow("inrange", WindowFlags.Normal); //Cv2.ImShow("inrange", thread); pixelcount = Cv2.CountNonZero(thread); Cv2.FindContours(thread, out contour1, out hier1, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple); if (thread_copy.Channels() == 1) { Cv2.CvtColor(thread_copy, thread_copy, ColorConversionCodes.GRAY2BGR); } for (int i = 0; i < contour1.Length; i++) { rect3 = Cv2.BoundingRect(contour1[i]); if (Cv2.ContourArea(contour1[i]) > 15 && Cv2.ContourArea(contour1[i]) < 1000) //60,500 20,1000 { if (rect3.Width > 2 && rect3.Width < 90 && rect3.Height < 26 && rect3.Height > 1) //20,90,26,3 { Cv2.DrawContours(thread_copy, contour1, i, Scalar.LimeGreen, 2); threadcount++; } } } //Cv2.NamedWindow("templete1", WindowFlags.Normal); //Cv2.ImShow("templete1", thread_copy); Cv2.ImWrite("thread" + ".bmp", resizeimg); } catch (Exception Ex) { //MessageBox.Show(Ex.Message.ToString()); log.Error("Error Message: " + Ex.Message.ToString(), Ex); } }
private void dealimage(String path, String savepath) { Mat result = Cv2.ImRead(path); Scalar color = new Scalar(0, 0, 0); Cv2.CopyMakeBorder(result, result, 10, 10, 10, 10, BorderTypes.Constant, color); Mat outp = new Mat(); Cv2.CvtColor(result, outp, ColorConversionCodes.BGR2GRAY); Mat thresh = new Mat(); Cv2.Threshold(outp, thresh, 0, 255, ThresholdTypes.Binary); /* Cv2.ImShow("2", thresh); * Cv2.WaitKey(-1);*/ OpenCvSharp.Point[][] counts; HierarchyIndex[] hierarchyIndices; Cv2.FindContours(thresh.Clone(), out counts, out hierarchyIndices, RetrievalModes.External, ContourApproximationModes.ApproxSimple); double max = 0; OpenCvSharp.Point[] point = null; foreach (var count in counts) { if (max < Cv2.ContourArea(count)) { point = count; max = Cv2.ContourArea(count); } } Console.WriteLine(thresh.Rows); Console.WriteLine(thresh.Cols); /*int** mask = new int[][];*/ Rect rect = Cv2.BoundingRect(point); Mat mat = Mat.Zeros(thresh.Rows, thresh.Cols, thresh.Type()); Cv2.Rectangle(mat, rect.TopLeft, rect.BottomRight, 255, -1); Mat minRect = mat.Clone(); Mat sub = mat.Clone(); while (Cv2.CountNonZero(sub) > 0) { Cv2.Erode(minRect, minRect, null); Cv2.Subtract(minRect, thresh, sub); } Cv2.FindContours(minRect.Clone(), out counts, out hierarchyIndices, RetrievalModes.External, ContourApproximationModes.ApproxSimple); max = 0; foreach (var count in counts) { if (max < Cv2.ContourArea(count)) { point = count; max = Cv2.ContourArea(count); } } rect = Cv2.BoundingRect(point); result = new Mat(result, rect); savepath = savepath + "/" + "result.jpg"; Cv2.ImWrite(savepath, result); try { pictureBox1.Image = Image.FromFile(savepath); } catch (Exception e) { } MessageBox.Show("拼接成功"); }
static void Main1(string[] args) { Process[] processes = Process.GetProcesses(); Process wzqProcess = null; foreach (var item in processes) { if (item.MainWindowTitle == "五子棋") { Console.WriteLine(item.ProcessName); Console.WriteLine(item.Id); //窗口名 Console.WriteLine(item.MainWindowTitle); Console.WriteLine(item.MainModule.FileName); Console.WriteLine(item.MainModule.FileVersionInfo.FileVersion); Console.WriteLine(item.MainModule.FileVersionInfo.FileDescription); Console.WriteLine(item.MainModule.FileVersionInfo.Comments); Console.WriteLine(item.MainModule.FileVersionInfo.CompanyName); Console.WriteLine(item.MainModule.FileVersionInfo.FileName); //产品名 Console.WriteLine(item.MainModule.FileVersionInfo.ProductName); Console.WriteLine(item.MainModule.FileVersionInfo.ProductVersion); Console.WriteLine(item.StartTime); Console.WriteLine(item.MainWindowHandle); wzqProcess = item; break; } } Bitmap bitmap = CaptureImage.Captuer(wzqProcess); if (bitmap == null) { return; } //bitmap.Save("a.bmp"); //Process.Start("mspaint", "a.bmp"); //左上角 //227 129 //右下角 //721 621 int width = 721 - 227; int height = 621 - 129; int step = width * 15 / 14 / 15; Bitmap wzqBoardImage = new Bitmap(width * 15 / 14, height * 15 / 14); Graphics g = Graphics.FromImage(wzqBoardImage); // // 摘要: // 在指定位置并且按指定大小绘制指定的 System.Drawing.Image 的指定部分。 // // 参数: // image: // 要绘制的 System.Drawing.Image。 // // destRect: // System.Drawing.Rectangle 结构,它指定所绘制图像的位置和大小。 将图像进行缩放以适合该矩形。 // // srcRect: // System.Drawing.Rectangle 结构,它指定 image 对象中要绘制的部分。 // // srcUnit: // System.Drawing.GraphicsUnit 枚举的成员,它指定 srcRect 参数所用的度量单位。 g.DrawImage(bitmap, new Rectangle(0, 0, wzqBoardImage.Width, wzqBoardImage.Height), new Rectangle(227 - step / 2, 129 - step / 2, wzqBoardImage.Width, wzqBoardImage.Height), GraphicsUnit.Pixel); g.Dispose(); //把Bitmap转换成Mat Mat boardMat = BitmapConverter.ToMat(wzqBoardImage); //因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做) Mat blurBoardMat = new Mat(); Cv2.MedianBlur(boardMat, blurBoardMat, 9); //转为灰度图像 Mat grayBoardMat = new Mat(); Cv2.CvtColor(blurBoardMat, grayBoardMat, ColorConversionCodes.BGR2GRAY); //3:霍夫圆检测:使用霍夫变换查找灰度图像中的圆。 CircleSegment[] circleSegments = Cv2.HoughCircles(grayBoardMat, HoughMethods.Gradient, 1, step * 0.4, 70, 30, (int)(step * 0.3), (int)(step * 0.5)); foreach (var circleSegment in circleSegments) { Cv2.Circle(boardMat, (int)circleSegment.Center.X, (int)circleSegment.Center.Y, (int)circleSegment.Radius, Scalar.Red, 1, LineTypes.AntiAlias); } //判断棋子位置,遍历棋盘上的每个位置 int rows = 15; List <Tuple <int, int, int> > chessPointList = new List <Tuple <int, int, int> >(); //计算棋子颜色的阈值 Scalar scalarLower = new Scalar(128, 128, 128); Scalar scalarUpper = new Scalar(255, 255, 255); //行 for (int i = 0; i < rows; i++) { //列 for (int j = 0; j < rows; j++) { //棋盘棋子坐标 Point2f point = new Point2f(j * step + 0.5f * step, i * step + 0.5f * step); foreach (var circleSegment in circleSegments) { //有棋子 if (circleSegment.Center.DistanceTo(point) < 0.5 * step) { //检查棋子的颜色 //以棋子中心为中心点,截取一部分图片(圆内切正方形),来计算图片颜色 //r^2 = a^2 + a^2 //--> a= ((r^2)/2)^-2 double len = Math.Sqrt(circleSegment.Radius * circleSegment.Radius / 2); Rect rect = new Rect((int)(circleSegment.Center.X - len), (int)(circleSegment.Center.Y - len), (int)(len * 2), (int)(len * 2)); Mat squareMat = new Mat(grayBoardMat, rect); //计算颜色 Mat calculatedMat = new Mat(); Cv2.InRange(squareMat, scalarLower, scalarUpper, calculatedMat); float result = 100f * Cv2.CountNonZero(calculatedMat) / (calculatedMat.Width * calculatedMat.Height); chessPointList.Add(new Tuple <int, int, int>(i + 1, j + 1, result < 50 ? 0 : 1)); break; } } } } foreach (var item in chessPointList) { Console.WriteLine($"{item.Item1},{item.Item2},{item.Item3}"); } Cv2.ImShow("boardMat", boardMat); Cv2.WaitKey(); }
private void task() { /* * MotorControler mc = MotorControler.GetInstance(parameterManager); * mc.SetMotorSpeed(MotorSpeed.Speed4); * * Camera camera = Camera.GetInstance(); * Vector3 InitPoint = mc.GetPoint(); * Vector3 p = new Vector3(); * int viewcounter = 0; * int rowcounter = 0; * int colcounter = 0; * * while (rowcounter < 2) { * while (colcounter < 2) { * mc.MovePoint( * InitPoint.X + (parameterManager.ImageLengthX - 0.01) * colcounter, * InitPoint.Y + (parameterManager.ImageLengthY - 0.01) * rowcounter, * InitPoint.Z + 0.01); * mc.Join(); * * p = mc.GetPoint(); * * bool flag = true; * while (flag) { * mc.MoveDistance(-0.003, VectorId.Z); * mc.Join(); * byte[] b = camera.ArrayImage; * Mat src = new Mat(440, 512, MatType.CV_8U, b); * Mat mat = src.Clone(); * * Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); * Mat gau = mat.Clone(); * Cv2.GaussianBlur(gau, gau, Cv.Size(31, 31), -1); * Cv2.Subtract(gau, mat, mat); * Cv2.Threshold(mat, mat, 10, 1, ThresholdType.Binary); * int brightness = Cv2.CountNonZero(mat); * * viewcounter++; * if (brightness > 10000 || viewcounter > 30) flag = false; * } * * p = mc.GetPoint(); * byte[] bb = camera.ArrayImage; * Mat mat2 = new Mat(440, 512, MatType.CV_8U, bb); * mat2.ImWrite(String.Format(@"c:\img\{0}_{1}_{2}_{3}.bmp", * System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"), * (int)(p.X * 1000), * (int)(p.Y * 1000), * (int)(p.Z * 1000))); * * string datfileName = string.Format(@"c:\img\{0}_{1}_{2}.dat", * System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"), * (int)(p.X * 1000), * (int)(p.Y * 1000)); * BinaryWriter writer = new BinaryWriter(File.Open(datfileName, FileMode.Create)); * * flag = true; * while (flag) { * byte[] b = camera.ArrayImage; * Mat src = new Mat(440, 512, MatType.CV_8U, b); * writer.Write(b); * Mat mat = src.Clone(); * Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); * Mat gau = mat.Clone(); * Cv2.GaussianBlur(gau, gau, Cv.Size(31, 31), -1); * Cv2.Subtract(gau, mat, mat); * Cv2.Threshold(mat, mat, 10, 1, ThresholdType.Binary); * int brightness = Cv2.CountNonZero(mat); * viewcounter++; * if (brightness < 3000) flag = false; * mc.MoveDistance(-0.004, VectorId.Z); * mc.Join(); * } * * writer.Close(); * * viewcounter = 0; * colcounter++; * } * colcounter = 0; * rowcounter++; * } */ /* * MotorControler mc = MotorControler.GetInstance(parameterManager); * Camera camera = Camera.GetInstance(); * Vector3 InitPoint = mc.GetPoint(); * Vector3 p = new Vector3(); * int viewcounter = 0; * int rowcounter = 0; * int colcounter = 0; * * while (rowcounter < 45) { * while (colcounter < 40) { * mc.MovePoint( * InitPoint.X + (parameterManager.ImageLengthX - 0.01) * colcounter, * InitPoint.Y + (parameterManager.ImageLengthY - 0.01) * rowcounter, * InitPoint.Z + 0.01); * mc.Join(); * * p = mc.GetPoint(); * * bool flag = true; * while (flag) { * mc.MoveDistance(-0.003, VectorId.Z); * mc.Join(); * byte[] b = camera.ArrayImage; * Mat src = new Mat(440, 512, MatType.CV_8U, b); * Mat mat = src.Clone(); * * Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); * Mat gau = mat.Clone(); * Cv2.GaussianBlur(gau, gau, Cv.Size(31, 31), -1); * Cv2.Subtract(gau, mat, mat); * Cv2.Threshold(mat, mat, 10, 1, ThresholdType.Binary); * int brightness = Cv2.CountNonZero(mat); * * viewcounter++; * if (brightness > 10000 || viewcounter > 30) flag = false; * } * * p = mc.GetPoint(); * byte[] bb = camera.ArrayImage; * Mat mat2 = new Mat(440, 512, MatType.CV_8U, bb); * mat2.ImWrite(String.Format(@"c:\img\{0}_{1}_{2}_{3}.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"), * (int)(p.X * 1000), * (int)(p.Y * 1000), * (int)(p.Z * 1000))); * * viewcounter = 0; * colcounter++; * } * colcounter = 0; * rowcounter++; * } */ MotorControler mc = MotorControler.GetInstance(parameterManager); Camera camera = Camera.GetInstance(); int viewcounter = 0; bool flag = true; while (flag) { mc.MoveDistance(-0.003, VectorId.Z); mc.Join(); byte[] b = camera.ArrayImage; Mat src = new Mat(440, 512, MatType.CV_8U, b); Mat mat = src.Clone(); Cv2.GaussianBlur(mat, mat, Cv.Size(3, 3), -1); Mat gau = mat.Clone(); Cv2.GaussianBlur(gau, gau, Cv.Size(31, 31), -1); Cv2.Subtract(gau, mat, mat); Cv2.Threshold(mat, mat, 10, 1, ThresholdType.Binary); int brightness = Cv2.CountNonZero(mat); viewcounter++; if (brightness > 10000 || viewcounter > 30) { flag = false; } } byte[] bb = camera.ArrayImage; Mat mat2 = new Mat(440, 512, MatType.CV_8U, bb); Vector3 p = new Vector3(); mat2.ImWrite(String.Format(@"c:\img\{0}_{1}_{2}_{3}.bmp", System.DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"), (int)(p.X * 1000), (int)(p.Y * 1000), (int)(p.Z * 1000))); }
//img1:test image; img2:ref img public float MatchTemplate(Mat img1, Mat img2, bool ishowImageMatchTemplate, string s = "Match") { float matchRate = 0.0f; using (var descriptors1 = new Mat()) using (var descriptors2 = new Mat()) using (var matcher = new BFMatcher(NormTypes.L2SQR)) using (var kaze = KAZE.Create()) { KeyPoint[] keypoints1, keypoints2; kaze.DetectAndCompute(img1, null, out keypoints1, descriptors1); kaze.DetectAndCompute(img2, null, out keypoints2, descriptors2); DMatch[][] matches = matcher.KnnMatch(descriptors1, descriptors2, 2); using (Mat mask = new Mat(matches.Length, 1, MatType.CV_8U)) { mask.SetTo(new Scalar(255)); int nonZero = Cv2.CountNonZero(mask); VoteForUniqueness(matches, mask); nonZero = Cv2.CountNonZero(mask); nonZero = VoteForSizeAndOrientation(keypoints2, keypoints1, matches, mask, 1.5f, 20); List <Point2f> obj = new List <Point2f>(); List <Point2f> scene = new List <Point2f>(); List <DMatch> goodMatchesList = new List <DMatch>(); //iterate through the mask only pulling out nonzero items because they're matches for (int i = 0; i < mask.Rows; i++) { MatIndexer <byte> maskIndexer = mask.GetGenericIndexer <byte>(); if (maskIndexer[i] > 0) { obj.Add(keypoints1[matches[i][0].QueryIdx].Pt); scene.Add(keypoints2[matches[i][0].TrainIdx].Pt); goodMatchesList.Add(matches[i][0]); } } List <Point2d> objPts = obj.ConvertAll(Point2fToPoint2d); List <Point2d> scenePts = scene.ConvertAll(Point2fToPoint2d); if (nonZero >= 4) { Mat homography = Cv2.FindHomography(objPts, scenePts, HomographyMethods.Ransac, 1.5, mask); nonZero = Cv2.CountNonZero(mask); //calculate match rate by how many match points exist //matchRate = (float)nonZero / keypoints2.Count(); matchRate = 1 - (float)(keypoints2.Count() - nonZero) / (keypoints2.Count() + nonZero); if (homography != null && ishowImageMatchTemplate == true) { Point2f[] objCorners = { new Point2f(0, 0), new Point2f(img1.Cols, 0), new Point2f(img1.Cols, img1.Rows), new Point2f(0, img1.Rows) }; Point2d[] sceneCorners = MyPerspectiveTransform3(objCorners, homography); //This is a good concat horizontal using (Mat img3 = new Mat(Math.Max(img1.Height, img2.Height), img2.Width + img1.Width, MatType.CV_8UC3)) using (Mat left = new Mat(img3, new Rect(0, 0, img1.Width, img1.Height))) using (Mat right = new Mat(img3, new Rect(img1.Width, 0, img2.Width, img2.Height))) { img1.CopyTo(left); img2.CopyTo(right); byte[] maskBytes = new byte[mask.Rows * mask.Cols]; mask.GetArray(0, 0, maskBytes); Cv2.DrawMatches(img1, keypoints1, img2, keypoints2, goodMatchesList, img3, Scalar.All(-1), Scalar.All(-1), maskBytes, DrawMatchesFlags.NotDrawSinglePoints); //List<List<Point>> listOfListOfPoint2D = new List<List<Point>>(); //List<Point> listOfPoint2D = new List<Point>(); //listOfPoint2D.Add(new Point(sceneCorners[0].X + img1.Cols, sceneCorners[0].Y)); //listOfPoint2D.Add(new Point(sceneCorners[1].X + img1.Cols, sceneCorners[1].Y)); //listOfPoint2D.Add(new Point(sceneCorners[2].X + img1.Cols, sceneCorners[2].Y)); //listOfPoint2D.Add(new Point(sceneCorners[3].X + img1.Cols, sceneCorners[3].Y)); //listOfListOfPoint2D.Add(listOfPoint2D); //img3.Polylines(listOfListOfPoint2D, true, Scalar.LimeGreen, 2); Cv2.ImShow(s, img3.Resize(new Size(img3.Rows / 2, img3.Cols / 2))); Cv2.WaitKey(0); Cv2.DestroyWindow(s); //Window.ShowImages(img3.Resize(new Size(img3.Rows / 2, img3.Cols / 2))); //Window.WaitKey(0); //Window.DestroyAllWindows(); } } } } } return(matchRate); }