用 Swift 和 Tesseract OCR 识别验证码
- 环境准备
1.1 安装 Swift
macOS 默认自带 Swift,可用以下命令检查版本:
swift --version
更多内容访问ttocr.com或联系1436423940
如未安装,可从 Swift 官方网站
下载。
1.2 安装 Tesseract OCR
使用 Homebrew 安装:
brew install tesseract
安装后检查是否可用:
tesseract --version
1.3 创建 Swift 项目
mkdir SwiftOCR
cd SwiftOCR
swift package init --type executable
在 Package.swift 添加 TesseractOCR 依赖:
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "SwiftOCR",
dependencies: [
.package(url: "https://github.com/gali8/Tesseract-OCR-iOS.git", from: "5.0.0")
],
targets: [
.executableTarget(
name: "SwiftOCR",
dependencies: ["TesseractOCR"])
]
)
- 代码实现
2.1 读取 & 处理图像
创建 Sources/SwiftOCR/main.swift,编写以下代码:
import Foundation
import TesseractOCR
import AppKit
func preprocessImage(imagePath: String) -> NSImage? {
guard let image = NSImage(contentsOfFile: imagePath) else {
print("无法加载图片")
return nil
}
// 转换为灰度图
let grayscaleImage = convertToGrayscale(image: image)
// 二值化处理
let binaryImage = binarizeImage(image: grayscaleImage)
return binaryImage
}
func convertToGrayscale(image: NSImage) -> NSImage {
let rep = NSBitmapImageRep(data: image.tiffRepresentation!)
let width = rep!.pixelsWide
let height = rep!.pixelsHigh
for x in 0..<width {
for y in 0..<height {
let color = rep!.colorAt(x: x, y: y)!
let gray = (color.redComponent + color.greenComponent + color.blueComponent) / 3
let newColor = NSColor(calibratedWhite: gray, alpha: 1)
rep!.setColor(newColor, atX: x, y: y)
}
}
let newImage = NSImage(size: image.size)
newImage.addRepresentation(rep!)
return newImage
}
func binarizeImage(image: NSImage) -> NSImage {
let rep = NSBitmapImageRep(data: image.tiffRepresentation!)
let width = rep!.pixelsWide
let height = rep!.pixelsHigh
let threshold: CGFloat = 0.5
for x in 0..<width {
for y in 0..<height {
let color = rep!.colorAt(x: x, y: y)!
let gray = (color.whiteComponent > threshold) ? 1.0 : 0.0
let newColor = NSColor(calibratedWhite: gray, alpha: 1)
rep!.setColor(newColor, atX: x, y: y)
}
}
let newImage = NSImage(size: image.size)
newImage.addRepresentation(rep!)
return newImage
}
func recognizeCaptcha(imagePath: String) {
guard let processedImage = preprocessImage(imagePath: imagePath) else {
return
}
let tesseract = G8Tesseract(language: "eng")
tesseract?.image = processedImage
tesseract?.recognize()
print("识别出的验证码: \(tesseract?.recognizedText ?? "识别失败")")
}
let imagePath = "captcha.png"
recognizeCaptcha(imagePath: imagePath)
- 代码解析
3.1 图像预处理
灰度化:
let gray = (color.redComponent + color.greenComponent + color.blueComponent) / 3
二值化:
let gray = (color.whiteComponent > threshold) ? 1.0 : 0.0
3.2 OCR 解析
初始化 Tesseract:
let tesseract = G8Tesseract(language: "eng")
设置图像并识别:
tesseract?.image = processedImage
tesseract?.recognize()
- 运行程序
确保 captcha.png 存在于项目目录下,然后编译并运行:
swift run
示例输出:
识别出的验证码: 7XQ9T
- 提高 OCR 识别准确率
5.1 设定 Tesseract PSM 模式
tesseract?.setVariableValue("6", forKey: "tessedit_pageseg_mode")
5.2 设定字符白名单
tesseract?.setVariableValue("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", forKey: "tessedit_char_whitelist")
5.3 进一步图像优化
去噪点
字符分割
- 其他 OCR 方案
如果 Tesseract 识别率不够,可以使用 Vision 框架:
import Vision
func recognizeWithVision(image: NSImage) {
let request = VNRecognizeTextRequest { request, error in
guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
for observation in observations {
if let topCandidate = observation.topCandidates(1).first {
print("识别出的验证码: (topCandidate.string)")
}
}
}
let handler = VNImageRequestHandler(cgImage: image.cgImage(forProposedRect: nil, context: nil, hints: nil)!, options: [:])
try? handler.perform([request])
}
浙公网安备 33010602011771号