图片文本矫正:让歪斜的文字“正”回来

为什么需要图片文本矫正?

在拍摄文档、名片或黑板时,受拍摄角度影响,文字常出现倾斜、透视变形。这种变形的文本会严重降低OCR(光学字符识别)的准确率。图片文本矫正是将变形的文本通过图像处理技术恢复为正视平面,是OCR预处理的关键步骤。

核心算法原理

1. 透视变换 (Perspective Transform)

最经典的矫正方法基于四点变换。通过检测文档的四个角点(或四边形边界),计算变换矩阵,将图像投影到一个矩形区域。常用方法包括:

  • 霍夫变换检测直线:找到文档边缘的直线,通过直线交点估算角点。
  • Contour 检测:对二值化图像进行轮廓提取,筛选最大的四边形轮廓。
OpenCV 提供了 cv2.getPerspectiveTransform 和 cv2.warpPerspective 实现。

2. 文本行矫正与倾斜校正

对于仅有旋转倾斜的文本(没有透视畸变),可通过计算文本行倾斜角进行旋转校正。方法包括:

  • 投影法:在多个角度投影,选择投影方差最大的角度。
  • 霍夫变换:检测直线角度取平均。

3. 基于深度学习的端到端矫正

近年来,CNN 和 Spatial Transformer Network (STN) 被用于直接回归矫正参数。例如,将扭曲文本图像输入网络,输出矫正后的图像。这类方法对复杂场景(如弯曲页面、不规则变形)更鲁棒。

实战:基于 OpenCV 的矫正流程

import cv2
import numpy as np

# 读取图像
img = cv2.imread('doc.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)

# 检测轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)

# 近似多边形
peri = cv2.arcLength(contours[0], True)
approx = cv2.approxPolyDP(contours[0], 0.02 * peri, True)

if len(approx) == 4:
    pts = approx.reshape(4, 2)
    # 定义目标矩形形状
    rect = np.array([[0, 0], [800, 0], [800, 1000], [0, 1000]], dtype='float32')
    M = cv2.getPerspectiveTransform(pts.astype('float32'), rect)
    warped = cv2.warpPerspective(img, M, (800, 1000))
    cv2.imshow('Corrected', warped)
    cv2.waitKey(0)

应用场景

  • 文档扫描:手机拍照扫描件自动矫正。
  • 车牌识别:倾斜车牌文字矫正后识别率提升。
  • 场景文本:自然场景中广告牌、指示牌文字的预处理。

挑战与趋势

传统方法依赖文档边界清晰,而深度学习方案需要大量标注数据。未来,轻量级网络(如MobileNet+STN)有望在移动端实现实时矫正,结合语义分割进一步提升对任意形状变形的鲁棒性。