Пакетная обработка изображений документов в виде факса
Допустим, у меня есть фотография или отсканированный текстовый документ, возможно, с небольшим фоном водяных знаков. Если это фотография, в дополнение к водяному знаку будут присутствовать градиенты яркости от освещения и, возможно, от листа бумаги, не лежащего горизонтально из-за складок.
Я хочу постобработать эти фотографии с помощью imagemagick, чтобы они выглядели как факс, то есть конвертировали изображение в черно-белый, исправляя локальные изменения яркости. Нормальный -threshold
вариант не сработает, т.к.
- Он не автоматически определяет необходимый уровень яркости для каждой фотографии.
- Из-за градиентов яркости текст на одной части изображения может быть ярче, чем фон на другой части, так что при любом заданном глобальном пороговом значении часть текста будет потеряна.
Приложения Cam-Scanner на смартфонах обычно предоставляют опцию черно-белого документа, которая корректирует такие цветовые градиенты и вычисляет разумное первое предположение для порогового значения, которое будет достаточно для пакетной обработки.
Они не помогают, хотя, когда у меня уже есть необработанное изображение на ПК, хотя я теоретически могу загрузить их на смартфон и импортировать их - это просто очень непрактично, особенно для большого количества изображений.
Поддерживает ли imagemagick или какое-либо другое программное обеспечение с поддержкой пакетной обработки (предпочтительно с открытым исходным кодом) такое преобразование?
2 ответа
Вы можете использовать методы математической композиции Imagemagick для достижения таких результатов. Divide_src
[1] в частности, поскольку он будет удалять любые градиенты, виньетки, нежелательные штриховки.
Затем -normalize
и -threshold
должен сделать все остальное.
конвертировать $input -colorspace grey ( +clone -blur 15,15) -compose Divide_Src -composite -normalize -threshold 80% $output
Вот мой результат:
Вы можете захотеть установить порог, чтобы получить наилучшие результаты.
В зависимости от ОС, которую вы собираетесь запустить, вам, возможно, придется выйти за скобки: "\(" и "\)".
Что касается пакетной обработки лично, я бы использовал цикл for либо в bash, либо в Cygwin снова, в зависимости от ОС:
для файла в тесте /*; конвертировать $file -colorspace grey (+ clone -blur 15,15) -compose Divide_Src -composite -normalize -threshold 80% результат /`basename $file`; сделанный
Однако есть другой инструмент командной строки, который вы можете попробовать mogrify
[2] для встроенного или конкретного -path
пакетная обработка.
Для получения дополнительной информации и, возможно, других результатов следуйте [3] и [4].
[1]: http://www.imagemagick.org/Usage/compose/
[2]: http://www.imagemagick.org/script/mogrify.php
Обновление Обновленные формы скриптов теперь размещаются в виде гистов [1] [2].
Основываясь на ответе моего отца, я написал сценарии, которые автоматизируют процесс, предназначенный для сканирования с разумным контрастом. Скрипты используют Poppler's pdfimages
ImageMagick's convert
а также pdftk
,
imagemagick-scan-pdf-to-mono.sh
(зависит от второго скрипта; вывод может быть повернут, что можно исправить, запустив pdftk FILE.pdf cat 1-endW output OUT.pdf
, Направление вращения можно изменить с помощью 1-endE
вместо 1-endW
)
#!/usr/bin/env bash
# -*- mode: sh; coding: us-ascii-unix -*-
# source libstacktrace || true
# set -e -u -E
MANUAL="
Usage: $0 [options] INPUT OUTPUT
Converts a scan-pdf (assuming one image per page) to monochrome.
-f INT, --from-page INT
Process only pages with page number >= INT
-t INT, --to-page INT
Process only pages with page number <= INT
-P, --parallel INT
Process INT pages in parallel each.
-v, --verbose / +v, --noverbose
Enables/Disables verbose reporting.
-h, -?, --help
Prints this message
"
vecho(){ $VERBOSE && echo "$@"; }
######### COMMAND LINE PARSING #######################################
declare VERBOSE=false
declare ARGS=()
declare PAGE_LIMIT_LOW=""
declare PAGE_LIMIT_HIGH=""
declare PARALLEL=1
## Print manual
if [[ $# -eq 0 ]]; then
echo "$MANUAL"
exit 1
fi
## Getopt-style consumption of arguments ##
##
## Don't forget "shift", don't delete "--" and "*" cases.
while [[ $# -gt 0 ]]; do
case "$1" in
-h|-\?|--help)
echo "$MANUAL"
exit 0
shift ;;
-v|--verbose)
VERBOSE=true
shift ;;
+v|--no-verbose)
VERBOSE=false
shift ;;
-f|--from-page)
PAGE_LIMIT_LOW="-f $2"
shift 2 ;;
-t|--to-page)
PAGE_LIMIT_HIGH="-l $2"
shift 2 ;;
-P|--parallel)
PARALLEL=$2
shift 2 ;;
--)
shift
break ;;
*)
ARGS[${#ARGS[@]}]="$1"
shift ;;
esac
done
## Consume stuff remaining after -- ##
while [[ $# -gt 0 ]]; do
ARGS[${#ARGS[@]}]="$1"
shift
done
## Note that ${ARGS[@]} is considered unbound if it is empty!
INFILE=$(readlink -m "${ARGS[0]}")
OUTFILE=$(readlink -m "${ARGS[1]}")
TMPDIR=$(mktemp -d)
vecho "Using work directory '$TMPDIR'."
cd "$TMPDIR"
vecho "Extracting images from '$INFILE'..."
## Cannot be parallelized, file-locking issue.
cmd="pdfimages -j $PAGE_LIMIT_LOW $PAGE_LIMIT_HIGH $(printf %q "$INFILE") page"
# vecho "$cmd"
eval "$cmd" || true
find -name "page-*" -and -not -name "page-*-mono*" \
| xargs -P $PARALLEL -I FILE sh -c "
imagemagick-scan-to-mono.sh FILE FILE-mono.pdf \
&& { if $VERBOSE; then echo Finished file 'FILE'; fi; }
rm FILE
"
vecho "Assembling PDF file '$OUTFILE'..."
pdftk page-*-mono.pdf cat output out.pdf
mv out.pdf "$OUTFILE"
rm page-*-mono.pdf
rmdir "$TMPDIR" || ls -l
imagemagick-scan-to-mono.sh
#!/usr/bin/env bash
# -*- mode: sh; coding: us-ascii-unix -*-
source libstacktrace || true
set -e -u -E
MANUAL="
Usage: $0 INFILE OUTFILE
Takes a document scan INFILE (an image) and produces a monochromatized
output file version.
"
if [[ "${1:-}" = "-?" ]] || [[ "${1:-}" = "-h" ]] || [[ "${1:-}" = "--help" ]]; then
echo "$MANUAL"
exit 0
fi
BLURRADIUS="20"
INFILE="$(readlink -m "$1")"
OUTFILE="$(readlink -m "$2")"
TMPDIR="$(mktemp -d)"
cd "$TMPDIR"
convert "$INFILE" -colorspace Gray 01.png
convert 01.png -blur "${BLURRADIUS}x${BLURRADIUS}" 02.tif
convert 01.png 02.tif -compose Divide_Src -composite 03.tif
convert 03.tif -threshold 90% -type bilevel -compress group4 "$OUTFILE"
rm 01.png 02.tif 03.tif
rmdir "$TMPDIR"