//////////////////////////////////////////////////////////////////////////////
        //
        //  IVA_ClampMin_Algorithm
        //
        //  Description:
        //      Measures a distance from the center of the search area towards the
        //      sides of the search area.
        //
        //  Parameters:
        //      image      -  The image that the function uses for distance
        //                    measurement.
        //      roi        -  The coordinate location of the rectangular search area
        //                    of the distance measurement.
        //      direction  -  The direction the function search for edges along the
        //                    search lines.
        //      stepSize   -  step size
        //      options    -  Describes how you want the function to detect edges
        //      firstEdge  -  Upon return, the coordinate location of the first edge
        //                    used to measure the distance.
        //      lastEdge   -  Upon return, the coordinate location of the last edge
        //                    used to measure the distance.
        //
        //  Return Value:
        //      The distance measured between the two parallel hit-lines
        //
        //////////////////////////////////////////////////////////////////////////////
        public static double IVA_ClampMin_Algorithm(VisionImage image, Roi roi, RakeDirection direction, int stepSize, EdgeOptions options, out PointContour firstEdge, out PointContour lastEdge)
        {
            Roi firstSearchRectROI;
            Roi secondSearchRectROI;

            // Separate the rect into two rectangles
            IVA_SplitRotatedRectangle(roi, direction, out firstSearchRectROI, out secondSearchRectROI);

            // Calculate the edge locations for the second half rect
            RakeReport secondReport = Algorithms.Rake(image, secondSearchRectROI, direction, EdgeProcess.First, stepSize, options);

            // Find the opposite direction, then calculate the edge locations for the second half rect
            RakeDirection oppositeDirection = RakeDirection.BottomToTop;

            switch (direction)
            {
            case RakeDirection.LeftToRight:
                oppositeDirection = RakeDirection.RightToLeft;
                break;

            case RakeDirection.RightToLeft:
                oppositeDirection = RakeDirection.LeftToRight;
                break;

            case RakeDirection.TopToBottom:
                oppositeDirection = RakeDirection.BottomToTop;
                break;

            case RakeDirection.BottomToTop:
                oppositeDirection = RakeDirection.TopToBottom;
                break;
            }

            RakeReport firstReport = Algorithms.Rake(image, firstSearchRectROI, oppositeDirection, EdgeProcess.First, stepSize, options);

            // Use the rake report to calculate the minimum distance
            LineContour firstPerpendicularLine;
            LineContour lastPerpendicularLine;
            double      distance = IVA_MeasureMinDistance(firstReport, secondReport, out firstPerpendicularLine, out lastPerpendicularLine, out firstEdge, out lastEdge);

            // Dispose of the ROIs
            secondSearchRectROI.Dispose();
            firstSearchRectROI.Dispose();

            return(distance);
        }
Exemplo n.º 2
0
        private static FindEdgeReport IVA_FindEdge(VisionImage image,
                                                   Roi roi,
                                                   RakeDirection direction,
                                                   EdgeOptions options,
                                                   StraightEdgeOptions straightEdgeOptions,
                                                   IVA_Data ivaData,
                                                   int stepIndex)
        {
            // First, delete all the results of this step (from a previous iteration)
            Functions.IVA_DisposeStepResults(ivaData, stepIndex);

            // Find the Edge
            FindEdgeOptions edgeOptions = new FindEdgeOptions(direction);

            edgeOptions.EdgeOptions         = options;
            edgeOptions.StraightEdgeOptions = straightEdgeOptions;
            FindEdgeReport lineReport = new FindEdgeReport();

            lineReport = Algorithms.FindEdge(image, roi, edgeOptions);

            // If there was at least one line, get data
            if (lineReport.StraightEdges.Count >= 1)
            {
                // Store the results in the data structure.
                ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 1.X Position (Pix.)", lineReport.StraightEdges[0].StraightEdge.Start.X));
                ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 1.Y Position (Pix.)", lineReport.StraightEdges[0].StraightEdge.Start.Y));
                ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 2.X Position (Pix.)", lineReport.StraightEdges[0].StraightEdge.End.X));
                ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 2.Y Position (Pix.)", lineReport.StraightEdges[0].StraightEdge.End.Y));
                if ((image.InfoTypes & InfoTypes.Calibration) != 0)
                {
                    ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 1.X Position (World)", lineReport.StraightEdges[0].CalibratedStraightEdge.Start.X));
                    ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 1.Y Position (World)", lineReport.StraightEdges[0].CalibratedStraightEdge.Start.Y));
                    ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 2.X Position (World)", lineReport.StraightEdges[0].CalibratedStraightEdge.End.X));
                    ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Point 2.Y Position (World)", lineReport.StraightEdges[0].CalibratedStraightEdge.End.Y));
                }

                ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Angle", lineReport.StraightEdges[0].Angle));
                if ((image.InfoTypes & InfoTypes.Calibration) != 0)
                {
                    ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Angle (World)", lineReport.StraightEdges[0].CalibratedAngle));
                }
            }
            return(lineReport);
        }
Exemplo n.º 3
0
        private void FindEdges()
        {
            if (imageViewer1.Roi.Count > 0)
            {
                // Use search direction selected.
                RakeDirection direction = (RakeDirection)Enum.Parse(typeof(RakeDirection), (string)searchDirection.SelectedItem);

                // Fill in the edge options structure from the controls on the form.
                EdgeOptions edgeOptions = new EdgeOptions();
                edgeOptions.ColumnProcessingMode = (ColumnProcessingMode)Enum.Parse(typeof(ColumnProcessingMode), (string)smoothing.SelectedItem);
                edgeOptions.InterpolationType    = (InterpolationMethod)Enum.Parse(typeof(InterpolationMethod), (string)interpolationMethod.SelectedItem);
                edgeOptions.KernelSize           = (uint)kernelSize.Value;
                edgeOptions.MinimumThreshold     = (uint)minimumThreshold.Value;
                edgeOptions.Polarity             = (EdgePolaritySearchMode)Enum.Parse(typeof(EdgePolaritySearchMode), (string)polarity.SelectedItem);
                edgeOptions.Width = (uint)width.Value;

                // Fill in the straight edge options structure from the controls on the form.
                StraightEdgeOptions straightEdgeOptions = new StraightEdgeOptions();
                straightEdgeOptions.AngleRange      = (double)angleRange.Value;
                straightEdgeOptions.AngleTolerance  = (double)angleTolerance.Value;
                straightEdgeOptions.HoughIterations = (uint)houghIterations.Value;
                straightEdgeOptions.ScoreRange.Initialize((double)minimumScore.Value, (double)maximumScore.Value);
                straightEdgeOptions.MinimumCoverage           = (double)minimumCoverage.Value;
                straightEdgeOptions.MinimumSignalToNoiseRatio = (double)minimumSignalToNoiseRatio.Value;
                straightEdgeOptions.NumberOfLines             = (uint)numberOfLines.Value;
                straightEdgeOptions.Orientation = (double)orientation.Value;
                straightEdgeOptions.SearchMode  = (StraightEdgeSearchMode)Enum.Parse(typeof(StraightEdgeSearchMode), (string)searchMode.SelectedItem);
                straightEdgeOptions.StepSize    = (uint)stepSize.Value;

                FindEdgeOptions options = new FindEdgeOptions(direction, true, true, true, true);
                options.EdgeOptions         = edgeOptions;
                options.StraightEdgeOptions = straightEdgeOptions;

                // Clear all overlays from previous run.
                imageViewer1.Image.Overlays.Default.Clear();

                // Run the edge detection.
                FindEdgeReport report = Algorithms.FindEdge(imageViewer1.Image, imageViewer1.Roi, options);
            }
        }
        //////////////////////////////////////////////////////////////////////////////
        //
        //  IVA_SplitRotatedRectangle
        //
        //  Description:
        //      Splits a rotated rectangle into two rotated rectangles
        //
        //  Parameters:
        //      roiToSplit  -  The rectangle roi to split.
        //      direction   -  The direction of the search; the split occurs in the
        //                     perpendicular direction
        //      firstRoi    -  The resulting first rectangle roi.
        //      secondRoi   -  The resulting second rectangle roi.
        //
        //  Return Value:
        //      None
        //
        //////////////////////////////////////////////////////////////////////////////
        public static void IVA_SplitRotatedRectangle(Roi roiToSplit, RakeDirection direction, out Roi firstRoi, out Roi secondRoi)
        {
            RotatedRectangleContour rectToSplit = (RotatedRectangleContour)roiToSplit[0].Shape;
            RotatedRectangleContour firstRect   = new RotatedRectangleContour();
            RotatedRectangleContour secondRect  = new RotatedRectangleContour();
            double xAdjustment;
            double yAdjustment;
            double shiftFactor;

            // Transfer the angle to each rectangle (the direction does not effect the angle).
            firstRect.Angle  = rectToSplit.Angle;
            secondRect.Angle = rectToSplit.Angle;

            // Determine which direction to split the rectangle
            switch (direction)
            {
            case RakeDirection.LeftToRight:
            case RakeDirection.RightToLeft:
                // Split the rectangle down the verticle axis
                firstRect.Width   = rectToSplit.Width / 2;
                firstRect.Height  = rectToSplit.Height;
                secondRect.Width  = rectToSplit.Width / 2;
                secondRect.Height = rectToSplit.Height;

                // Calculate the shift for the left coordinate of the two rects
                shiftFactor = (double)(rectToSplit.Width / 4.0);

                // Set the size of the adjustment
                xAdjustment = (double)(Math.Cos(rectToSplit.Angle * Math.PI / 180) * shiftFactor);
                yAdjustment = (double)(Math.Sin(rectToSplit.Angle * Math.PI / 180) * shiftFactor);

                // Fix the directions for the adjustments
                if (direction == RakeDirection.LeftToRight)
                {
                    firstRect.Center.X  = (int)(rectToSplit.Center.X - xAdjustment + (shiftFactor));
                    firstRect.Center.Y  = (int)(rectToSplit.Center.Y - xAdjustment + (shiftFactor));
                    secondRect.Center.X = (int)(rectToSplit.Center.X + xAdjustment + (shiftFactor));
                    secondRect.Center.Y = (int)(rectToSplit.Center.Y - yAdjustment);
                }
                else
                {
                    firstRect.Center.X  = (int)(rectToSplit.Center.X + xAdjustment + (shiftFactor));
                    firstRect.Center.Y  = (int)(rectToSplit.Center.Y - yAdjustment);
                    secondRect.Center.X = (int)(rectToSplit.Center.X - xAdjustment + (shiftFactor));
                    secondRect.Center.Y = (int)(rectToSplit.Center.Y + yAdjustment);
                }
                break;

            case RakeDirection.TopToBottom:
            case RakeDirection.BottomToTop:
                // Split the rectangle down the horizontal axis
                firstRect.Width   = rectToSplit.Width;
                firstRect.Height  = rectToSplit.Height / 2;
                secondRect.Width  = rectToSplit.Width;
                secondRect.Height = rectToSplit.Height / 2;

                // Calculate the shift for the top coordinate of the two rects
                shiftFactor = (double)(rectToSplit.Height / 4.0);

                // Set the size of the adjustment
                xAdjustment = (double)(Math.Sin(rectToSplit.Angle * Math.PI / 180) * shiftFactor);
                yAdjustment = (double)(Math.Cos(rectToSplit.Angle * Math.PI / 180) * shiftFactor);

                // Fix the directions for the adjustments
                if (direction == RakeDirection.TopToBottom)
                {
                    firstRect.Center.X  = (int)(rectToSplit.Center.X - xAdjustment);
                    firstRect.Center.Y  = (int)(rectToSplit.Center.Y - yAdjustment + (shiftFactor));
                    secondRect.Center.X = (int)(rectToSplit.Center.X + xAdjustment);
                    secondRect.Center.Y = (int)(rectToSplit.Center.Y + yAdjustment + (shiftFactor));
                }
                else
                {
                    firstRect.Center.X  = (int)(rectToSplit.Center.X + xAdjustment);
                    firstRect.Center.Y  = (int)(rectToSplit.Center.Y + yAdjustment + (shiftFactor));
                    secondRect.Center.X = (int)(rectToSplit.Center.X - xAdjustment);
                    secondRect.Center.Y = (int)(rectToSplit.Center.Y - yAdjustment + (shiftFactor));
                }
                break;
            }
            firstRoi  = new Roi(firstRect);
            secondRoi = new Roi(secondRect);
        }
Exemplo n.º 5
0
        private double MeasureMaximumDistance(VisionImage image, RectangleContour searchRectangle, RakeDirection rakeDirection, DrawOptions drawOptions, CoordinateTransform transform)
        {
            // Convert the search rectangle to an Roi.
            Roi roi = searchRectangle.ConvertToRoi();

            // Transform the Roi.
            Algorithms.TransformRoi(roi, transform);

            // Perform a rake operation.
            RakeReport report = Algorithms.Rake(image, roi, rakeDirection, EdgeProcess.FirstAndLast);

            // Find the maximum edge positions and compute the distance.
            Collection <LineContour> perpendicularLines;
            PointContour             closestFirstEdge, closestLastEdge;
            double distance = FindMinMaxPosition(report, out perpendicularLines, out closestFirstEdge, out closestLastEdge);

            // Draw the results.
            if (drawOptions.ShowSearchLines)
            {
                foreach (SearchLineInfo lineInfo in report.SearchLines)
                {
                    image.Overlays.Default.AddLine(lineInfo.Line, Rgb32Value.BlueColor);
                }
            }
            if (drawOptions.ShowSearchArea)
            {
                image.Overlays.Default.AddRoi(roi);
            }
            if (drawOptions.ShowEdgesFound)
            {
                foreach (EdgeInfo edgeInfo in report.FirstEdges)
                {
                    image.Overlays.Default.AddRectangle(new RectangleContour(edgeInfo.Position.X - 1, edgeInfo.Position.Y - 1, 3, 3), Rgb32Value.YellowColor, DrawingMode.PaintValue);
                }
                foreach (EdgeInfo edgeInfo in report.LastEdges)
                {
                    image.Overlays.Default.AddRectangle(new RectangleContour(edgeInfo.Position.X - 1, edgeInfo.Position.Y - 1, 3, 3), Rgb32Value.YellowColor);
                }
            }
            if (drawOptions.ShowResult)
            {
                // Overlay the measurement edge points.
                image.Overlays.Default.AddOval(new OvalContour(closestFirstEdge.X - 2, closestFirstEdge.Y - 2, 5, 5), Rgb32Value.RedColor, DrawingMode.PaintValue);
                image.Overlays.Default.AddOval(new OvalContour(closestLastEdge.X - 2, closestLastEdge.Y - 2, 5, 5), Rgb32Value.RedColor, DrawingMode.PaintValue);
                // Overlay the two lines that point inward from the search area to the clamp position.
                LineContour line1 = new LineContour(FindMidpoint(report.SearchLines[0].Line.Start, report.SearchLines[report.SearchLines.Count - 1].Line.Start),
                                                    FindMidpoint(perpendicularLines[0]));
                image.Overlays.Default.AddLine(line1, Rgb32Value.RedColor);
                DrawArrow(image.Overlays.Default, line1, Rgb32Value.RedColor);

                LineContour line2 = new LineContour(FindMidpoint(report.SearchLines[0].Line.End, report.SearchLines[report.SearchLines.Count - 1].Line.End),
                                                    FindMidpoint(perpendicularLines[1]));
                image.Overlays.Default.AddLine(line2, Rgb32Value.RedColor);
                DrawArrow(image.Overlays.Default, line2, Rgb32Value.RedColor);

                // Overlay the two lines perpendicular to the search lines that correspond to the clamp position.
                image.Overlays.Default.AddLine(perpendicularLines[0], Rgb32Value.RedColor);
                image.Overlays.Default.AddLine(perpendicularLines[1], Rgb32Value.RedColor);
            }
            return(distance);
        }
Exemplo n.º 6
0
 public static extern IntPtr imaqRake2(IntPtr image, ref ROI roi, RakeDirection direction, EdgeProcess process, int stepSize, ref EdgeOptions2 edgeOptions);
Exemplo n.º 7
0
 public static extern IntPtr imaqRake(IntPtr image, ref ROI roi, RakeDirection direction, EdgeProcess process, ref RakeOptions options);