我正在执行一项 OCR 任务,以从多个身份证明文件中提取信息。一个挑战是扫描图像的方向。需要固定 PAN、Aadhaar、驾驶执照或任何身份证明的扫描图像的方向。
已经在 Stackoverflow 和其他论坛上尝试了所有建议的方法,例如 OpenCV minAreaRect、Hough Lines Transforms、FFT、homography、tesseract osd with psm 0。均无效。
最佳答案
这是一种基于大部分文本偏向一侧的假设的方法。这个想法是我们可以根据主要文本区域所在的位置来确定角度
- Load the image , 转换成 grayscale , 和 Gaussian blur
- Adaptive threshold得到二值图像
- Find contours并使用 contour area 进行过滤
- 在蒙版上绘制过滤后的轮廓
- 根据方向水平或垂直分割图像
- 计算每一半的像素数
转换为灰度和高斯模糊后,自适应阈值得到二值图像
从这里我们找到轮廓并使用轮廓区域进行过滤以去除小噪声粒子和大边界。我们将通过此过滤器的任何轮廓绘制到蒙版上
为了确定角度,我们根据图像的尺寸将图像分成两半。如果 width > height
则它必须是水平图像,所以我们垂直分成两半。如果 height > width
那么它必须是垂直图像所以我们水平分成两半
现在我们有两半,我们可以使用 cv2.countNonZero()
来确定每一半的白色像素数量。这是确定角度的逻辑:
if horizontal
if left >= right
degree -> 0
else
degree -> 180
if vertical
if top >= bottom
degree -> 270
else
degree -> 90
left 9703
right 3975
因此图像为0度。这是其他方向的结果
left 3975
right 9703
我们可以得出结论,图像翻转了 180 度
这是垂直图像的结果。请注意,由于它是垂直图像,我们水平分割
top 3947
bottom 9550
因此结果是90度
import cv2
import numpy as np
def detect_angle(image):
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
adaptive = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,15,4)
cnts = cv2.findContours(adaptive, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 45000 and area > 20:
cv2.drawContours(mask, [c], -1, (255,255,255), -1)
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
h, w = mask.shape
# Horizontal
if w > h:
left = mask[0:h, 0:0+w//2]
right = mask[0:h, w//2:]
left_pixels = cv2.countNonZero(left)
right_pixels = cv2.countNonZero(right)
return 0 if left_pixels >= right_pixels else 180
# Vertical
else:
top = mask[0:h//2, 0:w]
bottom = mask[h//2:, 0:w]
top_pixels = cv2.countNonZero(top)
bottom_pixels = cv2.countNonZero(bottom)
return 90 if bottom_pixels >= top_pixels else 270
if __name__ == '__main__':
image = cv2.imread('1.png')
angle = detect_angle(image)
print(angle)
关于python - 根据文本方向检测图像方向角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58010660/