使用 Swift 结合 Tesseract OCR 进行验证码识别
- 环境准备
1.1 安装 Xcode 和 Swift
确保你已经安装了 Xcode 和 Swift,在终端运行以下命令检查:
bash
swift --version
如果尚未安装,可以通过 Mac App Store 下载最新版本的 Xcode,并在 Xcode 内安装命令行工具。
1.2 安装 Tesseract OCR
使用 Homebrew 安装 Tesseract:
bash
brew install tesseract
安装完成后,运行以下命令检查:
bash
tesseract --version
1.3 创建 Swift 项目
创建一个 Swift 命令行应用:
bash
mkdir SwiftOCR
cd SwiftOCR
swift package init --type executable
1.4 添加依赖
使用 Swift Package Manager(SPM) 添加 Tesseract 的 Swift 绑定: 在 Package.swift 中添加:
swift
dependencies: [
.package(url: "https://github.com/gali8/Tesseract-OCR-iOS.git", from: "4.0.0")
],
targets: [
.target(
name: "SwiftOCR",
dependencies: ["Tesseract-OCR-iOS"]
)
]
然后运行:
bash
swift build
2. 代码实现:识别验证码
在 Sources/SwiftOCR/main.swift 中编写以下代码:
swift
import Foundation
import TesseractOCR
import AppKit
// 预处理图像:灰度 & 二值化
func preprocessImage(_ imagePath: String) -> NSImage? {
guard let image = NSImage(contentsOfFile: imagePath) else {
print("无法加载图片")
return nil
}
// 转换为灰度图像
let grayImage = convertToGrayscale(image)
// 二值化(黑白化)
let binaryImage = applyThreshold(grayImage, threshold: 128)
return binaryImage
}
// 灰度转换
func convertToGrayscale(_ image: NSImage) -> NSImage {
let ciImage = CIImage(data: image.tiffRepresentation!)
let grayscale = ciImage?.applyingFilter("CIColorControls", parameters: [kCIInputSaturationKey: 0])
let rep = NSBitmapImageRep(ciImage: grayscale!)
let pngData = rep.representation(using: .png, properties: [:])
return NSImage(data: pngData!)!
}
// 二值化处理
func applyThreshold(_ image: NSImage, threshold: CGFloat) -> NSImage {
let ciImage = CIImage(data: image.tiffRepresentation!)
let filter = CIFilter(name: "CIColorMatrix", parameters: [
"inputRVector": CIVector(x: 0, y: 0, z: 0, w: 0),
"inputGVector": CIVector(x: 0, y: 0, z: 0, w: 0),
"inputBVector": CIVector(x: 0, y: 0, z: 0, w: 0),
"inputAVector": CIVector(x: 0, y: 0, z: 0, w: 1),
"inputBiasVector": CIVector(x: threshold / 255.0, y: threshold / 255.0, z: threshold / 255.0, w: 0)
])
filter?.setValue(ciImage, forKey: kCIInputImageKey)
let outputCIImage = filter?.outputImage
let rep = NSBitmapImageRep(ciImage: outputCIImage!)
let pngData = rep.representation(using: .png, properties: [:])
return NSImage(data: pngData!)!
}
// OCR 识别验证码
func recognizeCaptcha(imagePath: String) {
guard let preprocessedImage = preprocessImage(imagePath) else {
print("图像预处理失败")
return
}
guard let tesseract = G8Tesseract(language: "eng") else {
print("无法初始化 Tesseract")
return
}
tesseract.image = preprocessedImage
tesseract.recognize()
let recognizedText = tesseract.recognizedText ?? "识别失败"
print("识别出的验证码: \(recognizedText.trimmingCharacters(in: .whitespacesAndNewlines))")
}
// 运行 OCR 识别
let captchaPath = "captcha.png" // 确保图片路径正确
recognizeCaptcha(imagePath: captchaPath)
3. 代码解析
3.1 图像预处理
为了提高 OCR 识别率,我们对图像进行了处理:
灰度化:使用 CoreImage 过滤颜色
二值化:调整阈值增强对比度
swift
let grayscale = ciImage?.applyingFilter("CIColorControls", parameters: [kCIInputSaturationKey: 0])
3.2 OCR 解析
使用 TesseractOCR 进行文本识别:
swift
let tesseract = G8Tesseract(language: "eng")
tesseract.image = preprocessedImage
tesseract.recognize()
G8Tesseract(language: "eng") 创建 OCR 客户端
recognize() 执行 OCR 识别
4. 运行程序
确保 captcha.png 存在于项目目录下,然后运行:
bash
swift run
示例输出:
makefile
识别出的验证码: X9T7A
5. 提高 OCR 识别准确率
5.1 选择合适的 Tesseract PSM 模式
Tesseract 提供了不同的页面分割模式(PSM)。对于验证码,推荐使用 PSM 6(假设单行文本):
swift
tesseract.setVariable("tessedit_pageseg_mode", value: "6")
5.2 设定字符白名单
如果验证码仅包含数字和大写字母,可以限制识别范围:
swift
tesseract.setVariable("tessedit_char_whitelist", value: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
5.3 进一步优化图像
可以尝试:
高斯模糊 过滤背景噪声
形态学变换 处理粘连字符
6. 其他 OCR 方案
如果 Tesseract 不能满足需求,可以使用 Swift + 机器学习 方案:
Vision API(苹果官方 OCR)
Core ML OCR
Google ML Kit OCR
示例:
swift
import Vision
let request = VNRecognizeTextRequest { request, error in
if let observations = request.results as? [VNRecognizedTextObservation] {
let text = observations.compactMap { $0.topCandidates(1).first?.string }.joined(separator: " ")
print("OCR 识别结果: (text)")
}
}
Vision API 在 iOS/macOS 上运行更高效,适用于复杂验证码识别。
浙公网安备 33010602011771号