基于halcon的直线查找之拟合

我这人比较懒得罗里吧嗦,基本都是直接说两点:why?how?

基于halcon的直线查找之拟合

直线的检测在halcon中主要有两种方式:直线拟合和卡尺直线。这里分享直线拟合,直线卡尺请移步:直线卡尺

普通直线拟合

halcon有方便快捷的fit_line_contour_xld算子。用法简单粗暴:

draw_line画一条直线;
gen_region_line生成直线区域;
gen_contour_region_xld直线区域转xld轮廓;
④然后你可以直接fit_line_contour_xld拟合直线,也可以先get_contour_xld对轮廓的点坐标自己做一些筛选。

但是如果需求不允许使用阻塞线程的、交互性的draw系列算子,或者无法获取一系列的点坐标呢?

这里介绍一种只用两点坐标,甚至一点坐标 + 斜率,就能拟合直线的方法:

CTRL + CV时刻

直接上代码: 直接copy拿去用吧
下面是写好的 拟合代码,这里的参数类型可以改成其他同类的类型,或者其他容器类。

// 拟合代码,外部调用,我这里是传入首尾两点,起始可以传入任意位置的点来拟合,
// 传入不是首尾点的话,计算方式要做一点修改
bool FitLine(HTuple start, HTuple end, HTuple& phi)
{
    //公式AX + BY + C = 0
    double a = 0;
    double b = 0;
    double c = 0;
    a = end[0].D() - start[0].D();
    b = start[1].D() - end[1].D();
    c = end[1].D() * start[0].D() - start[1].D() * end[0].D();
    HTuple len = HTuple();
    DistancePp(start[0], start[1], end[0], end[1], &len);
    AngleLx(start[0], start[1], end[0], end[1], &phi);
    //x_len是x轴的直角边长度,看需求是用斜边len长,还是x_len长度,或者再求个y轴长度都行
    double x_len = cos(phi[0].D() * 180 / PI) * len[0].D();
    QList<double> rows, cols;
    rows.append(start[0].D());
    cols.append(start[1].D());
    double newX = 0;
    double newY = 0;
    //len[0].D() / 10.0,除10是点与点的像素间隔,你可以用5、20、17任意数字都行。
    //当然,别用负值,比较间隔没有负值  - -0
    for(int i = 2; i < static_cast<int>(len[0].D() / 10.0) - 2; i++)
    {
        newX = start[1].D() + (i * 10);
        newY = (-1 * a * newX - c) / b;
        rows.append(newY);
        cols.append(newX);
    }

    rows.append(end[0].D());
    cols.append(end[1].D());
    QPoint startPoint, endPoint;

    if(FitLineByTwoPoint(rows, cols, startPoint, endPoint))
    {
        AngleLx(startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y(), &phi);
        //这里可以在形参那里多传入一个HObject引用来获取直线结果对象
        //HObject line;
        //GenRegionLine(&line, startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y());
        //DispObj(line, winID);
        return true;
    }

    return false;
}
// 拟合代码,被FitLine使用:参数类型是QList,是Qt的,可以改成HTuple或者标准类型。
bool FitLineByTwoPoint(QList<double> rows, QList<double> cols, QPoint& startPoint, QPoint& endPoint)
{
    try
    {
        HTuple dst_rows = HTuple();
        HTuple dst_cols = HTuple();

        for (int i = 0; i < rows.length(); i++)
        {
            dst_rows.Append(rows[i]);
            dst_cols.Append(cols[i]);
        }

        //SortPairs(rows, cols, &dst_rows, &dst_cols);
        HTuple rowBegin = HTuple(), colBegin = HTuple(), rowEnd = HTuple(), colEnd = HTuple(), nr = HTuple(), nc = HTuple(), dist = HTuple();
        HXLDCont lineXLD = HXLDCont(dst_rows, dst_cols);
        FitLineContourXld(lineXLD, "tukey", -1, 0, 5, 2, &rowBegin, &colBegin, &rowEnd, &colEnd, &nr, &nc, &dist); //tukey剔除算法为halcon推荐算法
        startPoint = QPoint(colBegin.D(), rowBegin.D());
        endPoint = QPoint(colEnd.D(), rowEnd.D());
        return true;
    }
    catch (HException* ex)
    {
    }
    return false;
}

注意

我懒得写

  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值