Halcon 十字抓取算法

本文介绍了Halcon中的十字线抓取算法,关键在于滤波阈值设定和线段处理。通过设置滤波高值和低值为24,以及十字线宽度为60,算法能有效拟合高斯直线,过滤掉小线段,并连接相邻线段。最终,对连接后的线进行过滤和拟合,实现精准的十字线检测。

在这里插入图片描述` [DisplayName(“滤波高值”)]
public int ThresholdHight { get; set; } = 24;
[DisplayName(“滤波低值”)]
public int ThresholdLow { get; set; } = 24;
[DisplayName(“十字线宽”)]
public int CrossLineWidth { get; set; } = 60;

    [DisplayName("是否显示轮廓")]
    public YesNo ShowOutline { get; set; } = true;
    [DisplayName("第一次过滤最短线长")]
    public int FristSelectLineShort { get; set; } = 255;
    [DisplayName("是否显示第一次过滤线长")]
    public YesNo ShowFristSelectXLD { get; set; } = true;

    [DisplayName("第二次过滤最短线长")]
    public int DoubleSelectLineShort { get; set; } = 500;
    [DisplayName("是否显示第二次过滤线长")]
    public YesNo ShowDoubleSelectXLD { get; set; } = true;

    public bool FindCross(out HObject contours)
    {
        if (!base.Execute())
        {
            contours = null;
            return false;
        }
        if (ImageProvider == null || !ImageProvider.Enabled || !ImageProvider.GetResult())
        {
            contours = null;
            return false;
        }
        // Initialize local and output iconic variables 
        HOperatorSet.GenEmptyObj(out HObject ho_Angio);
        HOperatorSet.GenEmptyObj(out HObject ho_GrayImage);
        HOperatorSet.GenEmptyObj(out HObject ho_Lines);
        HOperatorSet.GenEmptyObj(out HObject ho_RelLines);
        HOperatorSet.GenEmptyObj(out HObject ho_UnionContours);
        HOperatorSet.GenEmptyObj(out HObject ho_asd);

        HObject curImage = ImageProvider.GetCurrentImage();
        HOperatorSet.Rgb1ToGray(ho_Angio, out ho_GrayImage);

        //根据最大线宽和对比度计算lines_gauss的三个参数
        //第1个参数:最大线宽
        //第2个参数:对比度,若有2个值,第2个值为最小对比度且一定小于第1个值;若
        //仅有1个值,则最小对比度为最大对比度的1/3
        calculate_lines_gauss_parameters(CrossLineWidth, (new HTuple(ThresholdHight)).TupleConcat(ThresholdLow), out HTuple hv_Sigma,
            out HTuple hv_Low, out HTuple hv_High);
        //计算高斯直线
        ho_Lines.Dispose();
        HOperatorSet.LinesGauss(curImage, out ho_Lines, hv_Sigma, hv_Low, hv_High,
            "dark", "true", "parabolic", "true");
        //过滤固定线长的轮廓
        ho_RelLines.Dispose();
        HOperatorSet.SelectContoursXld(ho_Lines, out ho_RelLines, "length", FristSelectLineShort, 9999, 0, 0);
        if (ShowFristSelectXLD)
        {
            contours = ho_RelLines;
            Owner.Display.ShowObject(ho_RelLines);                
        }
        //将共线的轮廓连接起来
        ho_UnionContours.Dispose();
        HOperatorSet.UnionCollinearContoursXld(ho_RelLines, out ho_UnionContours, 1000, 1, 6, 0.1, "attr_keep");
        //过滤固定线长的轮廓
        ho_asd.Dispose();
        HOperatorSet.SelectContoursXld(ho_UnionContours, out ho_asd, "length", DoubleSelectLineShort, 9999, 0, 0);
        if (ShowDoubleSelectXLD)
        {contours = ho_RelLines;
            Owner.Display.ShowObject(ho_asd);
        }
        //拟合直线
        HOperatorSet.FitLineContourXld(ho_asd, "tukey", -1, 0, 5, 2, out HTuple hv_RowBegin,
            out HTuple hv_ColBegin, out HTuple hv_RowEnd, out HTuple hv_ColEnd, out HTuple hv_Nr, out HTuple hv_Nc, out HTuple hv_Dist);
        HOperatorSet.TupleLength(hv_ColBegin, out HTuple length);
        if (length != 2)//避免取到过多直线
        {
            contours = null;
            return false;
        }
        else
        {
            contours = ho_RelLines;
        }

        List<PointF> Points = new List<PointF>();
        for (int i = 0; i < 2; i++)
        {
            double ox1 = 0, oy1 = 0, ox2 = 0, oy3 = 0;
            imageProvider.ConvertXY(hv_ColBegin[i], hv_RowBegin[i], ref ox1, ref oy1);
            imageProvider.ConvertXY(hv_ColEnd[i], hv_RowEnd[i], ref ox2, ref oy3);
            PointF point = new PointF((float)ox1, (float)oy1);
            PointF point1 = new PointF((float)ox2, (float)oy3);
            Points.Add(point);
            Points.Add(point1);
        }
        PointF CrossPoint = GetIntersection(Points[0], Points[1], Points[2], Points[3]);

        SetRunDataDouble("Xstart1", Points[0].X);
        SetRunDataDouble("Ystart1", Points[0].Y);
        SetRunDataDouble("XEmd1", Points[1].X);
        SetRunDataDouble("YEmd1", Points[1].Y);


        SetRunDataDouble("Xstart2", Points[2].X);
        SetRunDataDouble("Ystart2", Points[2].Y);
        SetRunDataDouble("XEmd2", Points[3].X);
        SetRunDataDouble("YEmd2", Points[3].Y);

        SetRunDataDouble("X", CrossPoint.X);
        SetRunDataDouble("Y", CrossPoint.Y);
        if (ShowOutline)
        {
            Line l1 = new Line(hv_ColBegin[0], hv_RowBegin[0], hv_ColEnd[0], hv_RowEnd[0]);
            Line l2 = new Line(hv_ColBegin[1], hv_RowBegin[1], hv_ColEnd[1], hv_RowEnd[1]);
            //Line l1 = new Line(Points[0].X, Points[0].Y, Points[1].X, Points[1].Y);
            //Line l2 = new Line(Points[2].X, Points[2].Y, Points[3].X, Points[3].Y);
            Owner.Display.ShowLine(l1, "green", 1, 0.2);
            Owner.Display.ShowLine(l2, "green", 1, 0.2);
            //Owner.Display.ShowObject(ho_asd);
        }
        return true;
    }
    protected override bool Execute()
    {
        return FindCross(out HObject contours);
    }`

算法的重点在于高斯直线的拟合,过滤小线段,连接相临线段,过滤连接后的线,然后拟合线。

连接后的过滤可以过滤全部的小线段。

HALCON抓取图像中十字中心的坐标,通常可以通过以下步骤实现: ### 1. 图像预处理 首先需要对图像进行适当的预处理,以增强十字边缘的清晰度并减少噪声干扰。可以使用高斯滤波、阈值分割或边缘增强等方法。 ```hdevelop * 对输入图像进行高斯平滑处理 gauss_filter(Image, ImageGauss, 3, 3) ``` ### 2. 提取十字结构 通过边缘检测算子(如 `edges_sub_pix`)提取图像中的亚像素级边缘信息。由于十字具有明显的直线交叉特征,可以结合霍夫变换(`lines_gauss` 或 `hough_lines`)来提取直线段。 ```hdevelop * 提取亚像素边缘 edges_sub_pix(ImageGauss, Edges, 'canny', 1, 20, 40) ``` ### 3. 直线检测与交叉点计算 使用 `hough_lines` 算子识别图像中的直线,并通过几何计算找到这些直线之间的交点。对于典型的十字结构,通常会有两条垂直相交的直线。 ```hdevelop * 使用霍夫变换检测直线 hough_lines(Edges, Lines, 1, 1, 180, 100, 20) * 分割直线为起点和终点 get_lines(Lines, Rows1, Cols1, Rows2, Cols2) * 计算交叉点 intersection_lines(Rows1[0], Cols1[0], Rows2[0], Cols2[0], Rows1[1], Cols1[1], Rows2[1], Cols2[1], CenterRow, CenterColumn) ``` ### 4. 输出十字中心坐标 最终得到的 `CenterRow` 和 `CenterColumn` 即为十字中心的图像坐标。可以将其用于后续的定位、抓取或视觉引导任务。 ```hdevelop * 显示中心点 disp_cross(WindowHandle, CenterRow, CenterColumn, 10, 0) ``` ### 注意事项 - 若图像中存在多个交叉点,应根据实际形状特征筛选出真正的十字交叉点。 - 在复杂背景下,可能需要先使用模板匹配或 ROI 区域限定来提高鲁棒性。 - 可结合形态学操作(如开运算、闭运算)进一步优化边缘结构[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯文小提莫

努力提高作品质量

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值