使用 Python 和 OpenCV 改善图像偏移
Improving image deskew using Python and OpenCV
我生成的用于检测和纠正偏斜的代码给出了不一致的结果。我目前正在开展一个项目,该项目利用图像上的 OCR 文本提取(通过 Python 和 OpenCV),因此如果需要准确的结果,消除倾斜是关键。我的代码使用 cv2.minAreaRect
来检测偏斜。
我使用的图像完全相同(将来也会如此),所以我不确定是什么导致了这些不一致。我在应用我的代码的地方包含了两组前后图像(包括来自 cv2.minAreaRect
的偏斜值),一组显示成功去除偏斜并显示偏斜未被去除(看起来它增加了更多偏斜) .
图像 1 之前 (-87.88721466064453
)
Image 1 After (成功去歪斜)
图像 2 之前 (-5.766754150390625
)
Image 2 After(去歪斜不成功)
我的代码如下。注意:我处理过的图像比我在这里包含的图像多得多。到目前为止检测到的偏斜一直在 [-10, 0) 或 (-90, -80] 范围内,所以我试图在我的代码中考虑到这一点。
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gray = cv2.bitwise_not(img_gray)
thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
coords = np.column_stack(np.where(thresh > 0))
angle = cv2.minAreaRect(coords)[-1]
if (angle < 0 and angle >= -10):
angle = -angle #this was intended to undo skew for values in [-10, 0) by simply rotating using the opposite sign
else:
angle = (90 + angle)/2
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
deskewed = cv2.warpAffine(img, M, (w, h), flags = cv2.INTER_CUBIC, borderMode = cv2.BORDER_REPLICATE)
我浏览了各种帖子和文章以找到合适的解决方案,但没有成功。 This post 对理解偏斜值最有帮助,但即便如此我也无法深入了解。
可以在Python Wand 中找到一个非常好的文本歪斜校正工具,它使用ImageMagick。它基于 Radon 变换。
表格 1:
表格 2:
from wand.image import Image
from wand.display import display
with Image(filename='form1.png') as img:
img.deskew(0.4*img.quantum_range)
img.save(filename='form1_deskew.png')
display(img)
with Image(filename='form2.png') as img:
img.deskew(0.4*img.quantum_range)
img.save(filename='form2_deskew.png')
display(img)
表格 1 校正:
表格 2 校正:
我已经在这里回答了这个问题:
以下是可以帮助您校正图像的一段代码:
import numpy as np
from skimage import io
from skimage.transform import rotate
from skimage.color import rgb2gray
from deskew import determine_skew
from matplotlib import pyplot as plt
def deskew(_img):
image = io.imread(_img)
grayscale = rgb2gray(image)
angle = determine_skew(grayscale)
rotated = rotate(image, angle, resize=True) * 255
return rotated.astype(np.uint8)
def display_before_after(_original):
plt.subplot(1, 2, 1)
plt.imshow(io.imread(_original))
plt.subplot(1, 2, 2)
plt.imshow(deskew(_original))
display_before_after('img_35h.jpg')
之前:
之后:
我生成的用于检测和纠正偏斜的代码给出了不一致的结果。我目前正在开展一个项目,该项目利用图像上的 OCR 文本提取(通过 Python 和 OpenCV),因此如果需要准确的结果,消除倾斜是关键。我的代码使用 cv2.minAreaRect
来检测偏斜。
我使用的图像完全相同(将来也会如此),所以我不确定是什么导致了这些不一致。我在应用我的代码的地方包含了两组前后图像(包括来自 cv2.minAreaRect
的偏斜值),一组显示成功去除偏斜并显示偏斜未被去除(看起来它增加了更多偏斜) .
图像 1 之前 (-87.88721466064453
)
Image 1 After (成功去歪斜)
图像 2 之前 (-5.766754150390625
)
Image 2 After(去歪斜不成功)
我的代码如下。注意:我处理过的图像比我在这里包含的图像多得多。到目前为止检测到的偏斜一直在 [-10, 0) 或 (-90, -80] 范围内,所以我试图在我的代码中考虑到这一点。
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gray = cv2.bitwise_not(img_gray)
thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
coords = np.column_stack(np.where(thresh > 0))
angle = cv2.minAreaRect(coords)[-1]
if (angle < 0 and angle >= -10):
angle = -angle #this was intended to undo skew for values in [-10, 0) by simply rotating using the opposite sign
else:
angle = (90 + angle)/2
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
deskewed = cv2.warpAffine(img, M, (w, h), flags = cv2.INTER_CUBIC, borderMode = cv2.BORDER_REPLICATE)
我浏览了各种帖子和文章以找到合适的解决方案,但没有成功。 This post 对理解偏斜值最有帮助,但即便如此我也无法深入了解。
可以在Python Wand 中找到一个非常好的文本歪斜校正工具,它使用ImageMagick。它基于 Radon 变换。
表格 1:
表格 2:
from wand.image import Image
from wand.display import display
with Image(filename='form1.png') as img:
img.deskew(0.4*img.quantum_range)
img.save(filename='form1_deskew.png')
display(img)
with Image(filename='form2.png') as img:
img.deskew(0.4*img.quantum_range)
img.save(filename='form2_deskew.png')
display(img)
表格 1 校正:
表格 2 校正:
我已经在这里回答了这个问题:
以下是可以帮助您校正图像的一段代码:
import numpy as np
from skimage import io
from skimage.transform import rotate
from skimage.color import rgb2gray
from deskew import determine_skew
from matplotlib import pyplot as plt
def deskew(_img):
image = io.imread(_img)
grayscale = rgb2gray(image)
angle = determine_skew(grayscale)
rotated = rotate(image, angle, resize=True) * 255
return rotated.astype(np.uint8)
def display_before_after(_original):
plt.subplot(1, 2, 1)
plt.imshow(io.imread(_original))
plt.subplot(1, 2, 2)
plt.imshow(deskew(_original))
display_before_after('img_35h.jpg')
之前:
之后: