private void DisplayDistance(PointContour point1, PointContour point2) { Collection <PointContour> points = new Collection <PointContour>(new PointContour[] { point1, point2 }); double distance = Algorithms.FindPointDistances(points)[0]; OverlayTextOptions textOptions = new OverlayTextOptions(); textOptions.FontSize = 14; textOptions.BackgroundColor = Rgb32Value.WhiteColor; textOptions.HorizontalAlignment = HorizontalTextAlignment.Center; imageViewer1.Image.Overlays.Default.AddText(String.Format("{0:0.00}", distance), new PointContour((point1.X + point2.X) / 2, (point1.Y + point2.Y) / 2), Rgb32Value.BlackColor, textOptions); }
private void MeasureDistortionTarget(VisionImage image, Collection <PointContour> pixelPoints, Collection <PointContour> realWorldPoints, Direction d) { OverlayTextOptions overlayOptions = new OverlayTextOptions("Arial", 16); overlayOptions.TextDecoration.Bold = true; if (d == Direction.Horizontal) { overlayOptions.HorizontalAlignment = HorizontalTextAlignment.Right; overlayOptions.VerticalAlignment = VerticalTextAlignment.Baseline; } else { overlayOptions.HorizontalAlignment = HorizontalTextAlignment.Center; overlayOptions.VerticalAlignment = VerticalTextAlignment.Bottom; } for (int i = 0; i < 3; ++i) { // Measure the real-world distance. Collection <PointContour> realWorldDistancePoints = new Collection <PointContour>(); realWorldDistancePoints.Add(realWorldPoints[2 * i]); realWorldDistancePoints.Add(realWorldPoints[9 - 2 * i]); double realWorldDistance = Algorithms.FindPointDistances(realWorldDistancePoints)[0]; // Find the line to overlay. LineContour line = new LineContour(); line.Start = pixelPoints[2 * i]; line.End = pixelPoints[9 - 2 * i]; if (d == Direction.Horizontal) { // Measurement is horizontal, so arrows stack vertically. line.Start.Y += (2 - i) * 30; line.End.Y += (2 - i) * 30; } else { // Measurement is vertical, so arrows stack horizontally. line.Start.X += (2 - i) * 30; line.End.X += (2 - i) * 30; } // Draw the line with arrows. image.Overlays.Default.AddLine(line, Rgb32Value.RedColor); DrawArrow(image.Overlays.Default, line, Rgb32Value.RedColor); // Flip the start and end to draw an arrow at the beginning. PointContour tempStart = line.Start; line.Start = line.End; line.End = tempStart; DrawArrow(image.Overlays.Default, line, Rgb32Value.RedColor); // Find the origin of the text to overlay. image.Overlays.Default.AddText(String.Format("{0:0.00}", realWorldDistance), tempStart, Rgb32Value.RedColor, overlayOptions); } }
/// <summary> /// 计算结果 /// </summary> /// <returns></returns> public VisionResult Detect(VisionImage image, Shape InitRoi = null, int textOffset = 0) { VisionResult rtn = new VisionResult(); rtn.State = VisionResultState.WaitCal; Dictionary <string, VisionResult> Result = new Dictionary <string, VisionResult>(); foreach (Detect func in this.Detects) { var result = func.Detected(image, Result, this, InitRoi); Result.Add(func.UnitID, result); rtn.VisionDesr.AddRange(result.VisionDesr); if (result.State == VisionResultState.NG) { rtn.State = VisionResultState.NG; return(rtn); } } OverlayTextOptions TEXT = new OverlayTextOptions(); TEXT.FontName = "Consolas"; TEXT.FontSize = 128; if (!string.IsNullOrEmpty(this.ResultX) && Result.ContainsKey(this.ResultX)) { rtn.Point = new PointContour(); rtn.Point.X = Result[this.ResultX].Point.X; image.Overlays.Default.AddText($"X:{rtn.Point.X:N2}", new PointContour(50 + textOffset, 100), Rgb32Value.BlueColor, TEXT); } if (!string.IsNullOrEmpty(this.ResultX) && Result.ContainsKey(this.ResultY)) { rtn.Point.Y = Result[this.ResultY].Point.Y; image.Overlays.Default.AddText($"Y:{rtn.Point.Y:N2}", new PointContour(50 + textOffset, 180), Rgb32Value.BlueColor, TEXT); } if (!string.IsNullOrEmpty(this.Angle) && Result.ContainsKey(this.Angle)) { rtn.Angle = Result[this.Angle].Angle; image.Overlays.Default.AddText($"Angle:{rtn.Angle:N2}", new PointContour(50 + textOffset, 260), Rgb32Value.BlueColor, TEXT); } if (!string.IsNullOrEmpty(this.Area) && Result.ContainsKey(this.Area)) { rtn.Area = Result[this.ResultX].Area; image.Overlays.Default.AddText($"Area:{rtn.Area:N2}", new PointContour(50 + textOffset, 340), Rgb32Value.BlueColor, TEXT); } rtn.State = VisionResultState.OK; return(rtn); }
private void OverlayTextOnImage(VisionImage image, DateTime time, int secondsToNextImage) { OverlayTextOptions textOptions = new OverlayTextOptions("Arial", 20); textOptions.TextDecoration.Bold = true; // Clear any overlays. image.Overlays.Default.Clear(); // Overlay text onto the image. This will not change the image pixels. image.Overlays.Default.AddText(String.Format("{0}\nNext image in {1}s.", time.ToLongTimeString(), secondsToNextImage.ToString()), textOrigin, new Rgb32Value(colorDialog1.Color), textOptions); // Display the overlaid text. overlaidTextBox.Text = String.Format("{0}\r\nNext image in {1}s.", time.ToLongTimeString(), secondsToNextImage.ToString()); }
private void MeasureObjectsAreas() { // Compute the full particle report. Collection <ParticleReport> reports = Algorithms.ParticleReport(imageViewer1.Image); // Overlay the area of each particle. OverlayTextOptions options = new OverlayTextOptions(); options.HorizontalAlignment = HorizontalTextAlignment.Center; options.VerticalAlignment = VerticalTextAlignment.Bottom; options.FontSize = 16; foreach (ParticleReport report in reports) { imageViewer1.Image.Overlays.Default.AddText(String.Format("{0}", report.Area), new PointContour(report.CenterOfMass.X, report.BoundingRect.Top), Rgb32Value.GreenColor, options); } }
private void DrawFailedLED(Overlay overlay, Roi roi) { RectangleContour rect = roi.GetBoundingRectangle(); rect.Left = rect.Left - rect.Width / 1.25; rect.Top = rect.Top - rect.Height / 1.25; rect.Width = rect.Width * 2.5; rect.Height = rect.Height * 2.5; // Overlay on the image to indicate which LED failed. overlay.AddRectangle(rect, Rgb32Value.RedColor, DrawingMode.DrawValue); OverlayTextOptions textOptions = new OverlayTextOptions("Arial", 20, HorizontalTextAlignment.Center); textOptions.VerticalAlignment = VerticalTextAlignment.Baseline; textOptions.TextDecoration.Bold = true; overlay.AddText("Fail", new PointContour(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2), Rgb32Value.RedColor, textOptions); }
private void runButton_Click(object sender, EventArgs e) { // Initialize the pattern matching options. matchPatternRoi = new Roi(new Shape[] { new RotatedRectangleContour(new PointContour(210, 220), 130, 110, 0) }); matchPatternOptions = new MatchPatternOptions(MatchMode.RotationInvariant, 1); matchPatternOptions.MinimumMatchScore = 650; matchPatternOptions.RotationAngleRanges.Add(new Range(-40, 40)); matchPatternOptions.SubpixelAccuracy = true; // Initialize text options. overlayTextOptions = new OverlayTextOptions("Arial Black", 36); // Update buttons. runButton.Enabled = false; // Enable the timer. timer1.Enabled = true; timer1_Tick(timer1, EventArgs.Empty); }
private void measureButton_Click(object sender, EventArgs e) { // Threshold the image. Algorithms.Threshold(imageViewer1.Image, imageViewer1.Image); // Change the viewer's palette to Binary to display the image. imageViewer1.Palette.Type = NationalInstruments.Vision.WindowsForms.PaletteType.Binary; // Compute the basic particle statistics to get the center of mass and orientation. Collection <ParticleReport> reports = Algorithms.ParticleReport(imageViewer1.Image); OverlayTextOptions textOptions = new OverlayTextOptions(); textOptions.HorizontalAlignment = HorizontalTextAlignment.Center; textOptions.VerticalAlignment = VerticalTextAlignment.Baseline; textOptions.FontSize = 16; foreach (ParticleReport report in reports) { imageViewer1.Image.Overlays.Default.AddText(String.Format("Angle = {0:###.#}", report.Orientation), report.CenterOfMass, Rgb32Value.WhiteColor); } }
private void timer1_Tick(object sender, EventArgs e) { double[] classCount = new double[8]; OverlayTextOptions textOptions = new OverlayTextOptions("Arial", 14); textOptions.HorizontalAlignment = HorizontalTextAlignment.Center; // Get the next image GetNextImage(imageViewer1.Image); // Process the image VisionImage binaryImage = new VisionImage(); Algorithms.Threshold(imageViewer1.Image, binaryImage, new Range(0, 200)); Algorithms.RejectBorder(binaryImage, binaryImage); Collection <ParticleReport> reports = Algorithms.ParticleReport(binaryImage); foreach (ParticleReport report in reports) { RectangleContour contour = report.BoundingRect; contour.Left -= 10; contour.Top -= 10; contour.Height += 20; contour.Width += 20; // Classify the part ClassifierReport classifierReport = classifier.Classify(binaryImage, new Roi(new Shape[] { contour })); // Display the result if (classifierReport.ClassificationScore > 500) { textOptions.BackgroundColor = Rgb32Value.TransparentColor; int classIndex = 0; Rgb32Value textColor = Rgb32Value.BlackColor; switch (classifierReport.BestClassName) { case "Motor": textColor = Rgb32Value.WhiteColor; classIndex = 0; break; case "Bolt": textColor = new Rgb32Value(Color.Cyan); classIndex = 1; break; case "Screw": textColor = Rgb32Value.RedColor; classIndex = 2; break; case "Gear": textColor = Rgb32Value.BlackColor; classIndex = 3; break; case "Washer": textColor = new Rgb32Value(Color.Magenta); classIndex = 4; break; case "Worm Gear": textColor = Rgb32Value.GreenColor; classIndex = 5; break; case "Bracket": textColor = new Rgb32Value(0x80, 0x80, 0); classIndex = 6; break; } classCount[classIndex]++; imageViewer1.Image.Overlays.Default.AddText(classifierReport.BestClassName, report.CenterOfMass, textColor, textOptions); } else { textOptions.BackgroundColor = Rgb32Value.BlackColor; imageViewer1.Image.Overlays.Default.AddText("Unknown!", report.CenterOfMass, Rgb32Value.RedColor, textOptions); } } classificationGraph1.PlotClassifier(classCount); }
private void measurePartsButton_Click(object sender, EventArgs e) { // Start timing. System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); // Apply the calibration to the parts image and correct it. Algorithms.CopyCalibrationInformation(calibrationTemplate, uncorrectedImage); Algorithms.CorrectCalibratedImage(uncorrectedImage, partImage, new PixelValue(0), InterpolationMethod.Bilinear); // Process the image to segment the parts from the background. Algorithms.Threshold(partImage, processedPartImage, new Range(0, 150)); Algorithms.RejectBorder(processedPartImage, processedPartImage); Algorithms.FillHoles(processedPartImage, processedPartImage); Algorithms.ConvexHull(processedPartImage, processedPartImage); // Perform particle analysis. Collection <ParticleReport> particleReports = Algorithms.ParticleReport(processedPartImage, Connectivity.Connectivity8, false); double[,] areas = Algorithms.ParticleMeasurements(processedPartImage, new Collection <MeasurementType>(new MeasurementType[] { MeasurementType.Area }), Connectivity.Connectivity8, ParticleMeasurementsCalibrationMode.Calibrated).CalibratedMeasurements; // Stop timing and overlay results. stopwatch.Stop(); OverlayTextOptions overlayOptions = new OverlayTextOptions("Arial", 18, HorizontalTextAlignment.Center); overlayOptions.TextDecoration.Bold = true; overlayOptions.VerticalAlignment = VerticalTextAlignment.Baseline; for (int i = 0; i < particleReports.Count; ++i) { partImage.Overlays.Default.AddText(String.Format("{0:0.00} cm^2", areas[i, 0]), particleReports[i].CenterOfMass, Rgb32Value.GreenColor, overlayOptions); } wholeImageTime.Text = String.Format("{0:0}", stopwatch.ElapsedMilliseconds); imageViewer1.Attach(partImage); imageViewer2.Attach(uncorrectedImage); stopwatch.Reset(); // Start timing. stopwatch.Start(); // Apply the calibration to the parts image. Algorithms.CopyCalibrationInformation(calibrationTemplate, uncorrectedImage); // Process the image to segment the parts from the background. Algorithms.Threshold(uncorrectedImage, processedPartImage, new Range(0, 150)); Algorithms.RejectBorder(processedPartImage, processedPartImage); Algorithms.FillHoles(processedPartImage, processedPartImage); Algorithms.ConvexHull(processedPartImage, processedPartImage); // Perform particle analysis. particleReports = Algorithms.ParticleReport(processedPartImage, Connectivity.Connectivity8, false); areas = Algorithms.ParticleMeasurements(processedPartImage, new Collection <MeasurementType>(new MeasurementType[] { MeasurementType.Area }), Connectivity.Connectivity8, ParticleMeasurementsCalibrationMode.Calibrated).CalibratedMeasurements; // Stop timing and overlay results. stopwatch.Stop(); for (int i = 0; i < particleReports.Count; ++i) { uncorrectedImage.Overlays.Default.AddText(String.Format("{0:0.00} cm^2", areas[i, 0]), particleReports[i].CenterOfMass, Rgb32Value.GreenColor, overlayOptions); } coinsImageTime.Text = String.Format("{0:0}", stopwatch.ElapsedMilliseconds); // Update command buttons. measurePartsButton.Enabled = false; }
private void timer1_Tick(object sender, EventArgs e) { // Get the next image VisionImage image = GetNextImage(); // Find peaks along 3 predetermined rows of the image. Store the points found // along each line in the pointsForRow array. Collection <PointContour>[] pointsForRow = new Collection <PointContour> [3]; int[] yPositions = new int[] { 145, 200, 300 }; for (int i = 0; i < 3; ++i) { int yPosition = yPositions[i]; byte[] rowPixels = image.GetLinePixels(new LineContour(new PointContour(0, yPosition), new PointContour(image.Width - 1, yPosition))).U8; double[] rowPixelsDouble = Array.ConvertAll <byte, double>(rowPixels, delegate(byte b) { return((double)b); }); Collection <PeakValleyReportItem> peakValleyReport = Algorithms.DetectPeaksOrValleys(rowPixelsDouble, PeakOrValley.Peaks, new DetectPeaksOrValleysOptions(19, 70)); pointsForRow[i] = new Collection <PointContour>(); foreach (PeakValleyReportItem item in peakValleyReport) { pointsForRow[i].Add(new PointContour(item.Location, yPosition)); } } // Find the top and bottom points nearest each point found along the middle line. double[] angles = new double[12]; Collection <PointContour> points = new Collection <PointContour>(); points.Add(new PointContour()); points.Add(new PointContour()); bool allPassed = true; Collection <PointContour>[] pinPoints = new Collection <PointContour> [12]; for (int i = 0; i < pointsForRow[0].Count; ++i) { // pinPoints[i][j] denotes the jth point of the ith pin. pinPoints[i] = new Collection <PointContour>(); pinPoints[i].Add(new PointContour()); pinPoints[i].Add(pointsForRow[1][i]); pinPoints[i].Add(new PointContour()); points[0] = pinPoints[i][1]; // For the top and bottom rows... foreach (int j in new int[2] { 0, 2 }) { int minIndex = -1; double minDistance = double.PositiveInfinity; // For each point along that row... for (int k = 0; k < pointsForRow[j].Count; ++k) { // Compute the distance between this point and the current point in the center row. points[1] = pointsForRow[j][k]; double distance = Algorithms.FindPointDistances(points)[0]; // The point with the smallest distance should be associated with the pin // corresponding to the center point. if (distance < minDistance) { minDistance = distance; minIndex = k; } } // Save the point. pinPoints[i][j] = pointsForRow[j][minIndex]; } // Use the information found to determine if the angle is within range. points[0] = pinPoints[i][0]; points[1] = pinPoints[i][2]; angles[i] = Algorithms.GetAngles(points, pinPoints[i][1])[0]; // If the angle is within [180-tolerance, 180+tolerance], the part // passes inspection. GetLed(i).Value = (angles[i] >= (180 - (double)tolerance.Value) && angles[i] <= (180 + (double)tolerance.Value)); allPassed &= GetLed(i).Value; } // Because not all images have 12 pins, set any remaining indicators to pass. for (int i = pointsForRow[0].Count; i < 12; ++i) { GetLed(i).Value = true; } // Display results partOK.Value = allPassed; numberOfPartsInspected++; partsInspected.Text = numberOfPartsInspected.ToString(); if (imageResultsMode.Checked) { // Display the overlay OverlayTextOptions textOptions = new OverlayTextOptions(); textOptions.HorizontalAlignment = HorizontalTextAlignment.Center; textOptions.FontSize = 14; // Overlay the pin positions on the image for (int i = 0; i < pointsForRow[0].Count; ++i) { if (GetLed(i).Value) { // Part passed // Draw a circle at each point on the pin. for (int j = 0; j < 3; ++j) { image.Overlays.Default.AddOval(new OvalContour(pinPoints[i][j].X - 2, pinPoints[i][j].Y - 2, 4, 4), Rgb32Value.GreenColor, DrawingMode.PaintValue); } // Connect the points image.Overlays.Default.AddPolyline(new PolylineContour(pinPoints[i]), Rgb32Value.GreenColor); image.Overlays.Default.AddText(String.Format("{0:0.0}", angles[i]), new PointContour(pinPoints[i][1].X, 100), Rgb32Value.GreenColor, textOptions); } else { // Part failed // Overlay a rectangle with an X inside RectangleContour rect = new RectangleContour(pinPoints[i][1].X - 20, 120, 40, 210); image.Overlays.Default.AddRectangle(rect, Rgb32Value.RedColor, DrawingMode.DrawValue); image.Overlays.Default.AddLine(new LineContour(new PointContour(rect.Left, rect.Top), new PointContour(rect.Left + rect.Width, rect.Top + rect.Height)), Rgb32Value.RedColor); image.Overlays.Default.AddLine(new LineContour(new PointContour(rect.Left + rect.Width, rect.Top), new PointContour(rect.Left, rect.Top + rect.Height)), Rgb32Value.RedColor); } } } if (imageResultsMode.Checked || imageMode.Checked) { // Display the image Algorithms.Copy(image, imageViewer1.Image); } }