示例#1
0
        //Нужны:
        //1.Алгоритмы Собеля и Превита
        //!2.Алгоритм связывания контура
        //!!!3.Преобразование Хаффа (?)
        //!!4.Правильная отрисовка прямых

        private void btnPerformHaff_Click(object sender, EventArgs e)
        {
            //anotherWayToPerformHough(15, 5, 0.5);
            //0.Картинка уже загружена
            Int32 w = currBit.Width;
            Int32 h = currBit.Height;

            //1.Шаг theta и p выбираются автоматически (диагональ и 360)
            double temp      = Math.Pow((double)w, 2.0) + Math.Pow((double)h, 2.0);
            int    p_max     = (int)(Math.Sqrt(temp)) + 1; //диагональ
            int    theta_max = 360;                        //окружность
            int    stepP     = 20;
            int    stepTheta = 20;

            //большой цикл:
            for (int k = 0; k < 3; k++)
            {
                //2.Преобразование Хаффа
                Stack <int>[,] H = new Stack <int> [1, 1];
                ImageProc.doHoughTransform(ref originBit, ref H, p_max, theta_max + 1);

                MessageBox.Show("HoughTransform has been completed", "Progress");

                //3. Находим максимум из таблицы Хаффа:
                int iMax     = 0;
                int jMax     = 0;
                int countMax = 0;

                for (int i = 0; i < p_max; i++)
                {
                    for (int j = 0; j < theta_max; j++)
                    {
                        if (H[i, j].Count >= countMax)
                        {
                            countMax = H[i, j].Count;
                            iMax     = i;
                            jMax     = j;
                        }
                    }
                }

                //Делим на связные множества:
                int[]        points   = H[iMax, jMax].ToArray();
                List <Point> _lpoints = new List <Point>();
                for (int i = 0; i < points.Length - 1; i += 2)
                {
                    _lpoints.Add(new Point(points[i], points[i + 1]));
                }
                List <Point> f = new List <Point>();
                ImageProc.divideLinkedPoints(ref f, ref _lpoints, 7.0);

                //4. Выбираем граничные точки для построения прямой:
                Point P1 = new Point(f[0].X, f[0].Y);
                Point P2 = new Point(f[1].X, f[1].Y);

                //искомые:
                double rMax   = Math.Sqrt((P1.X - P2.Y) * (P1.X - P2.Y) + (P1.Y - P2.Y) * (P1.Y - P2.Y));
                Point  start  = P1;
                Point  finish = P2;

                foreach (Point i in f)
                {
                    foreach (Point j in f)
                    {
                        double newMax = Math.Sqrt((i.X - j.X) * (i.X - j.X) + (i.Y - j.Y) * (i.Y - j.Y));
                        if (rMax < newMax)
                        {
                            rMax   = newMax;
                            start  = new Point(i.X, i.Y);
                            finish = new Point(j.X, j.Y);
                        }
                    }
                }

                //5. Строим прямую:
                //Графика для отрисовки:
                Graphics g = Graphics.FromImage((Image)currBit);
                g.DrawLine(new Pen(Color.Red, 2f), start, finish);

                //4. Выбираем граничные точки для построения прямой:
                P1 = new Point(_lpoints[0].X, _lpoints[0].Y);
                P2 = new Point(_lpoints[1].X, _lpoints[1].Y);

                //искомые:
                rMax   = Math.Sqrt((P1.X - P2.Y) * (P1.X - P2.Y) + (P1.Y - P2.Y) * (P1.Y - P2.Y));
                start  = P1;
                finish = P2;

                foreach (Point i in f)
                {
                    foreach (Point j in f)
                    {
                        double newMax = Math.Sqrt((i.X - j.X) * (i.X - j.X) + (i.Y - j.Y) * (i.Y - j.Y));
                        if (rMax < newMax)
                        {
                            rMax   = newMax;
                            start  = new Point(i.X, i.Y);
                            finish = new Point(j.X, j.Y);
                        }
                    }
                }

                //5. Строим прямую:
                //Графика для отрисовки:
                g.DrawLine(new Pen(Color.Red, 2f), start, finish);
                //6. Удаляем точки (все, кроме граничных):
                _lpoints.Remove(start);
                _lpoints.Remove(finish);
                foreach (Point po in _lpoints)
                {
                    originBit.SetPixel(po.X, po.Y, Color.Black);
                }


                pictureBox1.Refresh();

                MessageBox.Show("Progress");

                pictureBox1.Image = (Image)currBit;
                pictureBox1.Refresh();
            }

            pictureBox1.Image = (Image)originBit;
            pictureBox1.Refresh();
            MessageBox.Show("Rastr");

            //////4.Выделим точки для проверки:
            ////int[] points = H[iMax, jMax].ToArray();
            ////for (int i = 0; i < points.Length - 1; i += 2)
            ////{
            ////    currBit.SetPixel(points[i], points[i + 1], Color.Red);

            ////}

            ////MessageBox.Show("Points have been painted", "Progress");

            //////4.Методом наименьших квадратов проведем прямую:
            ////double a = 0.0, b = 0.0;
            ////ImageProc.doMinSquaresMethod(points, ref a, ref b);

            MessageBox.Show("MinSquaresMethod has been performed", "Progress");

            pictureBox1.Image = currBit;
            pictureBox1.Refresh();
        }
示例#2
0
        //способ реализации алгоритма не по погрешности, а по "ячейкам":
        public void anotherWayToPerformHough(int stepP, int stepTheta, double accuracy)
        {
            //0.Картинка уже загружена
            Int32 w = currBit.Width;
            Int32 h = currBit.Height;

            //1.Шаг theta и p выбираются автоматически (диагональ и 360)
            double temp      = Math.Pow((double)w, 2.0) + Math.Pow((double)h, 2.0);
            int    p_max     = (int)(Math.Sqrt(temp)) + 1; //диагональ
            int    theta_max = 360;                        //окружность

            //////большой цикл:
            //for (int k = 0; k < 3; k++)
            //{
            //2.Преобразование Хаффа
            Stack <int>[,] H = new Stack <int> [1, 1];
            ImageProc.doHoughTransformCells(ref originBit, ref H, p_max, theta_max + 1, stepP, stepTheta, accuracy);

            int P = (p_max / stepP) + ((p_max % stepP == 0) ? 0 : 1);
            int T = (theta_max / stepTheta) + ((theta_max % stepTheta == 0) ? 0 : 1);

            //3. Находим максимум из таблицы Хаффа:
            int iMax     = 0;
            int jMax     = 0;
            int countMax = 0;

            for (int i = 0; i < P; i++)
            {
                for (int j = 0; j < T; j++)
                {
                    if (H[i, j].Count >= countMax)
                    {
                        countMax = H[i, j].Count;
                        iMax     = i;
                        jMax     = j;
                    }
                }
            }

            MessageBox.Show("" + countMax, "Number of dots:");

            //Рисуем эти точки:
            int[] points = H[iMax, jMax].ToArray();
            for (int i = 0; i < points.Length - 1; i += 2)
            {
                currBit.SetPixel(points[i], points[i + 1], Color.Red);
            }

            //Делим точки:
            Stack <List <Point> > Dots     = new Stack <List <Point> >();
            List <Point>          _lpoints = new List <Point>();

            for (int i = 0; i < points.Length - 1; i += 2)
            {
                _lpoints.Add(new Point(points[i], points[i + 1]));
            }
            //ImageProc.divideLinkedPoints(ref Dots, ref _lpoints, 5.0);

            foreach (Point i in Dots.Pop())
            {
                currBit.SetPixel(i.X, i.Y, Color.Yellow);
            }

            foreach (Point i in Dots.Pop())
            {
                currBit.SetPixel(i.X, i.Y, Color.Blue);
            }


            //    //4. Выбираем граничные точки для построения прямой:
            //    //int[] points = H[iMax, jMax].ToArray();
            //    int x1 = points[0], x2 = points[0];
            //    int y1 = points[1], y2 = points[1];

            //    //искомые:
            //    double rMax = Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
            //    Point start = new Point();
            //    Point finish = new Point();

            //    for (int i = 0; i < points.Length - 1; i += 2)
            //    {
            //        for (int j = 0; j < points.Length - 1; j += 2)
            //        {
            //            double newMax = Math.Sqrt((points[i] - points[j]) * (points[i] - points[j]) +
            //                                        (points[i + 1] - points[j + 1]) * (points[i + 1] - points[j + 1]));
            //            if (rMax < newMax)
            //            {
            //                rMax = newMax;
            //                start.X = points[i];
            //                start.Y = points[i + 1];
            //                finish.X = points[j];
            //                finish.Y = points[j + 1];
            //            }
            //        }
            //    }

            //    //5. Строим прямую:
            //    //Графика для отрисовки:
            //    Graphics g = Graphics.FromImage((Image)currBit);
            //    g.DrawLine(new Pen(Color.Red, 2f), start, finish);

            //    //6. Удаляем точки (все, кроме граничных):
            //    for (int i = 2; i < points.Length - 3; i += 2)
            //    {
            //        originBit.SetPixel(points[i], points[i + 1], Color.Black);
            //    }

            //    pictureBox1.Refresh();

            //    MessageBox.Show("Progress");

            //    pictureBox1.Image = (Image)currBit;
            //    pictureBox1.Refresh();
            //}

            pictureBox1.Image = currBit;
            pictureBox1.Refresh();
        }