////////////////////////////////////////////////////////////////////////////// // // 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); }
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); }
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); }
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); }
public static extern IntPtr imaqRake2(IntPtr image, ref ROI roi, RakeDirection direction, EdgeProcess process, int stepSize, ref EdgeOptions2 edgeOptions);
public static extern IntPtr imaqRake(IntPtr image, ref ROI roi, RakeDirection direction, EdgeProcess process, ref RakeOptions options);