【问题标题】:Is there a way to make a document image vertical from any position?有没有办法使文档图像从任何位置垂直?
【发布时间】:2020-02-29 05:52:11
【问题描述】:

我有这样的文件:

在某些情况下,图像会向右旋转,甚至上下颠倒。

文档示例向右旋转:

文档示例倒置:

有没有办法使图像垂直,无论起始位置如何?

预期结果:

【问题讨论】:

    标签: python python-3.x image opencv image-processing


    【解决方案1】:

    如您的示例中所示,处理典型(矩形)paper sizes 和从左到右的定向文本,可以做出以下两个假设:

    • 纸张高度必须始终大于纸张宽度。这很容易检查。如果需要,旋转 90 度。
    • 左侧的文本比右侧的多。因此,对所有行的像素值求和。文档左侧区域的总和值必须大于右侧区域的总和值。如果需要,旋转 180 度。

    这是我使用的代码:

    import cv2
    import numpy as np
    from skimage import io              # Only needed for web grabbing images; for local images, use cv2.imread(...)
    
    def correct_orientation(img):
    
        print('\nImage:\n------')
    
        h, w = img.shape
        if (w > h):
            img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
            h, w = img.shape
            print('\nRotated 90 degrees')
    
        summed = np.sum(255-img, axis=0)
    
        if (np.sum(summed[30:130]) < np.sum(summed[w-130:w-30])):
            img = cv2.rotate(img, cv2.ROTATE_180)
            print('\nRotated 180 degrees')
    
        return img
    
    correct_1 = io.imread('https://i.imgur.com/Gu8uAp6.jpg', as_gray=True)
    rot_90 = io.imread('https://i.imgur.com/o97vu59.jpg', as_gray=True)
    rot_180 = io.imread('https://i.imgur.com/XkBNfEb.jpg', as_gray=True)
    correct_2 = io.imread('https://i.imgur.com/EvaioRS.jpg', as_gray=True)
    
    images = [correct_orientation(img) for img in [correct_1, rot_90, rot_180, correct_2]]
    

    给定图像的输出:

    Image:
    ------
    
    Image:
    ------
    
    Rotated 90 degrees
    
    Rotated 180 degrees
    
    Image:
    ------
    
    Rotated 180 degrees
    
    Image:
    ------
    

    在您的图像中,文档有额外的边框(蓝色或黑色)。这使得找到线条的开头和结尾变得困难。因此,调整左右区域的手动设置值应该在最终解决方案中进行调整。

    希望有帮助!

    编辑:忘记了以下可视化。对于方向正确的文档,所有行的总和值如下所示:

    查看左侧较大的值,这些是行的开头。

    180 度旋转后的文档看起来像这样:

    再次注意,由于额外的图像边框,边框上的“伪影”。

    【讨论】:

      【解决方案2】:

      我认为您违反了 EXIF 存储方向的能力,一些观众忽略了这一点。最简单的方法是使用 ImageMagick,它包含在大多数 Linux 发行版中,可用于 macOS 和 Windows。在终端中使用此命令,或在 Windows 上使用命令提示符,将首先纠正方向,然后删除设置,以免混淆查看者:

      magick input.jpg -auto-orient -strip result.jpg
      

      如果使用 v6 ImageMagick,请将 magick 替换为 convert


      如果不这样做,您可以通过每次将图像旋转 90 度来遍历四个可能的方向。在每个方向,通过pytesseract 运行图像并选择与/usr/share/dict/words.txt 或系统上调用的任何内容最匹配的方向。为了增加乐趣和性能,将测试变成一个函数并在 4 个单独的线程上并行调用它 - 每个方向一个。

      这可能看起来像这样:

      #!/usr/bin/env python3
      
      import numpy as np
      import pytesseract
      import cv2
      import re
      from textblob import TextBlob
      
      def analyse(im, rotation):
         text = pytesseract.image_to_string(im, config="--psm 4")
         correctedText = TextBlob(text).correct()
         legit = []
         for found in correctedText.split():
            if found in words:
                legit.append(found)
         print(f"Rotation: {rotation}, word count: {len(legit)}, words: {legit}")
      
      # Load dictionary of permissible words
      words = set()
      with open('/usr/share/dict/words') as f:
          for line in f:
              # Don't add short words like "at", tesseract often finds small, easily matched strings
              if len(line) > 5:
                  words.add(line.rstrip())
      
      # Load document
      orig = cv2.imread('document.png',cv2.IMREAD_GRAYSCALE)
      h, w = orig.shape
      centre = (w//2, h//2)
      
      # Iterate through orientations
      
      # Original, no rotation
      r = 0
      cv2.imwrite(f'rotated-{r}.png',orig)
      analyse(orig,0)
      
      # 90 degrees
      r = 90
      rotated = cv2.rotate(orig, cv2.ROTATE_90_CLOCKWISE) 
      cv2.imwrite(f'rotated-{r}.png',rotated)
      analyse(rotated,r)
      
      # 180 degrees
      r = 180
      rotated = cv2.rotate(orig, cv2.ROTATE_180) 
      cv2.imwrite(f'rotated-{r}.png',rotated)
      analyse(rotated,r)
      
      # 270 degrees
      r = 270
      rotated = cv2.rotate(orig, cv2.ROTATE_90_COUNTERCLOCKWISE) 
      cv2.imwrite(f'rotated-{r}.png',rotated)
      analyse(rotated,r)
      

      样本输出

      Rotation: 0, word count: 43, words: ['between', 'Secession', 'deserted', 'above', 'noted', 'hereby', 'release', 'other', 'money', 'above', 'together', 'action', 'party', 'against', 'other', 'patty', 'holding', 'depart', 'Canada', 'refund', 'cashier', 'cheque', 'shall', 'their', 'irrevocable', 'author', 'hereby', 'commission', 'regeneration', 'above', 'except', 'hereinbefore', 'shall', 'binding', 'whereof', 'hereunto', 'presence', 'whereof', 'hereunto', 'presence', 'whereof', 'hereunto', 'presence']
      
      Rotation: 90, word count: 0, words: []
      
      Rotation: 180, word count: 10, words: ['saliva', 'sense', 'sleeping', 'anode', 'alone', 'sappy', 'sleeping', 'young', 'sawing', 'Utopian']
      
      Rotation: 270, word count: 0, words: []
      

      如您所见,它在第一个未旋转的图像中找到了更多的单词。

      关键字:Python、tesseract、pytesseract、OCR、psm、配置、图像、图像处理、定向、自动定向、自动定向。

      【讨论】:

      • 我曾尝试使用它,但如前所述,我需要所有文档的方向元数据。泰,我投了赞成票。还有其他人吗?
      • 我添加了一个新想法...请再看看。
      • AMAZING 答案,也为我工作。有点费时,但有效
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2021-09-19
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-18
      相关资源
      最近更新 更多