使用 Swift 进行验证码识别:集成 Tesseract OCR

news/2025/10/29 23:29:10/文章来源:https://www.cnblogs.com/ocr12/p/19175607
  1. 环境准备
    1.1 安装 Tesseract OCR
    更多内容访问ttocr.com或联系1436423940
    在 macOS 上可以使用 Homebrew 进行安装:

brew install tesseract

安装完成后,检查 Tesseract 是否安装成功:

tesseract --version

1.2 创建 Swift 项目

如果是 macOS 应用,可以使用 Swift Package Manager (SPM),或者直接在 Xcode 项目中集成 OCR 识别功能。

创建一个新的 Swift 项目:

mkdir SwiftCaptchaOCR
cd SwiftCaptchaOCR
swift package init --type executable

编辑 Package.swift,添加 Tesseract 相关库:

// swift-tools-version:5.5
import PackageDescription

let package = Package(
name: "SwiftCaptchaOCR",
dependencies: [
.package(url: "https://github.com/gali8/Tesseract-OCR-iOS.git", from: "4.0.0")
],
targets: [
.executableTarget(
name: "SwiftCaptchaOCR",
dependencies: ["Tesseract-OCR-iOS"]
)
]
)

然后运行:

swift build

  1. 代码实现

在 Sources/SwiftCaptchaOCR/main.swift 中写入以下代码:

import Foundation
import TesseractOCR
import Cocoa

func preprocessImage(inputPath: String, outputPath: String) {
guard let image = NSImage(contentsOfFile: inputPath) else {
print("无法加载图片")
return
}

// 转换为灰度图像
let grayscaleImage = convertToGrayscale(image: image)// 二值化处理
let binaryImage = applyThreshold(image: grayscaleImage, threshold: 128)// 保存处理后的图片
saveImage(image: binaryImage, outputPath: outputPath)

}

func convertToGrayscale(image: NSImage) -> NSImage {
let rep = NSBitmapImageRep(data: image.tiffRepresentation!)
let grayscaleRep = rep?.converting(to: .deviceGray, renderingIntent: .default)
let grayImage = NSImage(size: image.size)
grayImage.addRepresentation(grayscaleRep!)
return grayImage
}

func applyThreshold(image: NSImage, threshold: CGFloat) -> 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)!.whiteComponentlet newColor = color > threshold / 255.0 ? NSColor.white : NSColor.blackrep.setColor(newColor, atX: x, y: y)}
}let newImage = NSImage(size: image.size)
newImage.addRepresentation(rep)
return newImage

}

func saveImage(image: NSImage, outputPath: String) {
let rep = NSBitmapImageRep(data: image.tiffRepresentation!)
let pngData = rep?.representation(using: .png, properties: [:])
try? pngData?.write(to: URL(fileURLWithPath: outputPath))
}

func recognizeCaptcha(imagePath: String) -> String {
guard let tesseract = G8Tesseract(language: "eng") else {
return "Tesseract 初始化失败"
}
tesseract.image = NSImage(contentsOfFile: imagePath)
tesseract.recognize()
return tesseract.recognizedText ?? "识别失败"
}

let inputImagePath = "captcha.png" // 请替换为你的验证码图片路径
let processedImagePath = "processed_captcha.png"

// 预处理验证码图像
preprocessImage(inputPath: inputImagePath, outputPath: processedImagePath)

// OCR 识别
let result = recognizeCaptcha(imagePath: processedImagePath)
print("识别出的验证码: (result)")

  1. 代码解析
    3.1 图像预处理

为了提高 OCR 识别率,我们进行了以下优化:

转换为灰度图像:

func convertToGrayscale(image: NSImage) -> NSImage {
let rep = NSBitmapImageRep(data: image.tiffRepresentation!)
let grayscaleRep = rep?.converting(to: .deviceGray, renderingIntent: .default)
let grayImage = NSImage(size: image.size)
grayImage.addRepresentation(grayscaleRep!)
return grayImage
}

二值化处理,增强字符对比度:

func applyThreshold(image: NSImage, threshold: CGFloat) -> NSImage {
let rep = NSBitmapImageRep(data: image.tiffRepresentation!)!
for x in 0..<rep.pixelsWide {
for y in 0..<rep.pixelsHigh {
let color = rep.colorAt(x: x, y: y)!.whiteComponent
let newColor = color > threshold / 255.0 ? NSColor.white : NSColor.black
rep.setColor(newColor, atX: x, y: y)
}
}
let newImage = NSImage(size: image.size)
newImage.addRepresentation(rep)
return newImage
}

3.2 OCR 解析

初始化 Tesseract OCR:

guard let tesseract = G8Tesseract(language: "eng") else {
return "Tesseract 初始化失败"
}

加载图像并执行 OCR:

tesseract.image = NSImage(contentsOfFile: imagePath)
tesseract.recognize()
tesseract.recognizedText ?? "识别失败"

  1. 运行程序

确保 captcha.png 在项目目录下,然后运行:

swift run

示例输出:

识别出的验证码: X9F2G

  1. 提高 OCR 识别率
    5.1 设置 Tesseract PSM 模式

Tesseract 提供不同的页面分割模式(PSM),可以调整以优化验证码识别:

tesseract.setVariableValue("6", forKey: "tessedit_pageseg_mode")

5.2 只识别特定字符
tesseract.charWhitelist = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

5.3 进一步优化

如果验证码干扰较多,可以使用 Core Image 进行滤波、去噪等处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/950330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Rust 进行验证码识别:结合 Tesseract OCR 进行文本解析

环境准备 1.1 安装 Rust如果尚未安装 Rust,可使用 Rust 官方安装工具 :更多内容访问ttocr.com或联系1436423940 curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh 安装完成后,检查 Rust 版本: rustc…

软件技术基本第二次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/25rjjc这个作业的目标 实现文本计数统计姓名-学号 冯艳-2023329301103码云仓库地址:https://gitee.com/f2196470648/word-counter.git

Day7CSS的引入方式与选择器

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">…

ZR-J 2025-10-29 比赛总结

比赛链接 分数:\(100 + 100 + 0 + 0 = 200\) 永康喵喵又没有翻车! 有了前几次翻车的教训,我形成了先写注释(对于难题)\(\rightarrow\) 仔细写题 \(\rightarrow\) 静态检查 \(\rightarrow\) 动态检查 \(\rightarro…

newDay17

1.背了背单词,把u校园作业弄了,其他的没啥 2.明天看看Java那个期中考试怎么弄 3.最近有点摆

AI元人文架构:从价值计算到智能主体的演进路径

AI元人文架构:从价值计算到智能主体的演进路径 摘要: 本文系统阐述了基于Free Transformer潜变量Z的AI元人文架构,通过构建三值纠缠模型与语境主权机制,建立多层次价值博弈体系。研究提出价值递归架构和情感维度建…

三元组 - MKT

三元组 [62] B. Jiang, Y. Zhu, and M. Liu, “A triangle feature based map-tomap matching and loop closure for 2d graph slam,” in Proc. of the International Conference on Robotics and Biomimetics (ROBIO…

《代码大全2》观后感-理论与现实的桥梁

大二的课程表里,充满了《数据结构》、《统一建模语言》、《工程实训》等课程。我们学到了“链表”、“多态”、“软件生命周期”这些概念。它们很重要,但总感觉有些抽象,像飘在空中的云。而《代码大全2》,就是那股…

做题日志3

欸我去, 真得努力做题了, 感觉做题比上班有意思多了 arc187-b 做计数还是没有对双射的条件反射, 考虑每个连通块只需要计数左端点即可.

《代码大全2》观后感-从“码农”到“工匠”的第一课

在翻开《代码大全2》之前,我对编程的理解,很大程度上还停留在“解决问题”的层面。老师布置一个作业,我打开IDE,开始敲击键盘,直到程序能跑通、能输出正确结果,任务就完成了。我把自己定义为一个“码农”,一个熟…

[Windows] WSL使用指南

[Windows] WSL使用指南$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");DeepSeek生成(2025年10月29日23:07:15)目录🚀 WSL 常用命令速查安装与基本设置发…

Causal Language Models in NLP

Causal Language Models in NLP https://www.geeksforgeeks.org/nlp/causal-language-models-in-nlp/ Causal language models are a type of machine learning model that generates text by predicting the next wor…

代码大全2,阅读3

“结对编程”。作者在 “成功运用结对编程的关键” 一节里,列了 10 条准则,每一条都戳中了 “结对容易踩的坑”。比如 “不要让结对编程变成旁观”,这是我自己实践过才懂的痛 —— 上次和同学结对做一个小项目,他负…

从零开始编写一个办公软件(二、自适应窗口)

桌面开发通常需要面对因为屏幕大小不同产生的视觉过大或过小的问题,基本都会被要求做大小自适应处理。网上一般介绍的是ViewBox,简单方便,但不仅面临性能的问题,部分情况下还会出现UI失真。我这里介绍下更繁琐但实…

10月29日日记

1.今天学习马哲以及;离散数学。 2.明天上体育课 3.Redis为什么使用跳跃表而不是平衡树?

2025.10.29总结

那个心理咨询项目学习模块完成学习包的添加和展示,还有完成进度的展示。后续需要为学习包添加视频,测验,测验后生成报告

代码大全2,阅读1

“编程是手艺,更是态度” 的表述,又让我沉下心来读。最先锁定第 33 章 “个人性格”,是因为很好奇:为什么一本讲代码的书,会把 “性格” 放在重要位置?读完才发现,作者把 “程序员该有的特质” 拆解得既具体又透…

代码大全2,阅读2

“布局清晰、控制逻辑严谨”,才是 “好代码” 的标配。但过程中也有不少和作者观点 “碰撞” 的地方,反而让思考更深入。 先说说 “数据声明的布局”。作者提了三个核心建议:每行只声明一个变量、变量声明贴近首次使…

UNIQUE VISION Programming Contest 2024 Christmas (AtCoder Beginner Contest 385)

D - Santa Claus 2 map<int,set> E - Snowflake Tree 开始想到枚举中心点,x=度数,y=min儿子度数-1,其余全要删除,删除越少留下越多,留下1+x+xy,删n-(1+x+xy) 样例1告诉我们可以删除某个子树,这样还是y=min儿…

如果我想在项目发布后,动态更新组件,如何使用模块联邦实现?

要在项目发布后动态更新组件,并使用 Webpack Module Federation(模块联邦) 实现,核心思路是: 将组件拆分为独立的 Remote 应用,Host 应用在运行时从远程加载最新版本的组件,而无需重新构建或部署 Host。 这正是…