Быстрый OCR-инг DjVu-шек с cuneiform

Aug 12, 2022 22:03


Как известно, у нас, пынгwынОw, всего две "народных" распознавалки текста, tesseract и cuneiform.

Первая хороша тем, что умеет распознавать "мультиязычные" тексты, также для нея существует python-приложение ocrodjvu, берущее на себя всю скучную работу по "сборке-разборке" DjVu-документа. Но очень уж она тормозная!

Вторая -- cuneiform -- значительно шустрее, хотя "понимает" только один язык за раз (с приятным исключением: ruseng). Вот для нея-то и предлагается нижеследующий скрипт-обёртка (cuneiform-djvu), автоматизирующий "сборку-разборку" и заодно исправляющий известный баг cuneifom (кракозябры вместо тире). Warning: для работы скрипта необходимы утилиты из состава DjVuLibre и hocr2djvused из состава ocrodjvu.

------8><--------------
#!/bin/bash

LANG_CODE="ruseng"
DETAIL="words"
PAGES=""
PAGE_LIST=""
QUIET=""
SINGLE_COL=""
TMPDIR="/tmp/cuneiform-djvu-$$"

doHelp() {
echo "cuneiform-djvu -- do OCR on DjVu file(s)"
echo "Usage: cuneiform-djvu File1.djvu ..."
echo "Options:"
echo " -h this help"
echo " -l LNG cuneiform's language, default is 'eng' (see 'cuneiform -l')"
echo " -p RANGE pages to process, comma-separated numbers and/or 'N1-N2' ranges"
echo " -q quiet mode"
echo " -s cuneiform's 'single column' flag"
echo " -t {lines,words,chars} hocr2djvused's detalization, default is 'words'"
exit
}

cleanup() {
rm -rf "$TMPDIR"
exit
}

makePageList() {
# $1: djvu file name
local p
PAGE_LIST=""
if [ -n "$PAGES" ]; then
for p in $(echo "$PAGES" | sed 's/,/ /g'); do
if [ -n "$(echo $p | grep '\-')" ]; then
PAGE_LIST="${PAGE_LIST}$(seq ${p%-*} ${p#*-})"
else
PAGE_LIST="${PAGE_LIST}$p"
fi
PAGE_LIST="$PAGE_LIST "
done
else
PAGE_LIST=$(seq $(djvused -e n "$1"))
fi
}

processDjvuFile() {
# $1: djvu file name
[[ -z "$QUIET" ]] && echo "processing document: $1"
mkdir -p "$TMPDIR"
rm -f "$TMPDIR/*"
makePageList "$1"
local p n=1 tot=$(echo "$PAGE_LIST" | wc -w)
for p in $PAGE_LIST; do
[[ -z "$QUIET" ]] && echo -ne "\tpage #$p ($n/$tot)... "
ddjvu -format=tiff -page=$p "$1" "$TMPDIR/page.tiff"
if [ -n "$SINGLE_COL" ]; then
cuneiform --singlecolumn -l $LANG_CODE -f hocr -o "$TMPDIR/page.hocr" "$TMPDIR/page.tiff" &> /dev/null
else
cuneiform -l $LANG_CODE -f hocr -o "$TMPDIR/page.hocr" "$TMPDIR/page.tiff" &> /dev/null
fi
rm -f "$TMPDIR/page.tiff"
if [ -f "$TMPDIR/page.hocr" ]; then
hocr2djvused --fix-utf8 -t "$DETAIL" "$TMPDIR/page.hocr" \
| sed "s/^select .*/select $p/; s/\xD0\xB2\xD0\x82\xE2\x80\x9D/\xE2\x80\x92/g" \
>> "$TMPDIR/script.djvused"
rm -f "$TMPDIR/page.hocr"
[[ -z "$QUIET" ]] && echo "OK"
else
[[ -z "$QUIET" ]] && echo "no OCR data"
fi
let n++
done
if [ -f "$TMPDIR/script.djvused" ]; then
[[ -z "$QUIET" ]] && echo "adding OCR data to $1"
djvused -s -f "$TMPDIR/script.djvused" "$1"
else
[[ -z "$QUIET" ]] && echo "no OCR data for $1"
fi
}

trap cleanup EXIT SIGINT SIGTERM SIGQUIT

# process cmd-line options
while getopts ":hqsl:p:t:" opt; do
case "$opt" in
h)
doHelp
;;
l)
LANG_CODE="$OPTARG"
;;
p)
PAGES="$OPTARG"
;;
q)
QUIET=1
;;
s)
SINGLE_COL=1
;;
t)
DETAIL="$OPTARG"
;;
:)
echo "Option $OPTARG requires an argument"
exit 1
;;
?)
echo "Unknown option $OPTARG, try '-h' for usage"
exit 1
;;
esac
done
shift "$(($OPTIND -1))"

# check programs presence
for arg in sed grep wc ddjvu djvused cuneiform hocr2djvused; do
if not which "$arg" &> /dev/null; then
echo "program not found: $arg"
exit 1
fi
done

# process documents
for arg in "$@"; do
processDjvuFile "$arg"
done------8><--------------

Примеры вызова:

$ cuneiform-djvu -l fra La_Marseillaise.djvu
$ cuneiform-djvu -l rus "Чай для чайников, том 1.djvu" "Чай для чайников, том 2.djvu"
$ cuneiform-djvu -p 2,5-15,20,21 "Мой альбом.djvu"
Original post: https://rexy-craxy.dreamwidth.org/715521.html

книги, программизьм, do it yourself, сканы

Previous post Next post
Up