Реализация алгоритма Hough Transform (+визуализация работы)

от автора

Не так давно я написал свою первую статью, благодаря которой стал полноценным хабражителем. Но все же метод предложенный мною калибрует со значительной ошибкой 5-7%, глупо терять на таком месте шанс на удачный результат. Поэтому решено было реализовать метод опубликованный Vasyutka в этом топике, на который меня направил ZlodeiBaal, за что ему спасибо. =)
Первым же делом предлагаю посмотреть, как он работает:

Сам процесс визуализации длился около 6 — 8 часов, так как был взят небольшой шаг для θ, да и сделано все было для одного раза.

Предполагается, что читатель знаком с алгоритмом. Если нет, то можно сделать это тут «Цифровая обработка изображений» Р. Гонсалес. Р. Вудс. Издание 3-е, 2012 г. страницы 848 — 854 или «Цифровая обработка изображений» Р. Гонсалес. Р. Вудс. 2005 г. Глава 10. В книгах написана исчерпывающая информация для написания программы.

Постобработка

Первым делом необходимо визуализировать прямые, сделать это можно с помощью трех операции:

            CvInvoke.GaussianBlur(gray, gray, new Size(3, 3), 1, 0, BorderType.Default);             CvInvoke.Sobel(gray, gray, DepthType.Default, 0, 1, 3);             CvInvoke.Canny(gray, gray, 70, 130); 

Сглаживание CvInvoke.GaussianBlur уберет лишние детали, оператор Собеля CvInvoke.Sobel с коэффициентом умножения по Kx = 0 и Ky = 1 визуализирует только горизонтальные линии, а оператор Кэнни CvInvoke.Canny окончательно выделит границы и бинаризирует изображение.

Определение границ для ρ и θ

public double SomeMethode(Image<Gray, byte> gray) {             int D = (int)(Math.Sqrt(gray.Width * gray.Width + gray.Height * gray.Height));             Image<Gray, int> houghSpace = new Image<Gray, int>(181, ((int)(1.414213562 * D) * 2) + 1); } 

houghSpace — аккумулятор значений, диапазон которого по θ [-90°, 90°], а по ρ — [-sqrt(2)*D, sqrt(2)*D] — где D — расстояние между двумя углами расположенных по диагонали.

Кэшируем значение углов

Все просто, кэшируем значение sinθ и cosθ. Где rad — шаг заполнения таблицы, на видео он был взят в 20 раз меньше, чем (Math.PI / 180).

private double[,] CreateTable()         {             double[,] table = new double[2, 181]; // 0 - cos, 1 - sin;             double rad = (Math.PI / 180);             double theta = rad * -90;             for (int i = 0; i < 181; i++)             {                 table[0, i] = Math.Cos(theta);                 table[1, i] = Math.Sin(theta);                 theta += rad;             }             return table;         } 

Нахождения HotPoint’a

При нахождении максимального значения у аккумулятора записывается i-тое значение для нахождения угла.

public double SomeMethode(Image<Gray, byte> gray) {             int D = (int)(Math.Sqrt(gray.Width * gray.Width + gray.Height * gray.Height));             Image<Gray, int> houghSpace = new Image<Gray, int>(181, ((int)(1.414213562 * D) * 2) + 1);             int xpoint = 0;             double maxT = 0;             double[,] table = CreateTable();             for (int xi = 0; xi < gray.Width; xi++)                 for (int yi = 0; yi < gray.Height; yi++)                 {                     if (gray[yi, xi].Intensity == 0) continue;                     for (int i = 0; i < 181; i++)                     {                         int rho = (int)((xi * table[0, i] + yi * table[1, i])) + (houghSpace.Height / 2);                         Gray g = new Gray(houghSpace[rho, i].Intensity + 1);                         if (g.Intensity > maxT)                         {                             maxT = g.Intensity;                             xpoint = i;                         }                         houghSpace [rho, i] = g;                     }                 } } 

Расчет угла поворота

            double thetaHotPoint = ((Math.PI / 180) * -90d) + (Math.PI / 180) * xpoint;             return (90 - Math.Abs(thetaHotPoint) * (180 / Math.PI)) * (thetaHotPoint< 0 ? -1 : 1); 

Таким образом мы получили угол, на который необходимо трансформировать изображение, чтобы самый длинный отрезок имел горизонтальное положение.

ссылка на оригинал статьи http://habrahabr.ru/post/263493/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *