Как найти координаты рамки абзаца в отсканированном документе? - PullRequest
0 голосов
/ 08 октября 2018

Я хотел бы получить координаты всех областей, содержащих любой текст, в отсканированных документах, как показано ниже (в уменьшенном качестве; исходные файлы имеют высокое разрешение):

Example input image

Я ищу что-то похожее на эти (GIMP-up-up!) Ограничивающие рамки.Для меня важно, чтобы пункты были признаны как таковые.Если два больших блока (верхний блок на левой странице, центральный блок на правой странице) получат по два ограничивающих блока, то все будет в порядке:

![Example of a possible desired result

Способ получения этих координат ограничивающего прямоугольника может быть через какой-то API (скриптовые языки предпочтительнее скомпилированных) или через командную строку, мне все равно.Важно то, что я получаю сами координаты, а не просто измененную версию изображения, где они видны.Причина в том, что мне нужно вычислить размер области каждого из них, а затем вырезать кусок в центре самого большого.

То, что я уже пробовал, пока безуспешно:

  • ImageMagick - он просто не предназначен для такой задачи
  • OpenCV - либо кривая обучения слишком высока, либо мой google-foo слишком плохой
  • Тессеракт - от чегоМне удалось получить это одноразовое программное обеспечение для распознавания текста, которое по историческим причинам не выполняет анализ макета страницы до попытки распознавания формы символа
  • OCRopus / OCRopy - должно быть в состоянии сделать это,но я не понимаю, как сказать, что мне интересны параграфы, а не слова или символы
  • Kraken ibn OCRopus - вилка OCRopus с некоторыми неровными краями, все еще борющаяся с ним
  • Использование статистики, в частности, алгоритма кластеризации (кажется, что OPTICS является наиболее подходящим для этой задачи) после бинаризации изображения - мои математические навыки и навыки кодированиядля этого достаточно

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

1 Ответ

0 голосов
/ 16 октября 2018

В Imagemagick вы можете установить порог на изображении, чтобы он не создавал слишком много шума, затем размыть его, а затем снова порог, чтобы соединить большие области черного цвета.Затем используйте -connected-components, чтобы отфильтровать небольшие области, особенно белые, а затем найдите ограничивающие рамки черных областей.(Синтаксис Unix bash)

convert image.png -threshold 95% \
-shave 5x5 -bordercolor white -border 5 \
-blur 0x2.5 -threshold 99% -type bilevel \
-define connected-components:verbose=true \
-define connected-components:area-threshold=20 \
-define connected-components:mean-color=true \
-connected-components 4 \
+write tmp.png null: | grep "gray(0)" | tail -n +2 | sed 's/^[ ]*//' | cut -d\  -f2`


Это изображение tmp.png, которое было создано.Обратите внимание, что я удалил области размером менее 20 пикселей.Отрегулируйте по желанию.Также отрегулируйте размытие по желанию.Вы можете увеличить его, чтобы получить больше связанных областей или меньше, чтобы приблизиться к отдельным строкам текста.Я выбрил 5 пикселей вокруг, чтобы удалить точечный шум в верхней части изображения, а затем добавил белую рамку в 5 пикселей.

enter image description here

Этосписок ограничивающих рамок.

Вот листинг:

267x223+477+123
267x216+136+43
48x522+413+0
266x86+136+317
266x43+136+410
266x66+477+404
123x62+479+346
137x43+142+259
117x43+486+65
53x20+478+46
31x20+606+347
29x19+608+48
26x18+716+347
26x17+256+480
25x17+597+481
27x18+716+47
21x17+381+240
7x7+160+409

Мы можем сделать еще один шаг, рисуя коробки с областями:

boxes=""
bboxArr=(`convert image.png -threshold 95% \
-shave 5x5 -bordercolor white -border 5 \
-blur 0x2.5 -threshold 99% -type bilevel \
-define connected-components:verbose=true \
-define connected-components:area-threshold=20 \
-define connected-components:mean-color=true \
-connected-components 4 \
+write tmp.png null: | grep "gray(0)" | sed 's/^[ ]*//' | cut -d\  -f2`)
num="${#bboxArr[*]}"
for ((i=0; i<num; i++)); do
WxH=`echo "${bboxArr[$i]}" | cut -d+ -f1`
xo=`echo "${bboxArr[$i]}" | cut -d+ -f2`
yo=`echo "${bboxArr[$i]}" | cut -d+ -f3`
ww=`echo "$WxH" | cut -dx -f1`
hh=`echo "$WxH" | cut -dx -f2`
x1=$xo
y1=$yo
x2=$((xo+ww-1))
y2=$((yo+hh-1))
boxes="$boxes rectangle $x1,$y1 $x2,$y2"
done
convert image.png -fill none -strokewidth 2 -stroke red -draw "$boxes" -alpha off image_boxes.png


enter image description here

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

...