分享:一种求角平分线方法—VisionPro脚本实现 点击:910 | 回复:0



lyfforever

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:3帖 | 4回
  • 年度积分:0
  • 历史总积分:14
  • 注册:2006年8月16日
发表于:2022-08-25 15:08:33
楼主

1. 角平分线定义:

  1. 从一个角的顶点引出一条射线(线在角内),把这个角分成两个完全相同的角,这条射线叫做这个角的角平分线(bisectorof angle)。
  2. 角平分线是在角的型内及形上,到角两边距离相等的点的轨迹。(具体如附图)

添加图片注释,不超过 140 字(可选)

2. 在VisionPro中创建角平分线

  1. VisionPro中软件中没有提供封装好的角平分线工具,下面我 们介绍一种方法通过Vpro脚本实现角平分线的创建。

添加图片注释,不超过 140 字(可选)

         2. 求角平分线的脚本Angular bisector

添加图片注释,不超过 140 字(可选)

3. 角平分线计算的原理和过程:

添加图片注释,不超过 140 字(可选)

  1. 输入图像和直线A,B
  2. 把直线A,B的坐标空间映射到输入图像Image中,创建两条新 lineAMapped和lineBMapped
  3. 获取直线lineAMapped和直线lineAMapped上的参考点A(xA,yA,rA)和B(xB,yB,rB),这里的角度为指向相对于坐标系X轴的角度。
  4. 求取两条直线之间的角度β
  5. 计算两条直线平分线的角度MidAngle,这里需要判断是否为锐角
  6. 过两条直线上参考点的中心点建立一条垂直与角平分线的直线Cutline
  7. 分别求Cutline与lineAMapped的交点,以及Cutline与lineBMapped的交点,两个交点的中点设置为角平分线的参考点。
  8. 输出角平分线和对应角度(将弧度转换为角度)

  1. 运行效果如图

添加图片注释,不超过 140 字(可选)

4. VisionPro脚本参考代码:

public override bool GroupRun(ref string message, ref CogToolResultConstants result)
  {
    // To let the execution stop in this script when a debugger is attached, uncomment the following lines.
    // #if DEBUG
    // if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
    // #endif
    ///定义输入图像和初始化输出信号
    CogImage8Grey image = mToolBlock.Inputs["Image"].Value as CogImage8Grey;
    mToolBlock.Outputs["MidLine"].Value = null;
    mToolBlock.Outputs["MidLineAngle"].Value = 999.999;

    ///定义lineA和lineB两条直线,并把输入的直线赋值给图像
    // Run each tool using the RunTool function
    foreach(ICogTool tool in mToolBlock.Tools)
      mToolBlock.RunTool(tool, ref message, ref result);
      CogLine lineA = mToolBlock.Inputs["LineA"].Value as CogLine;
      CogLine lineB = mToolBlock.Inputs["LineB"].Value as CogLine;

    ///把lineA和lineB的坐标空间映射到输入图像的坐标空间中,创建lineAMapped和lineBMapped两条新的直线
    CogLine lineAMapped = lineA.Map(image.GetTransform(image.SelectedSpaceName, lineA.SelectedSpaceName), CogCopyShapeConstants.All) as CogLine;
    CogLine lineBMapped = lineB.Map(image.GetTransform(image.SelectedSpaceName, lineB.SelectedSpaceName), CogCopyShapeConstants.All) as CogLine;
    ///获取两条线的参考点 Line Reference Point(XY和角度R,该角度为相对于X轴的角度,以弧度表示)
    double xA, yA, rA, xB, yB, rB;
    lineAMapped.GetXYRotation(out xA, out yA, out rA);                              //获得lineAMapped参考点
    lineBMapped.GetXYRotation(out xB, out yB, out rB);                              //获得lineBMapped参考点

    /// 计算lineAMapped和lineBMapped 之间的角度
    double dxA = Math.Cos(rA);
    double dyA = Math.Sin(rA);
    double dxB = Math.Cos(rB);
    double dyB = Math.Sin(rB);
    double dot= dxA * dxB + dyA * dyB;                                               // dot为向量A和向量B的点积
    dot = Math.Min(1.0, Math.Max(-1.0, dot));                                        //设定dot为单位向量-1.0 - 1.0之间的值
    double angSpan = Math.Acos(dot);                                                 //获得两条直线之间的夹角

    ///通过判定找到角平分线的夹角MidAngle
    double midAngle0 = rA + angSpan / 2.0;                                           //LineA上方角度
    double midAngle1 = rA - angSpan / 2.0;                                           //LineA下方角度
    double x0, y0, x1, y1;
    x0 = Math.Cos(midAngle0);                                                        //LineA上方的参考点XY
    y0 = Math.Sin(midAngle0);
    x1 = Math.Cos(midAngle1);                                                        //LineA下方的参考点XY
    y1 = Math.Sin(midAngle1);
    double dot0 = x0 * dxB + y0 * dyB;                                               //dot0 为上方参考点向量与LineB向量的点积
    double dot1 = x1 * dxB + y1 * dyB;                                               //dot1 为下方参考点向量与LineB向量的点积
    double midAngle = midAngle0;
    if (dot0 < dot1)                                                                 //dotx 值越说明与LineB的夹角(Acos(dotx))越小,最终输出LineA和LineB两线之间的夹角
      midAngle = midAngle1;


    /// 计算角平分线的交点
    CogLine cutLine = new CogLine();  
    cutLine.SelectedSpaceName = image.SelectedSpaceName;
    cutLine.SetXYRotation((xA + xB) / 2.0, (yA + yB) / 2.0, midAngle+Math.PI/2.0);  //创建一条角平分线的垂线

    CogIntersectLineLineTool lineLineIntersectA = new CogIntersectLineLineTool();   //计算LineA和垂线CutLine的交点
    lineLineIntersectA.InputImage = image;
    lineLineIntersectA.LineA = cutLine;
    lineLineIntersectA.LineB = lineAMapped;
    lineLineIntersectA.Run();

    CogIntersectLineLineTool lineLineIntersectB = new CogIntersectLineLineTool();   //计算LineB和垂线CutLine的交点
    lineLineIntersectB.InputImage = image;
    lineLineIntersectB.LineA = cutLine;
    lineLineIntersectB.LineB = lineBMapped;
    lineLineIntersectB.Run();

    if (lineLineIntersectA.Intersects && lineLineIntersectB.Intersects)             //如果LineA和LineB不平行,说明两线相交,则输出交点
    {
      double centerX= (lineLineIntersectB.X + lineLineIntersectA.X) / 2.0; 
      double centerY= (lineLineIntersectB.Y + lineLineIntersectA.Y) / 2.0; 
      CogLine midLine = new CogLine();
      midLine.SelectedSpaceName = image.SelectedSpaceName;
      midLine.SetXYRotation(centerX, centerY, midAngle);
      mToolBlock.Outputs["MidLine"].Value = midLine;                                //输出角平分线(锐角)
      mToolBlock.Outputs["MidLineAngle"].Value = CogMisc.RadToDeg( midAngle);       //输出角平分线的角度(相对X轴的弧度)
    }    
    return false;
  }

5. 更多内容

V+视觉编程软件下载以及更多视觉资源内容请搜索”德创视觉之家“微信小程序或者关注”德创测控“公众号

999.png



楼主最近还看过


热门招聘
相关主题

官方公众号

智造工程师