zoukankan      html  css  js  c++  java
  • WPF -- 一种直线识别方案

    本文介绍一种直线的识别方案。

    步骤
    1. 使用最小二乘法回归直线:

    1. 得到直线方程y=kx+b后,计算所有点到直线的距离,若在阈值范围内,认为是直线。
    实现
    /// <summary>
    /// 最小二乘法求回归直线方程
    /// </summary>
    /// <param name="points">输入数据</param>
    /// <param name="k">直线斜率</param>
    /// <param name="b">直线截距</param>
    /// <param name="type">直线类型 1:水平线 2:垂直线 3:一般直线</param>
    /// <returns></returns>
    public static bool IsLine(List<Point> points, out double k, out double b, out int type)
    {
        k = 0;
        b = 0;
        type = 0;
    
        if (points.Count < 2) return false;
    
        double averageX = 0, averageY = 0, n = 0;
        n = points.Count;
        foreach (Point p in points)
        {
            averageX += p.X;
            averageY += p.Y;
        }
        averageX /= n;
        averageY /= n;
    
        double numerator = 0, denominator = 0;
        foreach (Point p in points)
        {
            numerator += (p.X - averageX) * (p.Y - averageY);
            denominator += (p.X - averageX) * (p.X - averageX);
        }
    
        if (numerator == 0) //平行于X轴为水平线,返回纵坐标平均值
        {
            b = averageY;
            type = 1;
        }
        else if (denominator == 0)//平行于Y轴为垂直线,返回横坐标平均值
        {
            b = averageX;
            type = 2;
        }
        else
        {
            type = 3;
        }
    
        k = numerator / denominator;
        b = averageY - k * averageX;
    
        foreach (Point p in points)
        {
            dis = GetPoint2LineDistance(p, k, b, type);
            if (dis > MAX_POINT_LINE_DIS) return false; //点到拟合直线距离过大
        }
    
        return true;
    }
    
    /// <summary>
    /// 计算点到直线的距离
    /// </summary>
    /// <param name="p">待计算点</param>
    /// <param name="k">直线斜率</param>
    /// <param name="b">直线截距</param>
    /// <param name="type">直线类型 1:水平线 2:垂直线 3:一般直线</param>
    /// <returns>距离</returns>
    private static double GetPoint2LineDistance(Point p, double k, double b, int type)
    {
        if (type == 1)
        {
            return Math.Abs(p.Y - b);
        }
        else if (type == 2)
        {
            return Math.Abs(p.X - b);
        }
        else
        {
            double numerator = 0, denominator = 0;
            numerator = Math.Abs(k * p.X - p.Y + b);
            denominator = Math.Sqrt(k * k + 1);
            return numerator / denominator;
        }
    }
    
    转载请注明出处,欢迎交流。
  • 相关阅读:
    20199117 2019-2020-2《网络攻防实践》第八周作业
    20199117 2019-2020-2 《网络攻防实践》第七周作业
    20199117 2019-2020-2 《网络攻防实践》第六周作业
    20199117 2019-2020-2 《网络攻防实践》第五周作业
    20199117 2019-2020-2《网络攻防实践》第四次作业
    20199121《网络攻防实践》综合实践
    用VS开发PHP扩展,PHP调用C动态链接库
    20199121《网络攻防实践》第十二周作业
    20199121《网络攻防实践》第十一周作业
    20199121《网络攻防实践》第十周作业
  • 原文地址:https://www.cnblogs.com/louzixl/p/14285717.html
Copyright © 2011-2022 走看看