コード例 #1
0
        /// <summary>
        /// 采用另外一种方式进行数学计算, 最小二乘法做一定的约束条件,约束方程为 J = L2*(A*aParam + B*bParam)^2)
        /// 这种方式可以小范围的调整角度
        /// </summary>
        /// <param name="xArray"></param>
        /// <param name="yArray"></param>
        /// <param name="aParam"></param>
        /// <param name="bParam"></param>
        /// <param name="L2"></param>
        /// <returns></returns>
        public static bool leastSquareAdaptLine2(double[] xArray, double[] yArray, double aParam, double bParam, out cylineParam lineValue, double L2 = 100)
        {
            if (L2 <= 0)
            {
                return(leastSquareAdaptLine(new List <double>(xArray), new List <double>(yArray), out lineValue));
            }

            lineValue = new cylineParam();
            Trace.Assert(xArray.Length == yArray.Length);
            if (xArray.Length < 1)
            {
                return(false);
            }

            Trace.Assert(xArray.Length == yArray.Length);
            cyPointBaseClass class1 = new cyPointBaseClass();

            int    nums = xArray.Length;
            double xx = 0, yy = 0;
            double xy = 0;
            double x = 0, y = 0;

            for (int i = 0; i < xArray.Length; i++)
            {
                xx += xArray[i] * xArray[i];
                yy += yArray[i] * yArray[i];
                xy += xArray[i] * yArray[i];
                y  += yArray[i];
                x  += xArray[i];
            }


            /*     [ xx + n*L2*bParam, x ]       [xy - n*L2*aParam]      [n,                  -x]
             * T = [                     ] , B = [                ], T* =[                      ]
             *     [                x, n ]       [     y          ]      [-x    xx + n*L2*bParam]
             */
            double t11 = nums, t12 = -x;
            double t21 = t12, t22 = (xx + nums * L2 * bParam);
            double b1  = xy - nums * L2 * aParam;
            double b2  = y;
            double div = nums * (xx + nums * L2 * bParam) - x * x;

            double a = t11 * b1 + t12 * b2;
            double b = t21 * b1 + t22 * b2;

            if (Math.Abs(a) <= 1e-6 && Math.Abs(-div) <= 1e-6)
            {
                return(true);
            }

            double dValue = Math.Sqrt(a * a + div * div);

            lineValue.A = a / dValue;
            lineValue.B = -div / dValue;
            lineValue.C = -b / dValue;

            return(true);
        }
コード例 #2
0
        public static cylineParam GetVecticalLine(cylineParam mainLine, double xpoint, double ypoint)
        {
            double c2 = (mainLine.A * ypoint - mainLine.B * xpoint);

            return(new cylineParam()
            {
                A = -mainLine.B, B = mainLine.A, C = c2
            });
        }
コード例 #3
0
        /// <summary>
        /// 将像素坐标系中的直线转换到real中, 注意, xRes = Image/ real 的比例
        /// </summary>
        /// <param name="line"></param>
        /// <param name="xRes"></param>
        /// <param name="yRes"></param>
        /// <returns></returns>
        public static cylineParam OnRatioLine(cylineParam line, double xRes, double yRes)
        {
            cylineParam line1 = new cylineParam {
                A = line.A * xRes, B = line.B * yRes, C = line.C
            };

            line1 = line1 * (1 / Math.Sqrt(line1.A * line1.A + line1.B * line1.B));
            return(line1);
        }
コード例 #4
0
        public static cylineParam GetVecticalLine(cylineParam mainLine, cyPoint2d point)
        {
            double c2 = (mainLine.A * point.y - mainLine.B * point.x);

            return(new cylineParam()
            {
                A = -mainLine.B, B = mainLine.A, C = c2
            });
        }
コード例 #5
0
        public cylineParam OnGetLineParam()
        {
            cylineParam line = new cylineParam();

            line.A = A;
            line.B = B;
            line.C = C;

            return(line);
        }
コード例 #6
0
        public static cylineParam OnGetLine(cyPoint2d point1, cyPoint2d point2)
        {
            cylineParam line1 = new cylineParam();

            line1.A = point1.y - point2.y;
            line1.B = -(point1.x - point2.x);
            line1.C = line1.A * point1.x + line1.B * point1.y;
            line1.OnNormalize();
            return(line1);
        }
コード例 #7
0
        public static double GetPointDistance(cylineParam lineParam, double pointX, double pointY)
        {
            //保证 lineParam  的系数为 平方为 1
            //double subValue = Math.Sqrt(lineParam.A * lineParam.A + lineParam.B * lineParam.B);
            double pValue = lineParam.A * pointX + lineParam.B * pointY - lineParam.C;

            if (Math.Abs(lineParam.A) <= 1e-6 && Math.Abs(lineParam.B) <= 1e-6)
            {
                return(0);
            }
            else
            {
                return(Math.Abs(pValue));
            }
        }
コード例 #8
0
        /// <summary>
        /// 遍历一条直线距离这个区域最小距离的点
        /// </summary>
        /// <param name="line"></param>
        /// <param name="xArray"></param>
        /// <param name="yArray"></param>
        public static int SearchClosingLinePoint(cylineParam line, double[] xArray, double[] yArray)
        {
            //List<double> dist = new List<double>();
            double minValue = Double.MaxValue;
            int    index    = 0;

            for (int i = 0; i < xArray.Length; i++)
            {
                double distValue = Math.Abs(line.A * xArray[i] + line.B * yArray[i] - line.C);
                if (minValue > distValue)
                {
                    minValue = distValue; index = i;
                }
            }
            return(index);
        }
コード例 #9
0
        public static bool leastSquareAdaptLineWeight(List <double> xArray, List <double> yArray, List <double> weight, out cylineParam lineValue)
        {
            Trace.Assert(xArray.Count == yArray.Count);
            cyPointBaseClass class1 = new cyPointBaseClass();

            lineValue = new cylineParam()
            {
                A = 0, B = 0, C = 0
            };

            int           nums   = xArray.Count;
            List <double> matrix = new List <double>()
            {
                0, 0, 0, 0
            };
            List <double> bias = new List <double>()
            {
                0, 0
            };
            double xx = 0, xy = 0, yy = 0, x = 0, y = 0;

            for (int i = 0; i < xArray.Count; i++)
            {
                xx += xArray[i] * xArray[i] * weight[i];
                yy += yArray[i] * yArray[i] * weight[i];
                xy += xArray[i] * yArray[i] * weight[i];
                x  += xArray[i] * weight[i];
                y  += yArray[i] * weight[i];
            }

            matrix[0] = xx; matrix[1] = xy;
            matrix[2] = matrix[1]; matrix[3] = yy;
            bias[0]   = x; bias[1] = y;
            List <double> result;
            List <double> invMatrix;

            cyUCSMeasure.MatrixInv2X2(matrix, out invMatrix);
            cyUCSMeasure.Matrix_Mult2X1(invMatrix, bias, out result);
            lineValue.A = result[0]; lineValue.B = result[1];
            //double c = (result[0]*x + result[1]*y) /weight.Sum() ;
            lineValue = new cylineParam()
            {
                A = result[0], B = result[1], C = 1
            };
            lineValue.OnNormalize();
            return(true);
        }
コード例 #10
0
        public bool IntersectPoint(cylineParam line1, out cyPoint2d crossPoint)
        {
            crossPoint = new cyPoint2d()
            {
                x = 0, y = 0
            };
            double condition = line1.A * B - A * line1.B;

            if (Math.Abs(condition) < 1e-6)
            {
                return(false);
            }

            crossPoint.x = ((B * line1.C - line1.B * C) / condition);
            crossPoint.y = ((-A * line1.C + line1.A * C) / condition);
            return(true);
        }
コード例 #11
0
        public static cylineParam ToGetVectorLine(double[] xValue, double[] yValue, cylineParam line1)
        {
            Trace.Assert(xValue.Length == yValue.Length);

            cylineParam result = new cylineParam()
            {
                A = -line1.B, B = line1.A, C = 0
            };

            if (xValue.Length == 0)
            {
                return(result);
            }
            for (int i = 0; i < xValue.Length; i++)
            {
                result.C += result.A * xValue[i] + result.B * yValue[i];
            }

            result.C /= xValue.Length;
            return(result);
        }
コード例 #12
0
        /// <summary>
        /// 根据直线方程和contour ,计算交点;
        /// </summary>
        /// <param name="contourX"></param>
        /// <param name="contourY"></param>
        /// <param name="lineParam"></param>
        /// <param name="interSectionX"></param>
        /// <param name="interSectionY"></param>
        public static void OnInterSectionContours(List <double> contourX, List <double> contourY, cylineParam lineParam, out List <double> interSectionX, out List <double> interSectionY)
        {
            interSectionX = new List <double>();
            interSectionY = new List <double>();
            if (contourX.Count == 0)
            {
                return;
            }
            double value1 = lineParam.C - contourX[0] * lineParam.A - contourY[0] * lineParam.B;
            int    direct = 0;//零为正, 1 为负

            if (Math.Abs(value1) < 1e-8)
            {
                interSectionX.Add(contourX[0]); interSectionY.Add(contourY[0]);
            }
            for (int i = 1; i < contourX.Count; i++)
            {
                double value2 = lineParam.C - contourX[0] * lineParam.A - contourY[0] * lineParam.B;
                if ((value2 < 0 && value1 > 0) || (value2 > 0 && value1 < 0))
                {
                    cylineParam line1 = OnGetLine(new cyPoint2d()
                    {
                        x = contourX[i], y = contourY[i]
                    }, new cyPoint2d()
                    {
                        x = contourX[i - 1], y = contourY[i - 1]
                    });
                    cyPoint2d cross = IntersectPoint(line1, lineParam);
                    interSectionX.Add(cross.x);
                    interSectionY.Add(cross.y);
                }
                else if (value2 == 0)
                {
                    interSectionX.Add(contourX[i]);
                    interSectionY.Add(contourY[i]);
                }
                value1 = value2;
            }
        }
コード例 #13
0
        public static cyPoint2d IntersectPoint(cylineParam line1, cylineParam interline)
        {
            cyPoint2d crossPoint = new cyPoint2d()
            {
                x = 0, y = 0
            };
            List <double> matrix = new List <double>()
            {
                line1.A, line1.B, interline.A, interline.B
            };
            List <double> mult = new List <double>()
            {
                line1.C, interline.C
            };
            List <double> inv1, result;

            cyUCSMeasure.MatrixInv2X2(matrix, out inv1);
            cyUCSMeasure.Matrix_Mult2X1(inv1, mult, out result);

            crossPoint.x = result[0];
            crossPoint.y = result[1];
            return(crossPoint);
        }
コード例 #14
0
        /// <summary>
        /// 根据点坐标拟合一条直线
        /// </summary>
        public static bool leastSquareAdaptLine(List <double> xArray, List <double> yArray, out cylineParam lineValue)
        {
            Trace.Assert(xArray.Count == yArray.Count);
            cyPointBaseClass class1 = new cyPointBaseClass();

            lineValue = new cylineParam()
            {
                A = 0, B = 0, C = 0
            };

            int           nums   = xArray.Count;
            List <double> matrix = new List <double>()
            {
                0, 0, 0, 0
            };
            List <double> bias = new List <double>()
            {
                0, 0
            };
            double xx = 0, xy = 0, yy = 0, x = 0, y = 0;

            for (int i = 0; i < xArray.Count; i++)
            {
                xx += xArray[i] * xArray[i];
                yy += yArray[i] * yArray[i];
                x  += xArray[i];
                xy += xArray[i] * yArray[i];
                y  += yArray[i];
            }
            double dVAlue1 = xx - (x * x) / nums;
            double dValue2 = yy - (y * y) / nums;
            bool   bFunX   = true;

            // y方向的方差更小, 那证明, 应该采用 x= a*y +b;
            if (dVAlue1 < dValue2)
            {
                bFunX = false;
            }

            if (bFunX == true)
            {
                //y = ax+b;
                matrix[0] = xx; matrix[1] = x;
                matrix[2] = matrix[1]; matrix[3] = nums;
                bias[0]   = xy; bias[1] = y;
            }
            else
            {
                //ay +b = x
                matrix[0] = yy; matrix[1] = y;
                matrix[2] = matrix[1]; matrix[3] = nums;
                bias[0]   = xy; bias[1] = x;
            }

            List <double> Invmatrix = null;

            MatrixInv2X2(matrix, out Invmatrix);

            // AAd*y = a*x +c
            List <double> reusltMatrix = new List <double>();

            Matrix_Mult2X1(Invmatrix, bias, out reusltMatrix);
            double a = reusltMatrix[0];
            double c = reusltMatrix[1];

            //三次去掉最大的偏差点
            List <double> listDist   = new List <double>();
            List <double> moveIndex  = new List <double>();
            List <double> moveXArray = new List <double>();
            List <double> moveYArray = new List <double>();


            int nums2 = xArray.Count();

            for (int t = 0; t < 3; t++)
            {
                // 求平均距离, 和最大的偏置项,在置信度[-99.6, 99.6]内的值保留,其他的去掉
                double sValue = 0;
                double uValue = 0;
                if (xArray.Count() < nums2 * 2 / 3 || xArray.Count() <= 2)
                {
                    break;
                }
                for (int j = 0; j < xArray.Count; j++)
                {
                    double pValue = 0;
                    pValue = (bFunX == true) ? (xArray[j] * a + c - yArray[j]) / Math.Sqrt(a * a + 1) :
                             (yArray[j] * a + c - xArray[j]) / Math.Sqrt(a * a + 1);
                    listDist.Add(pValue);
                    uValue += pValue;
                    sValue += pValue * pValue;
                }
                uValue /= xArray.Count;
                sValue  = Math.Sqrt((sValue - (uValue * uValue) * xArray.Count) / (xArray.Count - 1));

                double distMin = uValue - 1.96 * sValue;
                double distMax = uValue + 1.96 * sValue;
                nums = xArray.Count;
                for (int j = 0; j < xArray.Count; j++)
                {
                    if (listDist[j] > distMin && listDist[j] < distMax)
                    {
                        continue;
                    }

                    matrix[0] -= ((bFunX == true)? (xArray[j] * xArray[j]):(yArray[j] * yArray[j]));
                    matrix[1] -= ((bFunX == true) ? xArray[j]:yArray[j]);
                    bias[0]   -= xArray[j] * yArray[j];
                    bias[1]   -= ((bFunX == true) ? yArray[j]:xArray[j]);

                    xArray.RemoveAt(j);
                    yArray.RemoveAt(j);
                    listDist.RemoveAt(j);

                    //double xValue = xArray[j];
                    //double yValue = yArray[j];
                    //moveXArray.Add(xValue);
                    //moveYArray.Add(yValue);
                    j--;
                }
                matrix[3] = xArray.Count;
                matrix[2] = matrix[1];
                MatrixInv2X2(matrix, out Invmatrix);
                Matrix_Mult2X1(Invmatrix, bias, out reusltMatrix);
                a = reusltMatrix[0];
                c = reusltMatrix[1];
                listDist.Clear();
                if (xArray.Count == nums)
                {
                    break;
                }
            }

            double div = Math.Sqrt(a * a + 1);

            if (bFunX == true)
            {
                // y=ax+c
                lineValue.A = a / div;
                lineValue.B = -1 / div;
                lineValue.C = -c / div;
            }
            else
            {
                //x = ay+c
                lineValue.A = 1 / div;
                lineValue.B = -a / div;
                lineValue.C = c / div;
            }


            return(true);
        }
コード例 #15
0
        public static void GetInterSectionContoursIndex(double[] contourX, double[] contourY, cylineParam lineParam, out List <int> crossIndex)
        {
            crossIndex = new List <int>();
            if (contourX.Length == 0)
            {
                return;
            }
            double value1 = lineParam.C - contourX[0] * lineParam.A - contourY[0] * lineParam.B;
            int    direct = 0;//零为正, 1 为负

            if (Math.Abs(value1) < 1e-8)
            {
                crossIndex.Add(0);
            }
            for (int i = 1; i < contourX.Length; i++)
            {
                double value2 = lineParam.C - contourX[i] * lineParam.A - contourY[i] * lineParam.B;
                if ((value2 < 0 && value1 > 0) || (value2 > 0 && value1 < 0))
                {
                    crossIndex.Add(i);
                }
                value1 = value2;
            }
        }
コード例 #16
0
        public static void OnInterSectionContours2(double[] contourX, double[] contourY, cylineParam lineParam, out List <double> interSectionX, out List <double> interSectionY)
        {
            interSectionX = new List <double>();
            interSectionY = new List <double>();
            if (contourX.Length == 0)
            {
                return;
            }
            double value1 = lineParam.C - contourX[0] * lineParam.A - contourY[0] * lineParam.B;
            int    direct = 0;//零为正, 1 为负

            if (Math.Abs(value1) < 1e-8)
            {
                interSectionX.Add(contourX[0]); interSectionY.Add(contourY[0]);
            }
            for (int i = 1; i < contourX.Length; i += 2)
            {
                double value2 = lineParam.C - contourX[i] * lineParam.A - contourY[i] * lineParam.B;
                if ((value2 < 0 && value1 > 0) || (value2 > 0 && value1 < 0))
                {
                    List <double> xpos = new List <double>(); List <double> ypos = new List <double>();
                    for (int t = -15; t < 15; t += 2)
                    {
                        int index = i + t;
                        if (index < 0)
                        {
                            index += contourX.Count();
                        }
                        else if (index >= contourX.Count())
                        {
                            index -= contourX.Count();
                        }
                        xpos.Add(contourX[index]); ypos.Add(contourY[index]);
                    }
                    cylineParam line1;
                    leastSquareAdaptLineFast(xpos, ypos, out line1);
                    cyPoint2d cross = IntersectPoint(line1, lineParam);
                    interSectionX.Add(cross.x);
                    interSectionY.Add(cross.y);
                }
                else if (Math.Abs(value2) <= Double.MinValue * 10)
                {
                    interSectionX.Add(contourX[i]); interSectionY.Add(contourY[i]);
                }
                value1 = value2;
            }
        }
コード例 #17
0
 public cyOXYLine(cylineParam lineParam)
 {
     A = (float)lineParam.A;
     B = (float)lineParam.B;
     C = (float)lineParam.C;
 }
コード例 #18
0
        public static bool IsVertical(cylineParam mainLine, cylineParam measureLine)
        {
            double tValue = mainLine.A * measureLine.A + mainLine.B * measureLine.B;

            return(Math.Abs(tValue) <= Double.Epsilon ? true : false);
        }