Подтвердить что ты не робот

Обнаружение горизонтальной линии с помощью OpenCV

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

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

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

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

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

Спасибо! Патрик.

4b9b3361

Ответ 1

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

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

UPDATE:

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

Для вашего изображения я могу получить хорошие результаты, объединив обнаружение Canny edge с 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)

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

Ответ 2

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

Ответ 3

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

  • Конвертировать из RGB в оттенки серого (cvCvtColor)
  • Гладкий (cvSmooth)
  • Порог (cvThreshold)
  • Обнаружение ребер (cvCanny)
  • Найти контуры (cvFindContours)
  • Приблизительные контуры с линейными функциями (cvApproxPoly)

В вашем приложении результирующий список контуров, вероятно, будет большим (в зависимости от "агрессивности" сглаживания и улучшения функции детектора края Canny. Вы можете обрезать этот список различными параметрами: количество точек, возвращаемых из объект контура, область контура (cvContourArea) и т.д. По моему опыту, я ожидал бы, что "правильные" строки в вашем приложении будут иметь четко определенные области и значения количества вершин. Кроме того, вы можете отфильтровать контуры на основе расстояния между конечными точками, угол, определяемый линией, соединяющей конечные точки и т.д.

В зависимости от того, сколько у вас "времени" процессора, вы всегда можете соединить алгоритм Hough с таким алгоритмом, чтобы точно определить горизонтальные и вертикальные линии.

Ответ 4

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