有没有一种方法可以使文档图像从任何位置垂直放置?

时间:2019-11-03 20:53:53

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

我有这样的文件:

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

文档示例向右旋转:

文档示例上下颠倒旋转:

是否有一种方法可以使图像垂直,无论起始位置是什么?

预期结果:

2 个答案:

答案 0 :(得分: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,配置,图像,图像处理,方向,自动定向,自动定向。

答案 1 :(得分:2)

处理示例中所示的典型(矩形)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:
------

在图像中,文档带有其他边框(蓝色或黑色)。这使得很难找到行的开始和结束。因此,在最终解决方案中应调整左侧和右侧区域的手动设置值。

希望有帮助!

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

Correct

在左侧看到较大的值,这些是线条的起点。

180度旋转文档的外观如下所示:

Not correct

同样,由于额外的图像边框,请注意边框上的“伪像”。