В рамках обмена стеками TeX мы обсуждали, как обнаружить «реки» в параграфах этого вопроса .
В этом контексте реки - это полосы пустого пространства, возникающие в результате случайного выравнивания межсловных пространств в тексте. Поскольку это может отвлекать читателя, плохие реки считаются признаком плохой типографии. Пример текста с реками - тот, где есть две реки, текущие по диагонали.
Существует заинтересованность в автоматическом обнаружении этих рек, чтобы их можно было избежать (возможно, путем ручного редактирования текста). Raphink добивается некоторого прогресса на уровне TeX (который знает только положения глифов и ограничивающие рамки), но я уверен, что лучший способ обнаружить реки - это некоторая обработка изображений (поскольку формы глифов очень важны и недоступны для TeX) , Я пробовал различные способы извлечения рек из приведенного выше изображения, но моя простая идея применения небольшого количества эллипсоидального размытия не кажется достаточно хорошей. Я также попробовал немного РадонаХоть фильтрация на основе преобразования, но я тоже никуда не попал. Реки очень хорошо видны для схем обнаружения признаков человеческого глаза / сетчатки / мозга, и я думаю, что это может быть преобразовано в какую-то операцию фильтрации, но я не могу заставить ее работать. Есть идеи?
В частности, я ищу какую-то операцию, которая обнаружит 2 реки на изображении выше, но не будет иметь слишком много других ложных положительных обнаружений.
РЕДАКТИРОВАТЬ: endolith спросил, почему я придерживаюсь подхода, основанного на обработке изображений, учитывая, что в TeX у нас есть доступ к позициям глифов, промежуткам и т. Д., И может быть намного быстрее и надежнее использовать алгоритм, который проверяет фактический текст. Моя причина сделать что-то другое, потому что формаиз глифов может повлиять на то, насколько заметна река, и на уровне текста очень трудно рассмотреть эту форму (которая зависит от шрифта, лигатуры и т. д.). Для примера того, как форма глифов может быть важна, рассмотрим следующие два примера, где различие между ними состоит в том, что я заменил несколько глифов на другие почти такой же ширины, чтобы анализ на основе текста мог рассмотреть их одинаково хорошо / плохо. Обратите внимание, однако, что реки в первом примере намного хуже, чем во втором.
источник
ImageLines[]
от Mathematica, с и без предварительной обработки. Я предполагаю, что это технически использует преобразование Хафа, а не Радона. Я не удивлюсь, если правильная предварительная обработка (я не пробовал предложенный datageist фильтр расширения) и / или настройки параметров могут сделать эту работу.Ответы:
Я подумал об этом еще немного и думаю, что следующее должно быть достаточно стабильным. Обратите внимание, что я ограничился морфологическими операциями, потому что они должны быть доступны в любой стандартной библиотеке обработки изображений.
(1) Откройте изображение с маской nPix-by-1, где nPix - это вертикальное расстояние между буквами.
(2) Откройте изображение с маской 1 × mPix, чтобы исключить то, что слишком узкое, чтобы быть рекой.
(3) Удалите горизонтальные «реки и озера» из-за пробелов между абзацами или отступов. Для этого мы удаляем все строки, которые являются истинными, и открываем их с помощью маски nPix-by-1, которая, как мы знаем, не повлияет на реки, которые мы нашли ранее.
Чтобы удалить озера, мы можем использовать открывающую маску, которая немного больше, чем nPix-by-nPix.
На этом этапе мы также можем выбросить все, что слишком мало, чтобы быть настоящей рекой, то есть все, что охватывает меньшую площадь, чем (nPix + 2) * (mPix + 2) * 4 (что даст нам ~ 3 строки). +2 есть, потому что мы знаем, что все объекты имеют как минимум nPix по высоте и mPix по ширине, и мы хотим пойти немного выше этого.
(4) Если нас интересует не только длина, но и ширина реки, мы можем объединить преобразование расстояния со скелетом.
(цвета соответствуют ширине реки (хотя цветовая полоса отключена в 2 раза)
Теперь вы можете получить приблизительную длину рек, подсчитав количество пикселей в каждом подключенном компоненте и среднюю ширину, усреднив их значения в пикселях.
Вот точно такой же анализ, примененный ко второму изображению «без реки»:
источник
В Mathematica, используя эрозию и преобразование Хафа:
Редактировать Отвечая на комментарий Мистера Волшебника
Если вы хотите избавиться от горизонтальных линий, просто сделайте что-то вроде этого (возможно, кто-то может сделать это проще):
источник
lines = ImageLines[ImageResize[#, {300, 300}], .6, "Segmented" -> True] & /@ i1;
. С учетом всего сказанного, для этой проблемы морфологический подход кажется более надежным.Хммм ... Я думаю, преобразование Радона не так просто извлечь из. (Преобразование Радона в основном вращает изображение, одновременно «просматривая его»). Это принцип, лежащий в основе CAT-сканирования.) Преобразование вашего изображения дает эту синограмму с «реками», образующими яркие пики, которые обведены кружком:
Тот, что при повороте на 70 градусов, можно увидеть довольно отчетливо, как пик слева от этого графика среза по горизонтальной оси:
Особенно, если текст был сначала размыт по Гауссу:
Но я не уверен, как надежно извлечь эти пики из остального шума. Яркие верхний и нижний концы синограммы представляют «реки» между горизонтальными строками текста, которые вам явно не нужны. Может быть, весовая функция против угла, который подчеркивает больше вертикальных линий и минимизирует горизонтальные?
Простая функция взвешивания косинуса хорошо работает на этом изображении:
найти вертикальную реку под углом 90 градусов, которая является глобальными максимумами на синограмме:
и на этом изображении обнаружение того, что под углом 104 градуса, хотя размытие сначала делает его более точным:
(
radon()
Функция SciPy довольно тупая , или я бы отобразил этот пик обратно на исходное изображение в виде линии, проходящей через середину реки.)Но он не находит ни одного из двух основных пиков в синограмме для вашего изображения после размытия и взвешивания:
Они там, но они ошеломлены вещами около среднего пика весовой функции. С правильным взвешиванием и настройкой этот метод, вероятно, мог бы работать, но я не уверен, каковы правильные настройки. Вероятно, это также зависит от свойств сканов страницы. Может быть, вес должен быть получен из общей энергии в срезе или что-то вроде нормализации.
источник
Я обучил дискриминационный классификатор по пикселям, используя производные функции (до 2-го порядка) в разных масштабах.
Мои ярлыки:
Прогноз по тренировочному имиджу:
Прогноз на двух других изображениях:
Я думаю, что это выглядит многообещающе и может дать полезные результаты, учитывая больше обучающих данных и, возможно, более умные функции. С другой стороны, мне потребовалось всего несколько минут, чтобы получить эти результаты. Вы можете воспроизвести результаты самостоятельно, используя программное обеспечение с открытым исходным кодом ilastik . [Отказ от ответственности: я один из главных разработчиков.]
источник
(Извините, этот пост не содержит удивительных демонстраций.)
Если вы хотите работать с информацией, которой уже располагает TeX (буквы и позиции), вы можете вручную классифицировать буквы и пары букв как «наклонные» в том или ином направлении. Например, «w» имеет угловые наклоны SW и SE, комбо «al» имеет угловой угол NW, «k» имеет угловой угол NE. (Не забывайте пунктуацию - кавычка, за которой следует буква, заполняющая нижнюю половину поля глифа, устанавливает хороший уклон; кавычка, за которой следует q, особенно сильна.)
Затем найдите вхождения соответствующих склонов на противоположных сторонах пространства - «w al» для реки SW-to-NE или «k T» для реки NW-SE. Когда вы найдете один на линии, посмотрите, происходит ли аналогичный, смещенный влево или вправо, на линии выше / ниже; когда вы найдете их, вероятно, есть река.
Также, очевидно, просто ищите места, сложенные почти вертикально, для равнинных вертикальных рек.
Вы можете стать немного более изощренным, измерив «силу» наклона: сколько передового бокса «пусто» из-за уклона и, таким образом, влияет на ширину реки. «w» довольно маленький, так как у него есть только маленький угол своего передового поля, чтобы внести свой вклад в ривер, но «V» очень сильный. «б» немного сильнее, чем «к»; более мягкая кривая дает более визуально непрерывный край реки, делая его более прочным и визуально более широким.
источник