Fixture DRI Training_Fixture讲解 目录一、坐标转换介绍坐标转换介绍坐标转换示例如何实现坐标转换CogTransform2DLinear 的方法介绍形状坐标转换的方法介绍坐标转换的功能二、转换坐标图像转换坐标脚本转换坐标用脚本转换坐标(MapPoint):三、Mapping工具MappingToolBlock流程介绍MappingToolBlock 注意事项Mapping特征——需要满足的条件坐标转换实现映射功能1、TB_Locate_Form1.搭建2个cogtoolblock 利用标定板进行转换2.导入图片 搭建流程3.Unify坐标4.TB_Loaction5.TB_MappingBackTo_N_Point6.TB_Mapping7.TB_CreateShape8.TB_Terminal_T49.TB_GraphicShow_NoSpec10.界面显示2.TB_ReCheck_To1.TB_UnifyFixture2.TB_Located3.TB_Terminal_T4C4.TB_Mapping5.TB_CreateShape6.TB_ReCheck_To7.TB_GraphicShow_NoSpec8.界面显示label四、DesRobotPose......公式讲解练习图片一、坐标转换介绍坐标转换介绍一个二维(2D)转换数学映射点从一个二维空间到另一个二维空间。在VisionPro中2D转换总是将点从源坐标空间(称为 from space)映射到第二个坐标空间(称为 to space)。例如许多机器视觉任务要求你将图像坐标空间中的点与用户定义空间中的点关联起来。这两个坐标空间通常有不同的测量单位来表示坐标。使用2D转换将点正确地从像素空间映射到用户空间。坐标转换示例已知两个坐标系Cognex中的X在两幅图像中是相同的。坐标转换将一个用户空间中的位置表达式映射到另一个用户空间。我们可以使用转换将任意点从一个用户空间映射到另一个用户空间Q假如将这个转换关系给予FixtureTool那么FixtureTool的TranslationX,TranslationY为多少如何实现坐标转换VisionPro坐标空间树包含一些函数可以让你获得一个转换对象该对象映射坐标空间树中任意两个空间之间的点。从坐标空间树获取转换的最常见方法是调用 VisionPro image对象的GetTransform方法。GetTransform允许提取映射中任意两个空间之间的点的转换。基本的 VisionPro 二维变换实现为 ICogTransform2D 接口。这个接口实现了一般的二维转换。基础变换可以是线性或者非线性变换。要在两个空间之间映射点可以使用此对象的 MapPoint 方法。然而一般来说应用程序不需要关心是线性的还是非线性的。大多数情况下只需使用 ICogTransform2D接口来映射空间之间的点。如果你知道 ICogTransform2D接口下的实际转换是线性的并且希望使用特定于线性转换的功能那么你可以使用 ICogTransform2D 接口的线性转换来获取新的 CogTransform2DLinear 对象。更改这个新转换的属性值并不会更改原始转换的值。如果你想从一个未知的转换类型进行转换声明一个为 CogTransform2DLinear 对象。 CogTransform2DLinear 表示一个特定的2D线性变换。可以修改 CogTransform2DLinear 的属性并且你可以使用它来映射点、向量和坐标空间之间的区域。CogTransform2DLinear 的方法介绍Compose返回一个线性变换类似于矩阵相乘ComposeBase同 Compose 函数类似但是返回值类型与Compose不同Invert返回一个线性变换结果为逆。逆矩阵。InvertBase同 Invert 函数类似但是返回值类型与 Invert 不同MapAngle通过这个转换映射给定的角度并返回结果以弧度为单位MapPoint通过这个变换映射给定的 x,y 点并返回映射的 x,y 坐标形状坐标转换的方法介绍(LineCircleRectangleAffine).Map通过给定的变换映射形状(LineCircleRectangleAffine).MapLinear通过线性变换映射直线圆仿射矩形创建新直线形状转换的返回结果为对应形状而CogTransform2DLinear 返回结果为一个线性的转换关系坐标转换的功能计算偏移量引导贴装定位功能统一图像坐标系统一Robot坐标系映射功能解决贴装后定位特征被遮挡的问题模板跟随获取 runtime 下的 shapemode 或者 region二、转换坐标图像转换坐标通过同一个圆在不同的图像下运行我们就可以拿到同一个点在不同空间下的坐标脚本转换坐标用脚本转换坐标(MapPoint)://清空输出里面的值 foreach(CogToolBlockTerminal ss in mToolBlock.Outputs) { if(ss.ValueType typeof(double)) { ss.Value 999; } } ICogImage image0 mToolBlock.Inputs[Image0].Value as ICogImage; ICogImage image1 mToolBlock.Inputs[Image1].Value as ICogImage; double x (double) mToolBlock.Inputs[X].Value; double y (double) mToolBlock.Inputs[Y].Value; //public ICogTransform2D GetTransform(string toSpaceName,string fromSpaceName) //Returns a tranform that maps points from the From coordinate space to the To space //返回一个 CogTransform2DLinear 类型为2D坐标变换该变换将点从 From坐标空间映射到To空间。 //特殊字符串“.” 被接收为该图像 所选空间名称的别名 CogTransform2DLinear transform (CogTransform2DLinear) image1.GetTransform(image0.SelectedSpaceName, image1.SelectedSpaceName); double mapPointx,mapPointy; transform.MapPoint(x, y, out mapPointx, out mapPointy);//在建立的trans下进行Image1目标点map到image0上 mToolBlock.Outputs[MapPointX].Value mapPointx; mToolBlock.Outputs[MapPointY].Value mapPointy;三、Mapping工具MappingToolBlock流程介绍在视觉项目中经常会遇到复检时由于贴装偏差导致定位特征被覆盖我们无法抓取所需特征来计算复检数据。此时有两种可以实现我们的需求。将定位的结果直接传到复检。这种情况下对机构的要求很高拍照视野不能有任何偏差坐标空间无改变通过map的方式在定位特征的同时选取某些在贴装前后无变化的特征建立Mapping的坐标系将需要的特征从原空间映射 Mapping坐标系下同时将这些Map后的数据给到复检。在复检的时候我们将数据通过同样的Mapping空间转换到原空间此时我们就可以得到那些无法直接抓取的特征。MappingToolBlock 注意事项定位与复检必须位于同一坐标空间下不同相机之间时需要使用 N-Point空间。Mapping 特征的选取定位与复检的MappingToolBlock的特征抓取必须完全保持一致Mapping特征——需要满足的条件特征必须来自于实际物料上特征在定位与复检时无空间位置变动不会受到贴装的影响比如压力MappingFixture 距离所需要map的特征越近越好坐标转换实现映射功能1、TB_Locate_Form1.搭建2个cogtoolblock 利用标定板进行转换2.导入图片 搭建流程3.Unify坐标CogFixtureTool fixture mToolBlock.Tools[CogFixtureTool_Unify] as CogFixtureTool; CogImage8Grey image mToolBlock.Inputs[InputImage].Value as CogImage8Grey; CogTransform2DLinear tranform (CogTransform2DLinear) image.GetTransform(Checkerboard Calibration, #); tranform.Scaling 1; fixture.RunParams.UnfixturedFromFixturedTransform tranform; fixture.Run(); mToolBlock.Outputs[OutputImage].Value fixture.OutputImage;4.TB_Loaction//创造线 和label集合 private CogLine leftLine; private CogLine bottomLine; private CogGraphicCollection dt new CogGraphicCollection(); //清空集合 赋值变量 dt.Clear(); foreach(CogToolBlockTerminal ss in mToolBlock.Outputs) { if(ss.ValueType typeof(double)) { ss.Value 999; } } double x (double)mToolBlock.Inputs[Offset_x].Value; double y (double)mToolBlock.Inputs[Offset_y].Value; CogLine left mToolBlock.Inputs[GetLine_Left].Value as CogLine; CogLine bottom mToolBlock.Inputs[GetLine_Bottom].Value as CogLine; CogIntersectLineLineTool intersect mToolBlock.Tools[CogIntersectLineLineTool1]as CogIntersectLineLineTool; intersect.Run(); CogCreateLineParallelTool parallel_left mToolBlock.Tools[CogCreateLineParallelTool_left]as CogCreateLineParallelTool; CogCreateLineParallelTool parallel_bottom mToolBlock.Tools[CogCreateLineParallelTool_bottom]as CogCreateLineParallelTool; //传递名称 以及平行线需要用的 x点 y点 和以谁为平行线的直线 leftLine Runline(parallel_left, intersect.Xx , intersect.Y, left); bottomLine Runline(parallel_bottom, intersect.X, intersect.Y-y, bottom); #region Create CogIntersectLineLineTool CogIntersectLineLineTool intersectlines new CogIntersectLineLineTool(); intersectlines.InputImage mToolBlock.Inputs[InputImage].Value as ICogImage; intersectlines.LineA leftLine; intersectlines.LineB bottomLine; intersectlines.Run(); #endregion //在相交的点加入圆形图形 dt.Add(createcircle(intersectlines.X,intersectlines.Y,0.04,CogColorConstants.Red)); //赋值 输出 mToolBlock.Outputs[X].Value intersectlines.X; mToolBlock.Outputs[Y].Value intersectlines.Y; mToolBlock.Outputs[Angle].Value CogMisc.RadToDeg(bottomLine.Rotation); //创建 Circle图形 private CogCircle createcircle(double x,double y,double radius,CogColorConstants color) { CogCircle cir new CogCircle(); cir.CenterX x; cir.CenterY y; cir.LineWidthInScreenPixels 4; cir.Radius radius; cir.Color color; return cir; } //创建平行线 返回输出的被创建线 private CogLine Runline(CogCreateLineParallelTool tt, double x,double y,CogLine line) { tt.X x; tt.Y y; tt.Line line; tt.Run(); return tt.GetOutputLine(); } //输出图标 foreach(ICogGraphic s in dt) { mToolBlock.AddGraphicToRunRecord(s, lastRecord, CogIntersectLineLineTool1.InputImage, script); }5.TB_MappingBackTo_N_PointCogImage8Grey image mToolBlock.Inputs[InputImage].Value as CogImage8Grey; //由于这里没有做标定 所以根本转换不了 N-Point 暂时使用# CogTransform2DLinear transform_N_Point (CogTransform2DLinear) image.GetTransform(#, #); transform_N_Point.Scaling 1; double MapPointx,MapPointy; transform_N_Point.MapPoint((double) mToolBlock.Inputs[X].Value, (double) mToolBlock.Inputs[Y].Value,out MapPointx,out MapPointy); double angle transform_N_Point.MapAngle((double) mToolBlock.Inputs[Angle].Value); mToolBlock.Outputs[X].Value MapPointx; mToolBlock.Outputs[Y].Value MapPointy; mToolBlock.Outputs[Angle].Value angle;6.TB_Mapping7.TB_CreateShape8.TB_Terminal_T4//写入output需要添加的类型和参数 Dictionary string,Type terminalList new Dictionarystring, Type () { {TB_Terminal_T4,typeof(CogToolBlockTerminalCollection)} }; //遍历字典 foreach(var item in terminalList) { CogToolBlockTerminal target null; //判断字典key是否包含输出的变量名 foreach(CogToolBlockTerminal t in mToolBlock.Outputs) { if(t.Name item.Key) { target t; break; } } //不包含就创建 if(target null) { target new CogToolBlockTerminal(item.Key, item.Value); mToolBlock.Outputs.Add(target); } //将input里面收入一个集合并赋值 if(item.Value typeof(CogToolBlockTerminalCollection)) { target.Value (CogToolBlockTerminalCollection) CogSerializer.DeepCopyObject(mToolBlock.Inputs); } }9.TB_GraphicShow_NoSpec声明label集合 private CogGraphicCollection dt new CogGraphicCollection(); //清空 dt.Clear(); CogToolBlockTerminal terminal null; int errorCode 1; //判断inputs是否有名字是ErrorCode的 int类型的变量名 foreach(CogToolBlockTerminal input in mToolBlock.Inputs) { if(input.ValueType.Name Int32 input.Name.ToString() ErrorCode) { errorCode (int) mToolBlock.Inputs[input.Name].Value; } } int nRow 0; foreach(CogToolBlockTerminal input in mToolBlock.Inputs) { //单位 遍历每个input是否是double类型 如果是 是否包含angle 如果包含用° 不包含用mm 否则用 string unit input.ValueType.Name Double ? (input.Name.Contains(Angle) ? ° : mm) : ; //是否保存小数 string fmt input.ValueType.Name Double ? f3 : f0; //创建label dt.Add(createlabel((errorCode 1 ? input.Name : double.Parse(input.Value.ToString()).ToString(fmt) unit : input.Name : 999.999 unit), 16, 40, 40 nRow * 40, errorCode 1 ? CogColorConstants.Green : CogColorConstants.Red)); nRow; } //判断outputs 是否有Graphic名字 没有创建 有则赋值 foreach(CogToolBlockTerminal output in mToolBlock.Outputs) { if(output.Name Graphic) { terminal output; break; } } if(terminal null) { mToolBlock.Outputs.Add(terminal new CogToolBlockTerminal(Graphic, typeof(CogGraphicCollection))); } terminal.Value (CogGraphicCollection) dt; //创建label方法 private CogGraphicLabel createlabel(string text, float size, double x, double y, CogColorConstants color) { CogGraphicLabel label new CogGraphicLabel(); label.Font new Font(Arial, size, FontStyle.Bold, GraphicsUnit.Pixel); label.SelectedSpaceName #; label.Color color; // label.BackgroundColor CogColorConstants.White; label.Alignment CogGraphicLabelAlignmentConstants.TopLeft; label.SetXYText(x, y, text); return label; }10.界面显示//创建动态数组 ArrayList arraylist new ArrayList(); //数组清空 获取声明 arraylist.Clear(); CogToolBlock tb_MappingBackTo_N_Point mToolBlock.Tools[TB_MappingBackTo_N_Point]as CogToolBlock; CogToolBlock tb_GraphicShow_NpSpec mToolBlock.Tools[TB_GraphicShow_NoSpec]as CogToolBlock; CogToolBlock tb_Terminal_T4 mToolBlock.Tools[TB_Terminal_T4]as CogToolBlock; //创建变量和类型 Dictionarystring,Type terminallist new Dictionarystring,Type() { {X,typeof(double)}, {Y,typeof(double)}, {Angle,typeof(double)}, {TB_Terminal_T4,typeof(CogToolBlockTerminalCollection)}, {Graphic,typeof(CogGraphicCollection)} }; //遍历字典key 看mToolBlock里面输出是否存在该名字 foreach(var item in terminallist) { CogToolBlockTerminal terminal null; foreach(CogToolBlockTerminal output in mToolBlock.Outputs) { if(output.Name item.Key) { terminal output; break; } } //不存在直接创建对应名字和类型 if(terminal null) { terminal new CogToolBlockTerminal(item.Key, item.Value); mToolBlock.Outputs.Add(terminal); } //把对应类型进行赋默认值 switch(item.Value.Name) { case Double: terminal.Value 999.999; break; case CogToolBlockTerminalCollection: terminal.Value new CogToolBlockTerminalCollection(); break; case CogGraphicCollection: terminal.Value new CogGraphicCollection(); break; } } //等待工具运行完毕后 foreach(ICogTool tool in mToolBlock.Tools) mToolBlock.RunTool(tool, ref message, ref result); //获取它的label集合 添加到动态数组里面 CogGraphicCollection graphic tb_GraphicShow_NpSpec.Outputs[Graphic].Value as CogGraphicCollection; foreach(ICogGraphic grap in graphic) { arraylist.Add(grap); } //output 对应输出 mToolBlock.Outputs[X].Value tb_MappingBackTo_N_Point.Outputs[X].Value; mToolBlock.Outputs[Y].Value tb_MappingBackTo_N_Point.Outputs[Y].Value; mToolBlock.Outputs[Angle].Value tb_MappingBackTo_N_Point.Outputs[Angle].Value; mToolBlock.Outputs[TB_Terminal_T4].Value tb_Terminal_T4.Outputs[TB_Terminal_T4].Value; //显示图像名字圈 ICogRecord hold lastRecord.SubRecords[TB_UnifyFixture.CogFixtureTool_Unify.OutputImage]; lastRecord.SubRecords.Clear(); lastRecord.SubRecords.Add(hold); //显示label数据 foreach(ICogGraphic label in arraylist) { mToolBlock.AddGraphicToRunRecord(label, lastRecord, TB_UnifyFixture.CogFixtureTool_Unify.OutputImage, script); }2.TB_ReCheck_To1.TB_UnifyFixtureCogImage8Grey image mToolBlock.Inputs[InputImage].Value as CogImage8Grey; CogFixtureTool fixture mToolBlock.Tools[CogFixtureTool_Unify]as CogFixtureTool; CogTransform2DLinear tranform (CogTransform2DLinear) image.GetTransform(Checkerboard Calibration, #); tranform.Scaling 1; fixture.RunParams.UnfixturedFromFixturedTransform tranform; fixture.Run(); mToolBlock.Outputs[OutputImage].Value fixture.OutputImage;2.TB_Located3.TB_Terminal_T4C//循环遍历Collection 如果存在名字 直接赋值 如果不存在直接new 赋值 foreach(CogToolBlockTerminal output in (CogToolBlockTerminalCollection) mToolBlock.Inputs[TB_Terminal_T4].Value) { string name output.Name T4C; if (!mToolBlock.Outputs.Contains(name)) mToolBlock.Outputs.Add(new CogToolBlockTerminal(name, output.Value)); mToolBlock.Outputs[name].Value output.Value; }4.TB_Mapping5.TB_CreateShape6.TB_ReCheck_To7.TB_GraphicShow_NoSpec声明label集合 private CogGraphicCollection dt new CogGraphicCollection(); //清空 dt.Clear(); CogToolBlockTerminal terminal null; int errorCode 1; //判断inputs是否有名字是ErrorCode的 int类型的变量名 foreach(CogToolBlockTerminal input in mToolBlock.Inputs) { if(input.ValueType.Name Int32 input.Name.ToString() ErrorCode) { errorCode (int) mToolBlock.Inputs[input.Name].Value; } } int nRow 0; foreach(CogToolBlockTerminal input in mToolBlock.Inputs) { //单位 遍历每个input是否是double类型 如果是 是否包含angle 如果包含用° 不包含用mm 否则用 string unit input.ValueType.Name Double ? (input.Name.Contains(Angle) ? ° : mm) : ; //是否保存小数 string fmt input.ValueType.Name Double ? f3 : f0; //创建label dt.Add(createlabel((errorCode 1 ? input.Name : double.Parse(input.Value.ToString()).ToString(fmt) unit : input.Name : 999.999 unit), 16, 40, 40 nRow * 40, errorCode 1 ? CogColorConstants.Green : CogColorConstants.Red)); nRow; } //判断outputs 是否有Graphic名字 没有创建 有则赋值 foreach(CogToolBlockTerminal output in mToolBlock.Outputs) { if(output.Name Graphic) { terminal output; break; } } if(terminal null) { mToolBlock.Outputs.Add(terminal new CogToolBlockTerminal(Graphic, typeof(CogGraphicCollection))); } terminal.Value (CogGraphicCollection) dt; //创建label方法 private CogGraphicLabel createlabel(string text, float size, double x, double y, CogColorConstants color) { CogGraphicLabel label new CogGraphicLabel(); label.Font new Font(Arial, size, FontStyle.Bold, GraphicsUnit.Pixel); label.SelectedSpaceName #; label.Color color; // label.BackgroundColor CogColorConstants.White; label.Alignment CogGraphicLabelAlignmentConstants.TopLeft; label.SetXYText(x, y, text); return label; }8.界面显示labelArrayList arraylist new ArrayList(); CogToolBlockTerminalCollection dt new CogToolBlockTerminalCollection(); dt.Clear(); arraylist.Clear(); CogToolBlock tb_GraphicShow_nospec mToolBlock.Tools[TB_GraphicShow_NoSpec]as CogToolBlock; CogToolBlock tb_Recheck_Gap mToolBlock.Tools[TB_Recheck_Gap]as CogToolBlock; foreach(ICogTool tool in mToolBlock.Tools) mToolBlock.RunTool(tool, ref message, ref result); dt (CogToolBlockTerminalCollection) CogSerializer.DeepCopyObject(tb_Recheck_Gap.Outputs); foreach(CogToolBlockTerminal output in dt) { string name output.Name; if(!mToolBlock.Outputs.Contains(name)) { mToolBlock.Outputs.Add(new CogToolBlockTerminal(name, output.Value)); } mToolBlock.Outputs[name].Value output.Value; } CogGraphicCollection graphic (CogGraphicCollection) tb_GraphicShow_nospec.Outputs[Graphic].Value as CogGraphicCollection; foreach(CogGraphicLabel label in graphic) { arraylist.Add(label); } ICogRecord hold lastRecord.SubRecords[TB_UnifyFixture.CogFixtureTool_Unify.OutputImage]; lastRecord.SubRecords.Clear(); lastRecord.SubRecords.Add(hold); foreach(ICogGraphic item in arraylist) { mToolBlock.AddGraphicToRunRecord(item, lastRecord, TB_UnifyFixture.CogFixtureTool_Unify.OutputImage, script); }四、DesRobotPose......公式讲解DesRobotPoseDesPartPose.Compose(CurrentPartPose.Invert().Compose(CurRobotPose)) 注释A: Robot SpaceB: N-Point SpaceC: Camera SpaceCurRobotPose: Space B from ACurrentPartPose: Space B from CDesRobotPose: Space B from ADesPartPose: Space B from C求DesRobotPoseSpace B from A已知DesPartPose: Space B from C 只需求出 Space C form ASpace C from A CurrentPartPose.Invert().Compose(CurRobotPose)DesRobotPoseDesPartPose.Compose(Space C from A)练习分别通过图像与脚本两种方法来实现Mapping功能。FixtureA为MappingFixture通过FixtureA来映射 L1L2。图片