Как определить частичную вертикальную / горизонтальную линию на изображении?
У меня есть изображение, и у меня есть частичная линия на изображении. Они все время горизонтальные или вертикальные линии. Я не знаю ни цвета линии, ни ширины линии.
Как я могу использовать PHP, чтобы обнаружить такую строку?
Как вы видите на загруженном изображении, есть секции 3х3, которые мне нужно нарезать. Мне нужно 3 вертикальных и 3 горизонтальных сечения, чтобы разрезать части. Обратите внимание, что вокруг области содержимого есть прямоугольник с несколькими отметками, который является частью изображений.
Мы можем использовать эти маркеры, чтобы получить координаты.
5 ответов
Лучше использовать маркеры, сравнивая первый и последний N пикселей каждой строки, если они имеют одинаковый цвет / длину. Это будет более эффективно, чем разбор всех пикселей в каждой строке.
Вы можете попробовать сделать обнаружение края, а затем использовать преобразование Хафа для обнаружения линий. Проблема в вашем случае заключается в том, что края, соответствующие линиям, очень слабые. С другой стороны, вам нужно только искать вертикальные и горизонтальные линии, чтобы вы могли сильно ограничить проблему.
Обязательно используйте отметки, иначе это сложная проблема.
Чтобы использовать отметки, вам просто нужно найти свои позиции. Для этого начните с краев, возьмите последовательные полосы шириной в один пиксель и найдите периодические отклонения. Классический и довольно простой способ сделать это - использовать автокорреляцию. Поскольку ваши метки очень четкие (т. Е. Очень мало, если есть шум), вы можете найти еще более простой способ, например, усреднить значение пикселя для всей полосы и все, что отклоняется от этого более чем на небольшую величину, является меткой; или, составьте гистограмму ваших значений пикселей, и она должна иметь два резких выпуклости, один большой выпуклость для фона и небольшой выпуклость для ваших отметок и т. д. Но какой бы подход вы ни использовали, найдите отметки, и все готово.
Вы должны проверить изображение по строкам и по столбцам. Вы, скорее всего, будете использовать imagecolorat()
, Обведите все столбцы и строки. Если два (или любое произвольное ограничение) или несколько пикселей имеют одинаковые (или очень близкие) цвета, они составляют линию.
- Найдите цвет фона ($cBack) из углового пикселя (скажем, слева вверху)
- Слева вверху переместите цикл foreach (range(1, imagesx($img_rsrc)), установив $ cCur.color = imagecolorat ($ img_asset, $ x, $ y);
- $iMarkWidth + = 1; $ iMarkPosStart = $ cCur.x; пока вы не нажмете пиксель другого цвета ($cCur.color!= $cBack.color), тогда $bMarkFound - true: иначе $ bMarkFound = false;
- If $ cCur.color == $ cBack.color, $ horizMarkArray [] = array ($ iMarkPosStart, $ iMarkPosStart + $iMarkWidth, $iMarkWidth);
- продолжить до конца ширины
- Если is_empty($horizMarkArray) повторить со следующей горизонтальной строкой
- .. и до 11. Повторите для высоты / вертикали с $vertMarkArray[]
На шагах 4 и 8 вы можете выполнить любое усреднение, обнаружение шума и т. Д. На шагах 7 и 11 вы можете повторить предыдущие шаги и усреднить значение $iMarkWidth, чтобы избежать ошибок сглаживания в верхней части строки. В этом случае вы останавливаетесь либо:
- после N строк или
- после $iMarkWidth > {то, что явно шире любой строки}