Обнаружение горизонтальной линии с помощью OpenCV - PullRequest
22 голосов
/ 29 августа 2011

Я пытаюсь найти горизонтальные и вертикальные линии на изображении, которое пришло из «документа».Документы - это отсканированные страницы из контрактов, поэтому строки выглядят так, как вы видите в таблице или в блоке контракта.

Я пробовал OpenCV для этой работы.Реализация преобразования Хафа в OpenCV казалась полезной для работы, но я не смог найти какую-либо комбинацию параметров, которая позволила бы ему точно находить вертикальные и горизонтальные линии.Я пытался с и без обнаружения края.Неудачно.Если кто-то сделал что-то подобное, мне интересно знать, как.

Смотрите здесь мое изображение до и после экспериментов с HoughP в OpenCV.Это лучшее, что я мог сделать, http://dl.dropbox.com/u/3787481/Untitled%201.png

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

Я знаю, что эта проблема разрешима, потому что у меня есть инструменты распознавания Nuance и ABBYY, которые могут надежно извлекать горизонтальные и вертикальные линии и возвращать мне ограничивающий прямоугольник линий.

Спасибо!Patrick.

Ответы [ 4 ]

29 голосов
/ 29 августа 2011

Вы видели пример кода из HoughLinesP документации по функциям?

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

ОБНОВЛЕНИЕ:

Как я вижу, вам нужно найти не линии, а горизонтальныевертикальные края на странице.Для выполнения этой задачи вам нужно объединить несколько этапов обработки, чтобы получить хорошие результаты.

Для вашего изображения я могу получить хорошие результаты, комбинируя обнаружение краев Canny с HoughLinesP.Вот мой код (я использовал Python, но я думаю, что вы видите идею):

img = cv2.imread("C:/temp/1.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 80, 120)
lines = cv2.HoughLinesP(edges, 1, math.pi/2, 2, None, 30, 1);
for line in lines[0]:
    pt1 = (line[0],line[1])
    pt2 = (line[2],line[3])
    cv2.line(img, pt1, pt2, (0,0,255), 3)
cv2.imwrite("C:/temp/2.png", img)

Результат выглядит так:

9 голосов
/ 27 июля 2012

Если вы просто хотите использовать «линии», а не «линейные сегменты», я бы не стал использовать Canny, Hough, FindContours или любую другую подобную функцию на тот случай, если вам нужна более быстрая скорость в вашем коде. Если ваши изображения не повернуты и то, что вы хотите найти, всегда вертикальное или горизонтальное, я бы просто использовал cv :: Sobel (одно для вертикального, а другое для горизонтального) и создавал массивы накопления для столбцов и строк. Затем вы можете искать максимумы в таких скоплениях или профилях, например, установив порог, и вы узнаете строку или столбец, в котором есть вертикальные или горизонтальные граничные линии.

6 голосов
/ 25 февраля 2013

Не конвертируйте RGB в оттенки серого.Иногда разные цвета в RGB могут быть объединены в одно и то же значение в градациях серого, поэтому могут пропустить некоторые контуры.Вы должны проанализировать каждый из каналов RGB отдельно.

5 голосов
/ 29 августа 2011

Вы могли бы рассмотреть возможность оставить обнаружение линии Хафа, так как этот метод ищет «глобальные» линии, а не обязательно отрезки.Недавно я реализовал приложение, которое идентифицировало «параллелограммы» - по сути квадраты, которые можно поворачивать и перспективу укорачивать из-за угла обзора.Вы могли бы рассмотреть что-то подобное.Мой конвейер был:

  1. Преобразование из RGB в оттенки серого (cvCvtColor)
  2. Плавный (cvSmooth)
  3. Порог (cvThreshold)
  4. Определить края (cvCanny)
  5. Поиск контуров (cvFindContours)
  6. Приблизительные контуры с линейными элементами (cvApproxPoly)

В вашем приложении результирующий список контуров, вероятно, будет большим (в зависимости отиз-за «агрессивности» сглаживания и улучшения характеристик детектора контуров Canny. Вы можете обрезать этот список по различным параметрам: количество точек, возвращаемых из искателя контура, площадь контура (cvContourArea) и т. д. Из моего опытаЯ ожидаю, что «действительные» линии в вашем приложении будут иметь четко определенные свойства площади и количества вершин.Кроме того, вы можете отфильтровать контуры на основе расстояния между конечными точками, угла, определенного линией, соединяющей конечные точки, и т. Д.

В зависимости от того, сколько процессорного времени у вас есть, вы всегда можете соединить алгоритм Хафа сАлгоритм, подобный приведенному выше, надежно определяет горизонтальные и вертикальные линии.

...