来自PDF的高分辨率图像

来自PDF的高分辨率图像,pdf,imagemagick,image-manipulation,tiff,Pdf,Imagemagick,Image Manipulation,Tiff,我正在做一个项目,我需要从多页PDF中提取每页的TIFF。PDF仅包含图像,每页只有一张图像(我相信它们是在某种复印机/扫描仪上制作的,但尚未确认这一点)。然后使用TIFF创建文档的其他几个衍生版本,因此分辨率越高越好 我发现了两个食谱,都有帮助的方面,但都不理想。希望有人能帮我调一个,或者提供第三个选择 配方1,PDF图像和ImageMagick: 首先要做: $ pdfimages $MY_PDF.pdf foo" 这会产生几个.pbm文件(名为foo-000.pbm,foo-001.pb

我正在做一个项目,我需要从多页PDF中提取每页的TIFF。PDF仅包含图像,每页只有一张图像(我相信它们是在某种复印机/扫描仪上制作的,但尚未确认这一点)。然后使用TIFF创建文档的其他几个衍生版本,因此分辨率越高越好

我发现了两个食谱,都有帮助的方面,但都不理想。希望有人能帮我调一个,或者提供第三个选择

配方1,PDF图像和ImageMagick:

首先要做:

$ pdfimages $MY_PDF.pdf foo"
这会产生几个
.pbm
文件(名为
foo-000.pbm
foo-001.pbm
),等等

然后针对每个
*.pbm
执行以下操作:

$ convert $each -resize 3200x3200\> -quality 100 $new_name.tif
赞成:最终的TIFF是一个健康的3300多像素的长尺寸,(-resize只是用来规范一切)

缺点:页面的方向丢失了,它们会旋转到不同的方向(它们遵循逻辑模式,所以可能就是它们被送入扫描仪的方向??)

配方2Imagemagick solo:

convert +adjoin $MY_PDF.pdf pages.tif
这为我提供了每页的TIFF(
pages-0.tif
pages-1.tif
,等等)

赞成者:方向保持不变

缺点:结果文件的长维度<800 px,太小了,没有用处,看起来好像应用了一些压缩


如何放弃PDF中图像流的缩放,但保留方向?在ImageMagick中还有我没有的魔法吗?完全是别的吗?

我想分享我的解决方案……它可能不适用于所有人,但既然没有其他办法,也许它会帮助其他人。最后,我选择了我问题中的第一个选项,那就是使用
pdfimages
来获得向各个方向旋转的大图像。然后,我找到了一种使用OCR和字数来猜测方向的方法,这使我从(估计)25%精确旋转到90%以上

流程如下:

  • 使用
    pdfimages
    (apt get install poppler utils)获取一组pbm 文件(下面未显示)
  • 对于每个文件:
  • 制作四个版本,分别旋转0度、90度、180度和270度(我在代码中称它们为“北”、“东”、“南”和“西”)
  • 光学字符识别。字数最少的两个版本可能是右侧向上和倒置版本。这是超过99%的准确率在我的一套图像处理到目前为止
  • 从字数最少的两个中,通过拼写检查运行OCR输出。拼写错误最少(即最容易识别的单词)的文件可能是正确的。在我的实验组中,基于500个样本,准确率约为93%(高于25%)
  • YMMV。我的文件是双音的,文本性很强。长边上的源图像平均为3300像素。我不能谈论灰度或彩色,或者有很多图像的文件。我的大部分源PDF文件都是旧影印件的不良扫描,因此使用更干净的文件可能会更准确。在旋转过程中使用
    -despeckle
    不会产生任何影响,会大大降低速度(~5×)。我选择ocrad是为了速度,而不是准确性,因为我只需要粗略的数字,我正在扔掉OCR。Re:性能方面,我的没有什么特别的Linux桌面机器可以每秒运行大约2-3个文件的整个脚本

    下面是一个简单bash脚本中的实现:

    #!/bin/bash
    # Rotates a pbm file in place.
    
    # Pass a .pbm as the only arg.
    file=$1
    
    TMP="/tmp/rotation-calc"
    mkdir $TMP
    
    # Dependencies:                                                                 
    # convert: apt-get install imagemagick                                          
    # ocrad: sudo apt-get install ocrad                                               
    ASPELL="/usr/bin/aspell"
    AWK="/usr/bin/awk"
    BASENAME="/usr/bin/basename"
    CONVERT="/usr/bin/convert"
    DIRNAME="/usr/bin/dirname"
    HEAD="/usr/bin/head"
    OCRAD="/usr/bin/ocrad"
    SORT="/usr/bin/sort"
    WC="/usr/bin/wc"
    
    # Make copies in all four orientations (the src file is north; copy it to make 
    # things less confusing)
    file_name=$(basename $file)
    north_file="$TMP/$file_name-north"
    east_file="$TMP/$file_name-east"
    south_file="$TMP/$file_name-south"
    west_file="$TMP/$file_name-west"
    
    cp  $file $north_file
    $CONVERT -rotate 90 $file $east_file
    $CONVERT -rotate 180 $file $south_file
    $CONVERT -rotate 270 $file $west_file
    
    # OCR each (just append ".txt" to the path/name of the image)
    north_text="$north_file.txt"
    east_text="$east_file.txt"
    south_text="$south_file.txt"
    west_text="$west_file.txt"
    
    $OCRAD -f -F utf8 $north_file -o $north_text
    $OCRAD -f -F utf8 $east_file -o $east_text
    $OCRAD -f -F utf8 $south_file -o $south_text
    $OCRAD -f -F utf8 $west_file -o $west_text
    
    # Get the word count for each txt file (least 'words' == least whitespace junk
    # resulting from vertical lines of text that should be horizontal.)
    wc_table="$TMP/wc_table"
    echo "$($WC -w $north_text) $north_file" > $wc_table
    echo "$($WC -w $east_text) $east_file" >> $wc_table
    echo "$($WC -w $south_text) $south_file" >> $wc_table
    echo "$($WC -w $west_text) $west_file" >> $wc_table
    
    # Take the bottom two; these are likely right side up and upside down, but 
    # generally too close to call beyond that.
    bottom_two_wc_table="$TMP/bottom_two_wc_table"
    $SORT -n $wc_table | $HEAD -2 > $bottom_two_wc_table
    
    # Spellcheck. The lowest number of misspelled words is most likely the 
    # correct orientation.
    misspelled_words_table="$TMP/misspelled_words_table"
    while read record; do
        txt=$(echo $record | $AWK '{ print $2 }')
        misspelled_word_count=$(cat $txt | $ASPELL -l en list | wc -w)
        echo "$misspelled_word_count $record" >> $misspelled_words_table
    done < $bottom_two_wc_table
    
    # Do the sort, overwrite the input file, save out the text
    winner=$($SORT -n $misspelled_words_table | $HEAD -1)
    rotated_file=$(echo $winner | $AWK '{ print $4 }')
    
    mv $rotated_file $file
    
    # Clean up.
    if [ -d $TMP ]; then
        rm -r $TMP
    fi
    
    #/bin/bash
    #原地旋转pbm文件。
    #将.pbm作为唯一参数传递。
    文件=$1
    TMP=“/TMP/旋转计算”
    mkdir$TMP
    #依赖项:
    #convert:apt-get-install-imagemagick
    #ocrad:sudo-apt-get-install-ocrad
    ASPELL=“/usr/bin/ASPELL”
    AWK=“/usr/bin/AWK”
    BASENAME=“/usr/bin/BASENAME”
    CONVERT=“/usr/bin/CONVERT”
    DIRNAME=“/usr/bin/DIRNAME”
    HEAD=“/usr/bin/HEAD”
    OCRAD=“/usr/bin/OCRAD”
    SORT=“/usr/bin/SORT”
    WC=“/usr/bin/WC”
    #在所有四个方向上进行复制(src文件为北;复制它以进行复制
    #事情不那么令人困惑)
    文件名=$(basename$文件)
    north_file=“$TMP/$file_name-north”
    east_file=“$TMP/$file_name-east”
    south_file=“$TMP/$file_name-south”
    west_file=“$TMP/$file_name-west”
    cp$文件$north_文件
    $CONVERT-旋转90$文件$east_文件
    $CONVERT-旋转180$文件$south\u文件
    $CONVERT-旋转270$文件$west_文件
    #OCR每个(只需将“.txt”附加到图像的路径/名称)
    north_text=“$north_file.txt”
    east_text=“$east_file.txt”
    south_text=“$south_file.txt”
    west_text=“$west_file.txt”
    $OCRAD-f-f utf8$north\u文件-o$north\u文本
    $OCRAD-f-f utf8$east\u文件-o$east\u文本
    $OCRAD-f-f utf8$south\u文件-o$south\u文本
    $OCRAD-f-f utf8$west\u文件-o$west\u文本
    #获取每个txt文件的字数(最少的“字”==最少的空白垃圾)
    #由应为水平的垂直文本行生成。)
    wc_table=“$TMP/wc_table”
    echo“$($WC-w$north\u text)$north\u file”>$WC\u表
    echo“$($WC-w$east\u text)$east\u file”>>$WC\u表
    echo“$($WC-w$south\u text)$south\u file”>>$WC\u表
    echo“$($WC-w$west_text)$west_file”>>$WC_表
    #以最下面的两个为例;这些可能是正面朝上和颠倒的,但是
    #一般来说,距离太近了,不能再叫了。
    bottom_two_wc_table=“$TMP/bottom_two_wc_table”
    $SORT-n$wc_table |$HEAD-2>$bottom_two_wc_table
    #拼写检查。拼写错误的单词数量最少的可能是
    #方向正确。
    拼写错误的单词表=“$TMP/拼写错误的单词表”
    读取记录时;做
    txt=$(echo$record |$AWK'{print$2}')
    拼写错误的单词计数=$(cat$txt |$ASPELL-l en list | wc-w)
    echo“$misspelled\u words\u count$record”>>$misspelled\u words\u表
    完成<$bottom\u two\u wc\u表格
    #进行排序,覆盖输入文件,保存文本
    获胜者=$($SORT-n$拼写错误的单词|$HEAD-1)
    旋转的_文件=$(echo$winner |$AWK'{print$4}')
    mv$rot