Программирование - это просто
Advertisement
Главная arrow Искусственный интеллект arrow Компьютерное зрение (платный раздел). arrow Компьютерное зрение. Урок 22. Методы представления контуров
29.06.2017 г.
Главное меню
Главная
Системный подход
Интернет магазин
Биржевые роботы
Программные продукты
Математика и информатика
1С:Предприятие
C#, Delphi, VB, F#, Web и пр.
Искусственный интеллект
Услуги
Ча. Во. (FAQ)
Платный раздел
Наука для чайников
Разное
Размышления
Карта сайта
Друзья сайта
Excel-это не сложно
Все о финансах
Компьютерное зрение. Урок 22. Методы представления контуров Печать E-mail
Автор megabax   
17.12.2016 г.
New Page 1

Компьютерное зрение. Урок 22. Методы представления контуров

Чтобы смотреть урок полностью, а также скачать исходники к уроку, подпишитесь на платный раздел.

В платном разделе статья находится здесь.


На прошлом уроке мы с вами разобрали алгоритм сопоставления контуров. Этот алгоритм гораздо быстрее, чем сопоставления кусочка картинки из урока 14. Но все таки, и он имеет свое ограничения по скорости, например, если картинка слишком большая и контур тоже большой, задержка уже заметна. Кроме того, данный алгоритм имеет такой недостаток, что объект другого масштаба или повернутый он уже не найдет. Поэтому, на прошлом уроке я пообещал разобрать различные способы представления контуров.

Итак, сначала перечислю некоторые способы представления контуров:

  • Цепные коды.  Берем какую либо точку кода. Следующая точка находиться в каком либо направлении от этой точки. Направления нумеруются от 0 до 7 (см. урок 20). Таким образом, весь контур представлен в виде таких вот кодов направления. Часто используют масштабирование, то есть, коды записывают не попиксельно, а делят изображение на сетку, и уже в этой сетке отмечают точки контура.

  • Аппроксимация ломанной линией. Контур может быть придавлен в виде какой-то кривой, и эта кривая подвергается аппроксимацией. Есть два подхода. В первом случае берем ряд точек и строим по ним прямую методом наименьших квадратов (некую такаю среднюю линию). Считаем отклонение точек от этой линии. Если они не выходят за заданный порог, то добавляем еще точек. Как только только вышли за определенный порог - таким же макаром строим новую прямую линию.  Другой подход - находим две крайние точки, соединяем их отрезком. Затем делим отрезок, чтобы захватить и другие точки. Те отрезки тоже делим и так до тех пор, пока не достигнем заданной точности аппроксимации.

  • Сигнатуры. Суть состоит в том, чтобы описать контур в виде одномерной функции. Например, можно координаты точек контура перевести в полярные. Радиус вектор от центра координат до точки - это будет значение функции, а угол поворота - ее аргумент. Таким образом, у нас получиться одномерная зависимость длины радиуса от угла поворота. Для круга это будет прямая линия, а для квадрата - некая функция с четырьмя экстремумами, соответствующими его углам.

  • Фурье-дескрипторы. Если представить контур в виде одномерной функции, то ее можно разложить в ряд Фурье (см. урок Цифровая обработка сигналов. Урок 1. Разложение в ряд Фурье и еще ряд уроков из той же области). Если контру представлен в виде массива точек, то его можно преобразовать при помощи дискретного преобразования Фурье. Как правило, значимыми являются только первые коэффициенты Фурье, так что по ним можно сравнивать похожесть контуров.

  • Статистические характеристики. Форму контуров можно описать при помощи различных статистических характеристик таких как различные средние, дисперсия и моменты более высокого порядка.

Рассмотрим аппроксимацию ломанной линии. Для проведения экспериментов возьмем исходники прошлого урока. Нам понадобиться новый класс  LineSearh, который реализует поиск прямой методом наименьших квадратов: ...

...

...

... Ну и все, тестируем:

       private void btnAprox_Click(object sender, EventArgs e)

        {

            Segmentation segmentation = new Segmentation();

            segmentation.hsv_frame = hsv_frame;

            segmentation.binarization.source = segmentation.hsv_frame;

            segmentation.binarization.threahold_binarization(0.99);

            segmentation.hsv_frame = segmentation.binarization.result;

            segmentation.exec();

 

            //переведем контур в полярные координаты с учетом центра масс

            List<PolarPoint> polars = new List<PolarPoint>();

            Point cm = segmentation.objects[0].get_center_mass();

            foreach (Point point in segmentation.objects[0].contour)

            {

                polars.Add(new PolarPoint(point.X - cm.X, point.Y - cm.Y));

            }

 

            //сортировка контура

            polars.Sort(

                delegate(PolarPoint point1, PolarPoint point2)

                {

                    if (point1.angle > point2.angle) return 1;

                    if (point2.angle > point1.angle) return -1;

                    return 0;

                });

 

            //Создадим контур, путем обратного преобразования полярных координат в декартовы

            List<Point> countour = new List<Point>();

            foreach (PolarPoint point in polars)

            {

                Point p = point.to_decart_point();

                p.X = p.X + cm.X;

                p.Y = p.Y + cm.Y;

                countour.Add(p);

            }

 

            Approximator apr = new Approximator();

            List<Edge> edges = apr.merger(countour);

            Graphics gr = pbImage.CreateGraphics();

 

            LineSearh ls = new LineSearh();

 

            string s = "";

            foreach (Edge item in edges)

            {

                ls.k = item.k;

                ls.b = item.b;

                ls.draw(gr, pbImage.Width, item.p1, item.p2);

 

                s = s + "[";

                if (item.neighbors.Count > 0)

                {

                    s = s + "(" + item.neighbors[0].angle.ToString("G3") + "; " + item.neighbors[0].ratio.ToString("G3") + "); ";

                    if (item.neighbors.Count > 1)

                    {

                        s = s + "(" + item.neighbors[1].angle.ToString("G3") + "; " + item.neighbors[1].ratio.ToString("G3") + ")";

                    }

                }

                s = s + "]; ";

            }

 

            MessageBox.Show(s);

        }

Смотрим на результат:

Компьютерное зрение. Урок 22. Методы представления контуров

Обратите внимание, что повернув треугольник, мы получим практически то же самое описание углов (за исключением крайних, которые плохо апрокисмировались?

Компьютерное зрение. Урок 22. Методы представления контуров

Небольшая разница в данном случае объясняется погрешностью аппроксимации.

Последнее обновление ( 17.12.2016 г. )
 
« След.   Пред. »
 
© 2017 Программирование - это просто
Joomla! - свободное программное обеспечение, распространяемое по лицензии GNU/GPL.
Русская локализация © 2005-2008 Joom.Ru - Русский Дом Joomla!
Design by Mamboteam.com | Powered by Mambobanner.de
Я принимаю Яндекс.Деньги
Мы принимаем
Банковские карты
Оплатите покупку в интернет-магазине банковскими картами VISA и Mastercard любого банка.
узнать больше
Электронный кошелек
Моментальная оплата покупок с помощью вашего электронного кошелька RBK Money.
узнать больше
Банковский платеж
Оплатите покупку в любом российском банке. Срок зачисления средств на счет - 3-5 рабочих дней.
узнать больше
Денежные переводы
Оплата покупок через крупнейшие системы денежных переводов CONTACT и Unistream.
узнать больше
Почтовые переводы
Оплатите покупку в любом отделении Почты России. Срок зачисления платежа - 3-4 рабочих дня.
узнать больше
Платежные терминалы
Оплата покупок в терминалах крупнейших платежных систем в любом городе России - быстро и без комиссии.
узнать больше