4

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

Я хочу постобработать эти фотографии с помощью imagemagick, чтобы они выглядели как факс, т. Е. Преобразуем изображение в черно-белое изображение, исправляя локальные изменения яркости. Нормальная опция -threshold не будет работать, так как

  1. Он не определяет автоматически необходимый уровень яркости для каждой фотографии.
  2. Из-за градиентов яркости текст на одной части изображения может быть ярче, чем фон на другой части, так что при любом заданном глобальном пороге часть текста будет потеряна.

Приложения Cam-Scanner на смартфонах обычно предоставляют параметр черно-белого документа, который корректирует такие цветовые градиенты и вычисляет разумное первое предположение для порогового значения, которое будет достаточно для пакетной обработки.

Они не помогают, хотя, когда у меня уже есть необработанное изображение на ПК, хотя я теоретически могу загрузить их на смартфон и импортировать их - это очень непрактично, особенно для большого количества изображений.

Поддерживает ли imagemagick или какое-либо другое программное обеспечение с поддержкой пакетной обработки (предпочтительно с открытым исходным кодом) такое преобразование?

2 ответа2

5

Вы можете использовать методы математической компоновки Imagemagick для достижения таких результатов. Divide_src [1], поскольку он удаляет любые градиенты, виньетки, нежелательные штриховки.

Тогда -normalize и -threshold должны делать все остальное.

convert $input -colorspace gray ( +clone -blur 15,15 ) -compose Divide_Src -composite -normalize -threshold 80% $output

Вот мой результат:

Вы можете захотеть установить порог, чтобы получить наилучшие результаты.

В зависимости от ОС, которую вы собираетесь запустить, вам, возможно, придется выйти за скобки: "\(" и "\)".

Что касается пакетной обработки лично, я бы использовал цикл for либо в bash, либо в Cygwin снова, в зависимости от ОС:

for file in test/*; do convert $file -colorspace gray ( +clone -blur 15,15 ) -compose Divide_Src -composite -normalize -threshold 80% result/`basename $file`; done

Однако есть другой инструмент командной строки вы можете проверить под названием mogrify [2] для встроенного или конкретного -path пакетной обработки.

Для получения дополнительной информации и, возможно, других результатов следуйте [3] и [4].


[1]: www.imagemagick.org/Usage/compose/#divide

[2]: www.imagemagick.org/script/mogrify.php

[3]: staff.washington.edu/corey/camscan/

[4]: www.imagemagick.org/Usage/photos/#color-in

2

Обновление Обновленные формы скриптов теперь размещаются в виде гистов [1] [2].

Основываясь на ответе моего отца, я написал сценарии, которые автоматизируют процесс, предназначенный для сканирования с разумным контрастом. Скрипты используют pdfimages pdfimages , convert ImageMagick и 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"

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .