批量处理文档图像,使其看起来像传真件

批量处理文档图像,使其看起来像传真件

假设我有一张文本文档的照片或扫描件,可能带有一些低对比度的水印背景。如果是照片,除了水印外​​,还会有来自灯光的亮度梯度,也可能是来自纸张因折叠而未平整。

我想用 imagemagick 对这些照片进行后期处理,使其看起来像传真,即将图像转换为单色黑/白,校正局部亮度变化。常规-threshold选项不起作用,因为

  1. 它不会自动检测每张照片所需的亮度级别。
  2. 由于亮度梯度,图像某一部分的文本可能比另一部分的背景更亮,因此对于任何给定的全局阈值,一些文本将会丢失。

智能手机上的 Cam-Scanner 应用程序通常提供黑白文档选项,可以校正这种颜色渐变并计算出阈值的合理初步猜测,这对于批处理来说已经足够了。

虽然理论上我可以将它们上传到智能手机并导入,但当我已经在 PC 上拥有原始图像时,它们却没有帮助——但这非常不切实际,尤其是对于大量图像而言。

imagemagick 或其他一些具有批处理功能的软件(最好是开源的)是否支持这种转换?

答案1

您可以使用 Imagemagick 的数学合成方法来获得这样的结果。Divide_src[1] 特别是因为它可以消除任何渐变、晕影和不需要的阴影。

然后 a-normalize和 a-threshold应该完成剩下的工作。

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

这是我的结果:

您可能需要调整阈值以获得最佳结果。

根据您要运行的操作系统,您可能必须转义括号:“\(”和“\)”。

至于批处理,我个人会根据操作系统在 bash 或 Cygwin 中使用“for”循环:

对于测试/*中的文件;执行转换$file-colorspace gray(+clone-blur 15,15)-compose Divide_Src-composite-normalize-threshold 80%结果/`basename $file`;完成

但是,您可能想要查看另一个名为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]

根据我的 matthewd 的回答,我编写了脚本,用于自动执行具有合理对比度的扫描过程。这些脚本使用了 poppler 的pdfimages、ImageMagick 的convertpdftk

imagemagick-scan-pdf-to-mono.sh(取决于第二个脚本;输出可能会旋转,可以通过运行 来修复。可以使用而不是 来pdftk FILE.pdf cat 1-endW output OUT.pdf更改旋转方向)1-endE1-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"

相关内容