コード例 #1
0
        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);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        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());
        }
コード例 #5
0
        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);
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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;
        }
コード例 #11
0
        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);
            }
        }