为了进一步防止自动化程序,很多验证码会在字符上加入波浪形扭曲或旋转变形。这种验证码的难点在于:字符形状被严重改变,传统 OCR 在未经校正的情况下几乎无法识别。本文将介绍一种基于几何校正与投影分析的识别流程。
一、问题分析
更多内容访问ttocr.com或联系1436423940
扭曲验证码的主要特征:
字符整体呈波浪形弯曲,笔画不再直立;
单个字符可能有旋转或缩放;
简单二值化无法恢复原始形态。
解决思路:
通过边缘检测或二值化获得字符轮廓;
分析字符的轮廓几何特征,估算倾斜或扭曲参数;
使用仿射变换或透视变换对图像进行校正;
将校正后的字符图像送入 OCR 识别。
二、实现步骤(Python 示例)
-
导入依赖
import cv2
import numpy as np
import pytesseract -
读取与二值化
img = cv2.imread("captcha_warp.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY_INV)
cv2.imwrite("step1_binary.png", binary)
- 轮廓检测与最小外接矩形
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
rect = cv2.minAreaRect(cnt)
angle = rect[-1]
if angle < -45:
angle += 90
# 仿射旋转校正
h, w = binary.shape
M = cv2.getRotationMatrix2D((w//2, h//2), angle, 1)
rotated = cv2.warpAffine(binary, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
cv2.imwrite("step2_rotated.png", rotated)
- 水平扭曲校正(透视变换)
假设验证码呈现水平波浪,可以通过形态学膨胀找到文本区域边界
coords = np.column_stack(np.where(rotated > 0))
x, y, w, h = cv2.boundingRect(coords)
roi = rotated[y:y+h, x:x+w]
将区域拉伸为固定高度
corrected = cv2.resize(roi, (w, h))
cv2.imwrite("step3_corrected.png", corrected)
- OCR 识别
text = pytesseract.image_to_string(corrected, config="--psm 7")
print("识别结果:", text.strip())