Beispiel #1
0
        //程序功能:利用最小二乘法拟合直线
        //输入:二维点
        //输出:拟合直线
        line calLine(LinkedList <myPair> input)
        {
            matrix A  = new matrix(input.Count, 2);
            matrix AT = new matrix(2, input.Count);
            matrix B  = new matrix(input.Count, 1);

            for (int i = 0; i < input.Count; ++i)
            {
                myPair cur = input.ElementAt(i);
                A.a[i, 0]  = cur.x;
                A.a[i, 1]  = cur.y;
                AT.a[0, i] = cur.x;
                AT.a[1, i] = cur.y;
                B.a[i, 0]  = 100;
            }

            matrix coef = AT.doMul(A);
            matrix b    = AT.doMul(B);
            matrix mat  = new matrix(2, 3);

            for (int i = 0; i < 2; ++i)
            {
                for (int j = 0; j < 2; ++j)
                {
                    mat.a[i, j] = coef.a[i, j];
                }
            }
            mat.a[0, 2] = b.a[0, 0];
            mat.a[1, 2] = b.a[1, 0];

            double BB = (mat.a[0, 0] * mat.a[1, 2] - mat.a[1, 0] * mat.a[0, 2]) / (mat.a[1, 1] * mat.a[0, 0] - mat.a[0, 1] * mat.a[1, 0]);
            double AA = (mat.a[0, 2] - mat.a[0, 1] * BB) / mat.a[0, 0];

            return(new line(AA, BB, -100));
        }
Beispiel #2
0
        //输出找到的最小刻度线的点
        public myPair FindLeft()
        {
            myPair ret  = new myPair(-1, -1);
            int    max1 = 0;

            for (int i = height - 1; i * 3 >= 2 *height; i--)
            {
                int sum = 0;
                for (int j = 0; j < 100; j++)
                {
                    if (gray[j, i] == 255)
                    {
                        if (gray[j + 1, i - 1] == 255 && gray[j + 2, i - 2] == 255 && gray[j + 3, i - 3] == 255 && gray[j + 4, i - 4] == 255)
                        {
                            //return new node(circle_x - (int)Math.Sqrt(radius * radius - (circle_y - i) * (circle_y - i)),i);
                            sum = (j - circle_x) * (j - circle_x) + (i - circle_y) * (i - circle_y);
                            if (Math.Sqrt(max1) + 10 < Math.Sqrt(sum))
                            {
                                ret.x = j;
                                ret.y = i;
                                max1  = sum;
                            }
                            break;
                        }
                        else if (gray[j + 1, i] == 255 && gray[j + 2, i - 1] == 255 && gray[j + 3, i - 2] == 255 && gray[j + 4, i - 3] == 255)
                        {
                            sum = (j - circle_x) * (j - circle_x) + (i - circle_y) * (i - circle_y);
                            if (Math.Sqrt(max1) + 10 < Math.Sqrt(sum))
                            {
                                ret.x = j;
                                ret.y = i;
                                max1  = sum;
                            }
                            break;
                        }
                    }
                }
            }
            return(ret);
        }
Beispiel #3
0
        //根据直线的两个端点P,Q进行初始化
        public line(myPair P, myPair Q)
        {
            if (P.x == Q.x)
            {
                A = 1;
                B = 0;
                C = -P.x;
                return;
            }

            if (P.y == Q.y)
            {
                A = 0;
                B = 1;
                C = -P.y;
                return;
            }

            B = 1;
            A = 1.0 * (Q.y - P.y) / (P.x - Q.x);
            C = -(A * P.x + B * P.y);
        }
Beispiel #4
0
        //输出找到的最大刻度线的点
        public myPair FindRight()
        {
            myPair ret  = new myPair(0, 0);
            int    max1 = 0;

            for (int i = height - 1; i * 3 >= 2 *height; i--)
            {
                int sum = 0;
                for (int j = width - 1, k = 0; k < 100; k++, j--)
                {
                    if (gray[j, i] == 255)
                    {
                        if (gray[j - 1, i - 1] == 255 && gray[j - 2, i - 2] == 255 && gray[j - 3, i - 3] == 255 && gray[j - 4, i - 4] == 255)
                        {
                            sum = (j - circle_x) * (j - circle_x) + (i - circle_y) * (i - circle_y);
                            if (Math.Sqrt(max1) + 10 < Math.Sqrt(sum))
                            {
                                ret.x = j;
                                ret.y = i;
                                max1  = sum;
                            }
                            break;
                        }
                        else if (gray[j - 1, i] == 255 && gray[j - 2, i - 1] == 255 && gray[j - 3, i - 2] == 255 && gray[j - 4, i - 3] == 255)
                        {
                            sum = (j - circle_x) * (j - circle_x) + (i - circle_y) * (i - circle_y);
                            if (Math.Sqrt(max1) + 10 < Math.Sqrt(sum))
                            {
                                ret.x = j;
                                ret.y = i;
                                max1  = sum;
                            }
                            break;
                        }
                    }
                }
            }
            return(ret);
        }
Beispiel #5
0
        //函数功能:利用RANSAC算法从图像中提取直线,RANSAC对噪声敏感度小
        //输入:二值化图像input,目标直线的一个端点center
        //输出:目标直线方程
        public line doRANSAC(myPicture input, myPair center)
        {
            LinkedList <myPair> arr = new LinkedList <myPair>();

            for (int i = 0; i < input.width; ++i)
            {
                for (int j = 0; j < input.height; ++j)
                {
                    if (input.grayDegree[i, j] == 255)
                    {
                        arr.AddLast(new myPair(i, j));
                    }
                }
            }

            Random rd        = new Random(13);
            line   ret       = new line(0, 0, 0);
            double besterror = 1000000000000;
            int    bound     = (int)(0.07 * arr.Count);

            for (int iter = 0; iter < 100; ++iter)
            {
                int    sampleIndex = rd.Next() % arr.Count;
                myPair sample      = arr.ElementAt(sampleIndex);
                line   cur         = new line(center, sample);
                LinkedList <myPair> alsoinliers = new LinkedList <myPair>();
                foreach (myPair p in arr)
                {
                    double d = cur.distance(p);
                    if (d <= 4)
                    {
                        alsoinliers.AddLast(p);
                    }
                }

                if (alsoinliers.Count >= bound)
                {
                    alsoinliers.AddLast(sample);
                    line   better    = calLine(alsoinliers);
                    double thiserror = 0;
                    foreach (myPair p in alsoinliers)
                    {
                        double dis = better.distance(p);
                        thiserror += dis * dis;
                    }
                    thiserror /= alsoinliers.Count;
                    if (thiserror < besterror)
                    {
                        besterror = thiserror;
                        ret       = better;
                    }
                }
            }

            return(ret);

            /*
             * for (int i = 0; i < input.width; ++i)
             * {
             *  for (int j = 0; j < input.height; ++j)
             *  {
             *      double val = Math.Abs(ret.A * i + ret.B * j + ret.C);
             *      if (val <= 1)
             *      {
             *          input.picture.SetPixel(i, j, Color.FromArgb(255, 0, 0));
             *      }
             *  }
             * }
             */
            //return input;
        }
Beispiel #6
0
 //计算该直线到点P的距离
 public double distance(myPair P)
 {
     return(Math.Abs(A * P.x + B * P.y + C) / Math.Sqrt(A * A + B * B));
 }
Beispiel #7
0
        //函数功能:对main.cs传入的图像进行处理,并将结果传递到ans.cs显示
        public void domain()
        {
            //处理输入
            double low  = 0.0;
            double high = 1.0;

            try
            {
                low  = Convert.ToDouble(smallInput.Text);
                high = Convert.ToDouble(largeInput.Text);
            }
            catch
            {
                return;
            }


            OTSU B = new OTSU();
            //锐化、二值化
            myPicture ret = B.doOTSU(sharp4.doSharp(Pic));
            myPicture res = ret;
            //找圆心之前的预处理
            findCircleInit circle = new findCircleInit();

            ret = circle.init(ret);
            ret = sharp4.doSharp(ret);
            ret = circle.doHough(ret);

            //找圆心
            circle o = new findCircleCenter().doFind(ret);

            //找指针
            ret = new findLineInit().doFind(Pic, o);
            myPicture tmp = sharp1.doSharp(ret);

            tmp = smooth2.doSmooth(tmp);
            tmp = B.doOTSU(tmp);
            RANSAC R = new RANSAC();
            myPair L = R.doFind(smooth2.doSmooth(B.doOTSU(sharp4.doSharp(Pic))), R.doRANSAC(tmp, new myPair((int)o.x, (int)o.y)), o);


            //找刻度线的预处理
            eraseCircleElement ECE = new eraseCircleElement(res, (int)o.r, (int)o.x, (int)o.y);
            int r = ECE.solve();

            res = ECE.erase(r - 1);

            //找到左右两端的刻度线
            findTick ticks = new findTick(res, r - 1, (int)o.x, (int)o.y);
            myPair   left = ticks.FindLeft(), right = ticks.FindRight();

            //求角度
            double thta = 2 * Math.PI - angle(left, right, o);
            double alpha;

            if (L.x <= o.x)
            {
                alpha = angle(left, L, o);
            }
            else
            {
                alpha = thta - angle(L, right, o);
            }
            double ans = low + (high - low) * (alpha + Math.PI / 180) / thta;

            Form newForm = new ans(ans);

            newForm.ShowDialog();
            newForm.Dispose();
        }
Beispiel #8
0
 private double angle(myPair left, myPair right, circle o)
 {
     return(Math.Acos(((left.x * right.x - o.x * (left.x + right.x) + o.x * o.x) + (left.y * right.y - o.y * (left.y + right.y) + o.y * o.y)) / (Math.Sqrt((left.x - o.x) * (left.x - o.x) + (left.y - o.y) * (left.y - o.y)) * Math.Sqrt((right.x - o.x) * (right.x - o.x) + (right.y - o.y) * (right.y - o.y)))));
 }