将PDF转换为PNG以便Tesseract处理

时间:2018-04-07 20:04:18

标签: php imagemagick tesseract

我目前在使用Imagemagick和Tesseract时遇到了问题。

我正在使用PHP的文档命令行分类器。这个想法是它接收PDF文档并使用League Pipeline package通过许多步骤。我已经确定的必要步骤如下:

  1. 将PDF转换为PNG文件
  2. 从PNG文件中提取文字
  3. 通过机器学习库运行文本以对其进行分类
  4. 主要命令如下:

    <?php
    
    namespace Matthewbdaly\LetterClassifier\Commands;
    
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    use Symfony\Component\Console\Input\InputArgument;
    use League\Pipeline\Pipeline;
    use Matthewbdaly\LetterClassifier\Stages\ConvertPdfToPng;
    use Matthewbdaly\LetterClassifier\Stages\ReadFile;
    
    class Processor extends Command
    {
        protected function configure()
        {
            $this->setName('process')
                ->setDescription('Processes a file')
                ->setHelp('This command processes a file')
                ->addArgument('file', InputArgument::REQUIRED, 'File to process');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $file = $input->getArgument('file');
            $pipeline = (new Pipeline)
                ->pipe(new ConvertPdfToPng)
                ->pipe(new ReadFile);
            $pipeline->process($file);
        }
    }
    

    如您所见,它接受文件名作为第一个参数,然后在将文件传递给管道之前为所需步骤定义管道。

    转换PDF的步骤如下所示:

    <?php
    
    namespace Matthewbdaly\LetterClassifier\Stages;
    
    use Imagick;
    
    class ConvertPdfToPng
    {
        public function __invoke($file)
        {
            $tmp = tmpfile();
            $uri = stream_get_meta_data($tmp)['uri'];
            $img = new Imagick($file);
            $img->setResolution(300, 300);
            $img->setImageDepth(8);
            $img->setImageFormat('png');
            $img->writeImage($uri);
            return $tmp;
        }
    }
    

    它将PDF的PNG版本写为临时文件。生成的文件看起来还不错,至少在我看来,但Tesseract无法正确读取。这是Tesseract处理文件的第二步:

    <?php
    
    namespace Matthewbdaly\LetterClassifier\Stages;
    
    use thiagoalessio\TesseractOCR\TesseractOCR;
    
    class ReadFile
    {
    
        public function __invoke($file)
        {
            $uri = stream_get_meta_data($file)['uri'];
            $ocr = new TesseractOCR($uri);
            $output = $ocr->lang('eng')->run();
            eval(\Psy\Sh());
        }
    }
    

    Psysh的输出如下:

    => """
       Am sum\n
       \n
       mm“ m mun SuHrkw-l\n
       n m 51mm\n
       \n
       mm\n
       \n
       um um\n
       \n
       ms Murine\n
       1 Elm: 51mm\n
       Emnuumn\n
       \n
       a mu\n
       \n
       m Mm 2m-\n
       Dav st-n-m.\n
       \n
       P‘Eualanfl ma lumnflarvlmamrmy ”Hay ”mum-m-\n
       we we “mum-m n: "mum,“ m mun\n
       \n
       vm [harem\n
       \n
       Am smrm
       """
    

    这不是我尝试分类的字母的内容 - 文字正在被破坏。如果我从shell运行以下命令,它们按预期工作,将字母的文本转换并写入输出文件:

    convert -density 300 Quote.pdf output.png
    tesseract output.png output
    

    如果我将Tesseract阶段中文件的路径硬编码为指向使用output.png命令生成的convert,则可行。因此,我非常有信心问题是生成PNG文件的步骤。我没有使用Imagemagick的经验,所以我不确定为什么文件无法处理,但似乎有某种我不知道的设置

    任何人都可以提出问题所在吗?

1 个答案:

答案 0 :(得分:1)

我怀疑问题在于,在致电setResolution()之前,Imagick会阅读PDF。

尝试实例化一个空的IMagick对象,设置解析然后读取文件:

$img = new Imagick();
$img->setResolution(300, 300);
$img->readImage($file);