private void OverlayCoordinateSystem(Overlay overlay, CoordinateSystem system) { const int axisLength = 150; // Overlay the origin point. overlay.AddRectangle(new RectangleContour(system.Origin.X - 2, system.Origin.Y - 2, 5, 5), Rgb32Value.RedColor, DrawingMode.PaintValue); // Draw the main axis line. double theta = system.Angle * Math.PI / 180.0; PointContour axisEnd = new PointContour(system.Origin.X + axisLength * Math.Cos(theta), system.Origin.Y - axisLength * Math.Sin(theta)); LineContour axisLine = new LineContour(system.Origin, axisEnd); overlay.AddLine(axisLine, Rgb32Value.RedColor); // Draw an arrow on the end of the line. DrawArrow(overlay, axisLine, Rgb32Value.RedColor); // Overlay the main axis legend. overlay.AddText("X", new PointContour(axisLine.End.X - 10, axisLine.End.Y - 10), Rgb32Value.RedColor, new OverlayTextOptions("Arial", 16)); // Overlay the secondary axis line. if (system.AxisOrientation == AxisOrientation.Indirect) { theta += Math.PI; } axisLine.End.Initialize(system.Origin.X - axisLength * Math.Sin(theta), system.Origin.Y - axisLength * Math.Cos(theta)); overlay.AddLine(axisLine, Rgb32Value.RedColor); // Draw an arrow on the end of the line. DrawArrow(overlay, axisLine, Rgb32Value.RedColor); // Overlay the secondary axis legend. overlay.AddText("Y", new PointContour(axisLine.End.X - 10, axisLine.End.Y - 10), Rgb32Value.RedColor, new OverlayTextOptions("Arial", 16)); }
////////////////////////////////////////////////////////////////////////////// // // IVA_MeasureMinDistance // // Description: // Measures the minimum distance between edges of two rake reports // // Parameters: // firstReport - The first rake report. // secondReport - The second rake report. // firstPerpendicularLine - Upon return, a line perpendicular to the // first edge point. // lastPerpendicularLine - Upon return, a line perpendicular to the // last edge point. // distance - Upon return, the distance between the two // perpendicular lines. // firstEdge - Upon return, the location of the first edge. // lastEdge - Upon return, the location of the last edge. // // Return Value: // The distance // ////////////////////////////////////////////////////////////////////////////// public static double IVA_MeasureMinDistance(RakeReport firstReport, RakeReport secondReport, out LineContour firstPerpendicularLine, out LineContour lastPerpendicularLine, out PointContour firstEdge, out PointContour lastEdge) { // Intialize all returned data to zero firstPerpendicularLine = new LineContour(new PointContour(0, 0), new PointContour(0, 0)); lastPerpendicularLine = new LineContour(new PointContour(0, 0), new PointContour(0, 0)); firstEdge = new PointContour(0, 0); lastEdge = new PointContour(0, 0); double distance = 0; // Only proceed if there was at least one rake line in each rake report if (firstReport.SearchLines.Count > 0 && secondReport.SearchLines.Count > 0) { // Find the edges that are closest to the boundaries of each search area firstEdge = IVA_FindExtremeEdge(firstReport, true); lastEdge = IVA_FindExtremeEdge(secondReport, true); // Find the edge lines by find perpendicular lines from the edges to the rake lines. LineContour tempPerpendicularLine1 = Algorithms.FindPerpendicularLine(firstReport.SearchLines[0].Line, firstEdge); LineContour tempPerpendicularLine2 = Algorithms.FindPerpendicularLine(firstReport.SearchLines[firstReport.SearchLines.Count - 1].Line, firstEdge); firstPerpendicularLine.Start = tempPerpendicularLine1.End; firstPerpendicularLine.End = tempPerpendicularLine2.End; tempPerpendicularLine1 = Algorithms.FindPerpendicularLine(firstReport.SearchLines[0].Line, lastEdge); tempPerpendicularLine2 = Algorithms.FindPerpendicularLine(firstReport.SearchLines[firstReport.SearchLines.Count - 1].Line, lastEdge); lastPerpendicularLine.Start = tempPerpendicularLine1.End; lastPerpendicularLine.End = tempPerpendicularLine2.End; // Compute the distance distance = Algorithms.FindPointDistances(new Collection <PointContour>(new PointContour[] { firstPerpendicularLine.Start, lastPerpendicularLine.Start }))[0]; } return(distance); }
private void btnFindCorner_Click(object sender, EventArgs e) { PointContour cross = new PointContour(); LineContour line1 = new LineContour(); LineContour line2 = new LineContour(); CPKTools.FindCorss(this.cbxCorner.SelectedIndex, this.cpkIni, ref cross, ref line1, ref line2); }
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); } }
public void showCross(double angle, PointContour center, Rgb32Value colcor) { double rate = angle / 180 * Math.PI; LineContour line1 = new LineContour(new PointContour(center.X - 2000 * Math.Sin(rate), center.Y - 2000 * Math.Cos(rate)), new PointContour(center.X + 2000 * Math.Sin(rate), center.Y + 2000 * Math.Cos(rate))); LineContour line2 = new LineContour(new PointContour(center.X + 2000 * Math.Cos(rate), center.Y - 2000 * Math.Sin(rate)), new PointContour(center.X - 2000 * Math.Cos(rate), center.Y + 2000 * Math.Sin(rate))); this.imageSet.Image.Overlays.Default.AddLine(line1, colcor); this.imageSet.Image.Overlays.Default.AddLine(line2, colcor); }
public static PaletteType ProcessImage(VisionImage image) { // Initialize the IVA_Data structure to pass results and coordinate systems. IVA_Data ivaData = new IVA_Data(2, 0); // Creates a new, empty region of interest. Roi roi = new Roi(); // 建一條巡邊線Star(229,40) End(229,300) PointContour vaStartPoint = new PointContour(229, 40); PointContour vaEndPoint = new PointContour(229, 300); LineContour vaLine = new LineContour(vaStartPoint, vaEndPoint); roi.Add(vaLine); // 邊緣偵測;採用簡單邊緣偵測方式 SimpleEdgeOptions vaSimpleEdgeOptions = new SimpleEdgeOptions(); vaSimpleEdgeOptions.Process = EdgeProcess.All; vaSimpleEdgeOptions.Type = LevelType.Absolute; vaSimpleEdgeOptions.Threshold = 128; vaSimpleEdgeOptions.Hysteresis = 2; vaSimpleEdgeOptions.SubPixel = true; simpleEdges = IVA_SimpleEdge(image, roi, vaSimpleEdgeOptions, ivaData, 0); roi.Dispose(); // Caliper // Delete all the results of this step (from a previous iteration) Functions.IVA_DisposeStepResults(ivaData, 1); // Computes the vaDistance between two points. Collection <double> vaDistance = IVA_GetDistance(image, ivaData, 1, 0, 3, 0, 5); caliperDistance = vaDistance[0]; // Dispose the IVA_Data structure. ivaData.Dispose(); //列出相關AOI資料 MessageBox.Show("座標點1" + simpleEdges[2].ToString() + "\r\n" + "座標點2" + simpleEdges[0].ToString() + "\r\n" + "座標點3" + simpleEdges[1].ToString() + "\r\n" + "\r\n" + "間距量測" + caliperDistance.ToString()); //繪出檢測直線(巡邊線) //Graphics g = Graphics.FromImage(FileName) //g.DrawLine(0, 0, 100, 100); // Return the palette type of the final image. return(PaletteType.Gray); }
// Overlay an arrowhead at the end of a line segment. private void DrawArrow(Overlay overlay, LineContour line, Rgb32Value color) { // This code computes the position of the arrow. double dX = line.End.X - line.Start.X; double dY = line.End.Y - line.Start.Y; double lineAngle = Math.Atan2(dY, dX); // The arrow has 3 points. Collection <PointContour> arrowPoints = new Collection <PointContour>(); arrowPoints.Add(line.End); arrowPoints.Add(new PointContour(line.End.X - 6 * Math.Cos(lineAngle - .35), line.End.Y - 6 * Math.Sin(lineAngle - .35))); arrowPoints.Add(new PointContour(line.End.X - 6 * Math.Cos(lineAngle + .35), line.End.Y - 6 * Math.Sin(lineAngle + .35))); overlay.AddPolygon(new PolygonContour(arrowPoints), color, DrawingMode.PaintValue); }
private void FindTransformWithPattern(VisionImage image, VisionImage template, FindTransformMode mode, MatchPatternOptions matchOptions, DrawOptions drawOptions, CoordinateTransform transform) { // Find the pattern in the image. Collection <PatternMatch> matches = Algorithms.MatchPattern(image, template, matchOptions); // If the pattern was found: if (matches.Count > 0) { // The points in the Corners collection are returned like this: // // 0 — 1 // | | // 3 — 2 // // Our main axis will be along the line from point 3 to point 2 and // our secondary axis will be from point 3 to point 0. The origin will // be at point 3. LineContour mainAxis = new LineContour(matches[0].Corners[3], matches[0].Corners[2]); LineContour secondaryAxis = new LineContour(matches[0].Corners[3], matches[0].Corners[0]); // Fill in the coordinate transform with the data obtained by the pattern matching. transform.MeasurementSystem.Origin = matches[0].Corners[3]; transform.MeasurementSystem.Angle = matches[0].Rotation; transform.MeasurementSystem.AxisOrientation = AxisOrientation.Direct; // If this is the first run, fill in the reference system too. if (mode == FindTransformMode.FindReference) { transform.ReferenceSystem.Origin = matches[0].Corners[3]; transform.ReferenceSystem.Angle = matches[0].Rotation; transform.ReferenceSystem.AxisOrientation = AxisOrientation.Direct; } // Draw the results on the image. if (drawOptions.ShowResult) { // Draw the origin. image.Overlays.Default.AddRectangle(new RectangleContour(mainAxis.Start.X - 2, mainAxis.Start.Y - 2, 5, 5), Rgb32Value.RedColor, DrawingMode.DrawValue); // Draw each axis. image.Overlays.Default.AddLine(mainAxis, Rgb32Value.RedColor); DrawArrow(image.Overlays.Default, mainAxis, Rgb32Value.RedColor); image.Overlays.Default.AddLine(secondaryAxis, Rgb32Value.RedColor); DrawArrow(image.Overlays.Default, secondaryAxis, Rgb32Value.RedColor); } } }
private double FindMinMaxPosition(RakeReport report, out Collection <LineContour> perpendicularLines, out PointContour closestFirstEdge, out PointContour closestLastEdge) { double closestFirstEdgeDistance = double.PositiveInfinity; double closestLastEdgeDistance = double.PositiveInfinity; closestFirstEdge = new PointContour(); closestLastEdge = new PointContour(); foreach (SearchLineInfo lineInfo in report.SearchLines) { // If we found an edge on this line, calculate the distances. if (lineInfo.EdgeReport.Edges.Count > 0) { double firstEdgeDistance = DistanceSquared(lineInfo.Line.Start, lineInfo.EdgeReport.Edges[0].Position); if (firstEdgeDistance < closestFirstEdgeDistance) { closestFirstEdgeDistance = firstEdgeDistance; closestFirstEdge = lineInfo.EdgeReport.Edges[0].Position; } double lastEdgeDistance = DistanceSquared(lineInfo.Line.End, lineInfo.EdgeReport.Edges[lineInfo.EdgeReport.Edges.Count - 1].Position); if (lastEdgeDistance < closestLastEdgeDistance) { closestLastEdgeDistance = lastEdgeDistance; closestLastEdge = lineInfo.EdgeReport.Edges[lineInfo.EdgeReport.Edges.Count - 1].Position; } } } perpendicularLines = new Collection <LineContour>(); perpendicularLines.Add(new LineContour()); perpendicularLines.Add(new LineContour()); // Find the two edge lines. LineContour tempLine = Algorithms.FindPerpendicularLine(report.SearchLines[0].Line, closestFirstEdge); perpendicularLines[0].Start = (PointContour)(tempLine.End.Clone()); tempLine = Algorithms.FindPerpendicularLine(report.SearchLines[0].Line, closestLastEdge); perpendicularLines[1].Start = (PointContour)(tempLine.End.Clone()); tempLine = Algorithms.FindPerpendicularLine(report.SearchLines[report.SearchLines.Count - 1].Line, closestFirstEdge); perpendicularLines[0].End = (PointContour)(tempLine.End.Clone()); tempLine = Algorithms.FindPerpendicularLine(report.SearchLines[report.SearchLines.Count - 1].Line, closestLastEdge); perpendicularLines[1].End = (PointContour)(tempLine.End.Clone()); // Compute the distance between them. double distance = Algorithms.FindPointDistances(new Collection <PointContour>(new PointContour[] { perpendicularLines[0].Start, perpendicularLines[1].Start }))[0]; return(distance); }
private static Collection <PointContour> IVA_GetIntersection(VisionImage image, IVA_Data ivaData, int stepIndex, int stepIndex1, int resultIndex1, int stepIndex2, int resultIndex2, int stepIndex3, int resultIndex3, int stepIndex4, int resultIndex4) { // Caliper: Lines Intersection // Computes the intersection point between two lines. PointContour point1 = Functions.IVA_GetPoint(ivaData, stepIndex1, resultIndex1); PointContour point2 = Functions.IVA_GetPoint(ivaData, stepIndex2, resultIndex2); PointContour point3 = Functions.IVA_GetPoint(ivaData, stepIndex3, resultIndex3); PointContour point4 = Functions.IVA_GetPoint(ivaData, stepIndex4, resultIndex4); LineContour line1 = new LineContour(point1, point2); LineContour line2 = new LineContour(point3, point4); Collection <PointContour> intersectionPoint = new Collection <PointContour>(); intersectionPoint.Add(Algorithms.FindIntersectionPoint(line1, line2)); // Store the results in the data structure. ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Intersection Point X Position (Pix.)", intersectionPoint[0].X)); ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Intersection Point X Position (Pix.)", intersectionPoint[0].Y)); // If the image is calibrated, compute the real world position. if ((image.InfoTypes & InfoTypes.Calibration) != 0) { CoordinatesReport realWorldPosition = Algorithms.ConvertPixelToRealWorldCoordinates(image, intersectionPoint); ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Intersection Point X Position (Calibrated)", realWorldPosition.Points[0].X)); ivaData.stepResults[stepIndex].results.Add(new IVA_Result("Intersection Point X Position (Calibrated)", realWorldPosition.Points[0].Y)); intersectionPoint.Add(realWorldPosition.Points[0]); } return(intersectionPoint); }
public static PaletteType ProcessImage(VisionImage image) { // Initialize the IVA_Data structure to pass results and coordinate systems. IVA_Data ivaData = new IVA_Data(2, 0); // Creates a new, empty region of interest. Roi roi = new Roi(); // Creates a new LineContour using the given values. PointContour vaStartPoint = new PointContour(229, 42); PointContour vaEndPoint = new PointContour(229, 298); LineContour vaLine = new LineContour(vaStartPoint, vaEndPoint); roi.Add(vaLine); // Edge Detector - Simple Edge SimpleEdgeOptions vaSimpleEdgeOptions = new SimpleEdgeOptions(); vaSimpleEdgeOptions.Process = EdgeProcess.All; vaSimpleEdgeOptions.Type = LevelType.Absolute; vaSimpleEdgeOptions.Threshold = 128; vaSimpleEdgeOptions.Hysteresis = 2; vaSimpleEdgeOptions.SubPixel = true; simpleEdges = IVA_SimpleEdge(image, roi, vaSimpleEdgeOptions, ivaData, 0); roi.Dispose(); // Caliper // Delete all the results of this step (from a previous iteration) Functions.IVA_DisposeStepResults(ivaData, 1); // Computes the vaDistance between two points. Collection <double> vaDistance = IVA_GetDistance(image, ivaData, 1, 0, 3, 0, 5); caliperDistance = vaDistance[0]; // Dispose the IVA_Data structure. ivaData.Dispose(); // Return the palette type of the final image. return(PaletteType.Gray); }
////////////////////////////////////////////////////////////////////////////// // // IVA_MeasureMaxDistance // // Description: // Measures the maximum distance between edges of a rake report // // Parameters: // reportToProcess - The rake report. Must be generated with // process equal to IMAQ_FIRST_AND_LAST or // IMAQ_ALL. // firstPerpendicularLine - Upon return, a line perpendicular to the // first edge point. // This is an optional parameter. // lastPerpendicularLine - Upon return, a line perpendicular to the // last edge point. // distance - Upon return, the distance between the two // perpendicular lines. // firstEdge - Upon return, the location of the first edge. // lastEdge - Upon return, the location of the last edge. // // Return Value: // TRUE if successful, FALSE if there was an error // ////////////////////////////////////////////////////////////////////////////// public static double IVA_MeasureMaxDistance(RakeReport reportToProcess, out LineContour firstPerpendicularLine, out LineContour lastPerpendicularLine, out PointContour firstEdge, out PointContour lastEdge) { // Intialize all returned data to zero firstPerpendicularLine = new LineContour(new PointContour(0, 0), new PointContour(0, 0)); lastPerpendicularLine = new LineContour(new PointContour(0, 0), new PointContour(0, 0)); double distance = 0; firstEdge = new PointContour(0, 0); lastEdge = new PointContour(0, 0); // Only proceed if there was at least one rake line if (reportToProcess.SearchLines.Count > 0) { // Locate the two extreme edges firstEdge = IVA_FindExtremeEdge(reportToProcess, true); lastEdge = IVA_FindExtremeEdge(reportToProcess, false); // Find the edge lines by find perpendicular lines from the edges to the rake lines. LineContour tempPerpendicularLine1 = Algorithms.FindPerpendicularLine(reportToProcess.SearchLines[0].Line, firstEdge); LineContour tempPerpendicularLine2 = Algorithms.FindPerpendicularLine(reportToProcess.SearchLines[reportToProcess.SearchLines.Count - 1].Line, firstEdge); firstPerpendicularLine.Start = tempPerpendicularLine1.End; firstPerpendicularLine.End = tempPerpendicularLine2.End; tempPerpendicularLine1 = Algorithms.FindPerpendicularLine(reportToProcess.SearchLines[0].Line, lastEdge); tempPerpendicularLine2 = Algorithms.FindPerpendicularLine(reportToProcess.SearchLines[reportToProcess.SearchLines.Count - 1].Line, lastEdge); lastPerpendicularLine.Start = tempPerpendicularLine1.End; lastPerpendicularLine.End = tempPerpendicularLine2.End; // Compute the distance distance = Algorithms.FindPointDistances(new Collection <PointContour>(new PointContour[] { firstPerpendicularLine.Start, lastPerpendicularLine.Start }))[0]; } return(distance); }
public static List <LineContour> CalculateLineContours(this Mesh self, double numberofLines, int dataIndex) { double minOfData = self.GetMinimumBounds(dataIndex); double maxOfData = self.GetMaximumBounds(dataIndex); double interval = Mathf.SliceInterval(numberofLines, minOfData, maxOfData); List <LineContour> finalContours = new List <LineContour>(); for (double contourValue = minOfData + interval / 2; contourValue <= maxOfData; contourValue += interval) { LineContour lineContour = new LineContour(); foreach (Zone zone in self.Zones) { foreach (Element element in zone.Elements) { switch (zone.ElementType) { case ElementType.Tetrahedron: case ElementType.Triangle: foreach (Face zoneFace in zone.Faces) { foreach (uint zoneFaceEdge in zoneFace.Edges) { Edge edge = zone.Edges[zoneFaceEdge]; edge.CalculateContour(zone, contourValue, dataIndex, minOfData, maxOfData, ref lineContour); } } break; case ElementType.IJKBrick: case ElementType.IJKQuad: case ElementType.FEBrick: case ElementType.FEQuad: foreach (Face zoneFace in zone.Faces) { string caseCode = GetCaseCode(dataIndex, contourValue, zone, zoneFace); if (caseCode == "0101") { Point3 firstPoint; Point3 secondPoint; Point3 finalPoint; double alpha = 0; double localMinData = 0; double localMaxData = 0; double average = new[] { zone.Vertices[zoneFace.Vertices[0]].Data[dataIndex], zone.Vertices[zoneFace.Vertices[1]].Data[dataIndex], zone.Vertices[zoneFace.Vertices[2]].Data[dataIndex], zone.Vertices[zoneFace.Vertices[3]].Data[dataIndex] }.Average(); if (average < contourValue) { for (int i = 0; i < 3; i++) { firstPoint = zone.Vertices[i].Position; secondPoint = zone.Vertices[i + 1].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } firstPoint = zone.Vertices[3].Position; secondPoint = zone.Vertices[0].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } else { for (int i = 1; i < 3; i++) { firstPoint = zone.Vertices[i].Position; secondPoint = zone.Vertices[i + 1].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } firstPoint = zone.Vertices[3].Position; secondPoint = zone.Vertices[0].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); firstPoint = zone.Vertices[0].Position; secondPoint = zone.Vertices[1].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } } else if (caseCode == "1010") { Point3 firstPoint; Point3 secondPoint; Point3 finalPoint; double alpha = 0; double localMinData = 0; double localMaxData = 0; double average = new[] { zone.Vertices[zoneFace.Vertices[0]].Data[dataIndex], zone.Vertices[zoneFace.Vertices[1]].Data[dataIndex], zone.Vertices[zoneFace.Vertices[2]].Data[dataIndex], zone.Vertices[zoneFace.Vertices[3]].Data[dataIndex] }.Average(); if (average > contourValue) { for (int i = 0; i < 3; i++) { firstPoint = zone.Vertices[i].Position; secondPoint = zone.Vertices[i + 1].Position; finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); lineContour.AddPoint(finalPoint); } firstPoint = zone.Vertices[3].Position; secondPoint = zone.Vertices[0].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } else { for (int i = 1; i < 3; i++) { firstPoint = zone.Vertices[i].Position; secondPoint = zone.Vertices[i + 1].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } firstPoint = zone.Vertices[3].Position; secondPoint = zone.Vertices[0].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); firstPoint = zone.Vertices[0].Position; secondPoint = zone.Vertices[1].Position; localMinData = Math.Min(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); localMaxData = Math.Max(firstPoint.Data[dataIndex], secondPoint.Data[dataIndex]); alpha = Mathf.Lerp(contourValue, localMinData, localMaxData); finalPoint = Mathf.Lerp(alpha, firstPoint, secondPoint); lineContour.AddPoint(finalPoint); } } else { foreach (uint zoneFaceEdge in zoneFace.Edges) { Edge edge = zone.Edges[zoneFaceEdge]; edge.CalculateContour(zone, contourValue, dataIndex, minOfData, maxOfData, ref lineContour); } } } break; case ElementType.Line: continue; default: throw new ArgumentOutOfRangeException(); } } } finalContours.Add(lineContour); } return(finalContours); }
public static PointContour MatchPattern(VisionImage SourceImage, RectangleContour vaRect, string TemplateFile, int vaNumMatchesRequested, float vaMinMatchScore, float fUpper = 0, float fLower = 0) { PointContour point = new PointContour(); point.X = -10000; point.Y = -10000; // Creates a new, empty region of interest. Roi roi = new Roi(); // Creates a new RotatedRectangleContour using the given values. PointContour vaCenter = new PointContour(vaRect.Left + vaRect.Width / 2, vaRect.Top + vaRect.Height / 2); RotatedRectangleContour vaRotatedRect = new RotatedRectangleContour(vaCenter, vaRect.Width - 50, vaRect.Height - 50, 0); roi.Add(vaRotatedRect); // MatchPattern Grayscale // string TemplateFile = "D:\\t1.png"; MatchingAlgorithm matchAlgorithm = MatchingAlgorithm.MatchGrayValuePyramid; float[] minAngleVals = { fLower, 0 }; float[] maxAngleVals = { fUpper, 0 }; int[] advancedOptionsItems = { 102, 106, 107, 108, 109, 111, 112, 113, 103, 104, 105, 100 }; double[] advancedOptionsValues = { 10, 300, 0, 6, 1, 20, 10, 20, 1, 20, 0, 5 }; int numberAdvOptions = 12; //int vaNumMatchesRequested = 1; //float vaMinMatchScore = 800; using (VisionImage imageTemplate = new VisionImage(ImageType.U8, 7)) { Collection <PatternMatchReport> patternMatchingResults = new Collection <PatternMatchReport>(); // Read the image template. imageTemplate.ReadVisionFile(TemplateFile); // Set the angle range. Collection <RotationAngleRange> angleRange = new Collection <RotationAngleRange>(); for (int i = 0; i < 2; ++i) { angleRange.Add(new RotationAngleRange(minAngleVals[i], maxAngleVals[i])); } // Set the advanced options. Collection <PMMatchAdvancedSetupDataOption> advancedMatchOptions = new Collection <PMMatchAdvancedSetupDataOption>(); for (int i = 0; i < numberAdvOptions; ++i) { advancedMatchOptions.Add(new PMMatchAdvancedSetupDataOption((MatchSetupOption)advancedOptionsItems[i], advancedOptionsValues[i])); } // Searches for areas in the image that match a given pattern. patternMatchingResults = Algorithms.MatchPattern3(SourceImage, imageTemplate, matchAlgorithm, vaNumMatchesRequested, vaMinMatchScore, angleRange, roi, advancedMatchOptions); string sPatterScore = ""; if (patternMatchingResults.Count > 0) { for (int i = 0; i < 1 /* patternMatchingResults.Count*/; ++i) { point.X = patternMatchingResults[i].Position.X; point.Y = patternMatchingResults[i].Position.Y; sPatterScore += " " + patternMatchingResults[i].Score.ToString(); //SourceImage.Overlays.Default.AddRectangle(new RectangleContour(point.X - imageTemplate.Width / 2 - 1, point.Y - imageTemplate.Height / 2 - 1, imageTemplate.Width, imageTemplate.Height), Rgb32Value.GreenColor); LineContour l1 = new LineContour(); l1.Start.X = point.X - (imageTemplate.Width / 2 - 3); l1.Start.Y = point.Y; l1.End.X = point.X + (imageTemplate.Width / 2 - 3); l1.End.Y = point.Y; SourceImage.Overlays.Default.AddLine(l1, Rgb32Value.RedColor); LineContour l2 = new LineContour(); l2.Start.X = point.X; l2.Start.Y = point.Y - (imageTemplate.Height / 2 - 3); l2.End.X = point.X; l2.End.Y = point.Y + (imageTemplate.Height / 2 - 3); SourceImage.Overlays.Default.AddLine(l2, Rgb32Value.RedColor); } } } roi.Dispose(); return(point); }
public static void CalculateContour(this Edge self, Zone zone, double contourValue, int dataIndex, double globalMin, double globalMax, ref LineContour lineContour) { Vertex startVertex = zone.Vertices[self.Start]; Vertex endVertex = zone.Vertices[self.End]; double startData = startVertex.Data[dataIndex]; double endData = endVertex.Data[dataIndex]; if (Mathf.Ranges(contourValue, startData, endData)) { double alpha = Mathf.Lerp(contourValue, startData, endData); Point3 finalPoint = Mathf.Lerp(alpha, startVertex.Position, endVertex.Position); Color contourColor = ColorUtility.CalculateColor(contourValue, globalMin, globalMax); lineContour.AddPoint(finalPoint); lineContour.Color = contourColor; } }
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); }
private PointContour FindMidpoint(LineContour line) { return(FindMidpoint(line.Start, line.End)); }
/// <summary> /// 第几条线 /// </summary> /// <param name="lineNum">线号</param> /// <param name="cpkIni">配置信息</param> /// <param name="cross">输出 角点</param> /// <param name="line1">输出 水平线</param> /// <param name="line2">输出 垂直线</param> /// <returns></returns> public static bool FindCorss(int lineNum, IniFile cpkIni, ref PointContour cross, ref LineContour line1, ref LineContour line2) { string header = string.Format("vision{0}", lineNum); int selectSearchDir = 0; int selectMode = 0; VisionImage image = Form_Main.Instance.imageSet.Image; List <LineContour> lines = new List <LineContour>(); for (int i = 0; i < 2; i++) { selectSearchDir = int.Parse(cpkIni.IniReadValue(header, string.Format("SearchDirection{0}", i))); selectMode = int.Parse(cpkIni.IniReadValue(header, string.Format("EdgePolaritySearchMode{0}", i))); string strRoi = cpkIni.IniReadValue(header, string.Format("LineROI{0}", i)); string[] array = strRoi.Split(','); RectangleContour rect = new RectangleContour(int.Parse(array[0]), int.Parse(array[1]), int.Parse(array[2]), int.Parse(array[3])); PointContour start = new PointContour(); PointContour end = new PointContour(); int rtn = CPKTools.FitLine(image, rect, 40, selectSearchDir, selectMode, ref start, ref end); if (rtn == 0) { lines.Add(new LineContour(start, end)); } else { return(false); } } cross = Algorithms.FindIntersectionPoint(lines[0], lines[1]); line1 = lines[0]; line2 = lines[1]; // show Form_Main.Instance.imageSet.Image.Overlays.Default.AddLine(line1, Rgb32Value.RedColor); Form_Main.Instance.imageSet.Image.Overlays.Default.AddLine(line2, Rgb32Value.RedColor); return(true); }
/// <summary> /// 获得一个位置的CPK数据 /// </summary> /// <param name="point">位置</param> /// <param name="cpkIni">配置信息</param> /// <param name="variable">速度</param> /// <param name="result">CPK 数据</param> /// <returns></returns> public static bool GetCPK(IniFile cpkIni, Variable.VelMode variable, double gain, double offset, int cycle, ref CPK_ResultItem result) { if (result == null) { return(false); } // 移动到目标位 Form_Main.Instance.XYGoPosTillStop(20 * 1000, result.Pos, variable); Thread.Sleep(100); // 获得上相机图像 VisionImage image = Form_Main.Instance.GrabImage2View(Camera.CAM.Top); if (image == null) { return(false); } for (int i = 0; i < cycle; ++i) { image = Form_Main.Instance.GainOffset(image, gain, offset); } // 初定位 寻找模板 try { // NI 视觉检测方法 List <PointContour> crossList = new List <PointContour>(); List <LineContour> lineList = new List <LineContour>(); for (int i = 0; i < 4; ++i) // 找4个角 { PointContour cross = new PointContour(); LineContour line1 = new LineContour(); // 水平线 LineContour line2 = new LineContour(); // 垂直线 bool rtn = false; for (int retry = 0; retry < 3; retry++) { rtn = FindCorss(i, cpkIni, ref cross, ref line1, ref line2); if (rtn) { break; } } if (!rtn) { return(false); } //crossList.Add(cross); lineList.Add(line1); lineList.Add(line2); PointContour center1 = new PointContour((line1.Start.X + line1.End.X) / 2.0, (line1.Start.Y + line1.End.Y) / 2.0); PointContour center2 = new PointContour((line2.Start.X + line2.End.X) / 2.0, (line2.Start.Y + line2.End.Y) / 2.0); crossList.Add(center1); crossList.Add(center2); } if (lineList.Count != 8) { return(false); } LineContour orgHLine = lineList[0]; // 基准水平线 LineContour orgVLine = lineList[1]; // 基准垂直线 //PointContour top = crossList[1]; // 顶点 //PointContour leftBottom = crossList[2]; // 左下角 //PointContour rightTop = crossList[3]; // 右上角 PointContour topV = crossList[3]; PointContour topH = crossList[2]; PointContour leftBottom = crossList[5]; PointContour rightTop = crossList[6]; PointContour cross1 = Algorithms.FindIntersectionPoint(orgVLine, new LineContour(topV, new PointContour(topV.X + 10, topV.Y))); PointContour cross2 = Algorithms.FindIntersectionPoint(orgHLine, new LineContour(topH, new PointContour(topH.X, topH.Y + 10))); PointContour cross3 = Algorithms.FindIntersectionPoint(orgVLine, new LineContour(leftBottom, new PointContour(leftBottom.X + 10, leftBottom.Y))); PointContour cross4 = Algorithms.FindIntersectionPoint(orgHLine, new LineContour(rightTop, new PointContour(rightTop.X, rightTop.Y + 10))); PointF xy = new PointF(); xy.X = (float)Form_Main.Instance.X.Pos; xy.Y = (float)Form_Main.Instance.Y.Pos; PointF tv = Form_Main.Instance.Point2CCDCenter(xy, topV, CAM.Top, 0); PointF th = Form_Main.Instance.Point2CCDCenter(xy, topH, CAM.Top, 0); PointF l = Form_Main.Instance.Point2CCDCenter(xy, leftBottom, CAM.Top, 0); PointF r = Form_Main.Instance.Point2CCDCenter(xy, rightTop, CAM.Top, 0); PointF c1 = Form_Main.Instance.Point2CCDCenter(xy, cross1, CAM.Top, 0); PointF c2 = Form_Main.Instance.Point2CCDCenter(xy, cross2, CAM.Top, 0); PointF c3 = Form_Main.Instance.Point2CCDCenter(xy, cross3, CAM.Top, 0); PointF c4 = Form_Main.Instance.Point2CCDCenter(xy, cross4, CAM.Top, 0); result.X1 = Math.Abs(tv.X - c1.X); result.Y1 = Math.Abs(th.Y - c2.Y); result.X2 = Math.Abs(l.X - c3.X); result.Y2 = Math.Abs(r.Y - c4.Y); Form_Main.Instance.imageSet.Image.Overlays.Default.AddLine(new LineContour(cross1, topV)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddLine(new LineContour(cross2, topH)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddLine(new LineContour(cross3, leftBottom)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddLine(new LineContour(cross4, rightTop)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddText("X1: " + result.X1.ToString(), topV, Rgb32Value.BlueColor, new OverlayTextOptions("Consolas", 24)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddText("Y1: " + result.Y1.ToString(), topH, Rgb32Value.BlueColor, new OverlayTextOptions("Consolas", 24)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddText("X2: " + result.X2.ToString(), leftBottom, Rgb32Value.BlueColor, new OverlayTextOptions("Consolas", 24)); Form_Main.Instance.imageSet.Image.Overlays.Default.AddText("Y2: " + result.Y2.ToString(), rightTop, Rgb32Value.BlueColor, new OverlayTextOptions("Consolas", 24)); } catch { } return(false); }
public void LineTo(float x, float y) { var newLine = new LineContour(x, y); Contours.Add(newLine); }
public void LineTo(double x, double y) { var newLine = new LineContour(x, y); Contours.Add(newLine); }