Rust 实现验证码识别(结合 Tesseract OCR)


1. 环境准备
1.1 安装 Rust
如果尚未安装 Rust,可以使用 rustup 进行安装:

bash

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
安装完成后,检查 Rust 是否可用:

bash

rustc --version
1.2 安装 Tesseract OCR
在不同系统上的安装方式如下:

Linux (Ubuntu)
bash

sudo apt update
sudo apt install tesseract-ocr libtesseract-dev
macOS
bash

brew install tesseract
Windows
可从 Tesseract GitHub 下载适用于 Windows 的安装包,并配置环境变量。

1.3 创建 Rust 项目并添加依赖
创建一个新的 Rust 项目:

bash

cargo new captcha_ocr
cd captcha_ocr
编辑 Cargo.toml,添加必要的依赖:

toml

[dependencies]
tesseract = "0.14.0" # Tesseract OCR Rust 绑定
image = "0.24.5" # 处理图像
2. 代码实现
创建 src/main.rs 并添加以下代码:

rust

use image::{DynamicImage, GenericImageView, GrayImage, Luma};
use std::path::Path;
use tesseract::Tesseract;

fn preprocess_image(image_path: &str) -> GrayImage {
    // 加载图像
    let img = image::open(image_path).expect("无法打开图像");

    // 转换为灰度图像
    let gray_img = img.to_luma8();

    // 二值化处理,提高 OCR 识别率
    let threshold = 128;
    let binary_img = GrayImage::from_fn(gray_img.width(), gray_img.height(), |x, y| {
        let pixel = gray_img.get_pixel(x, y);
        if pixel[0] > threshold {
            Luma([255]) // 白色
        } else {
            Luma([0])   // 黑色
        }
    });

    binary_img
}

fn recognize_captcha(image_path: &str) -> String {
    // 预处理图像
    let processed_image = preprocess_image(image_path);
    let processed_path = "processed_captcha.png";
    processed_image.save(processed_path).expect("无法保存预处理图像");

    // 初始化 Tesseract
    let mut tess = Tesseract::new(None, "eng").expect("无法初始化 Tesseract");
    tess.set_image(Path::new(processed_path))
        .expect("无法加载图像");
    
    // 进行 OCR 识别
    let text = tess.get_text().expect("OCR 识别失败");
    text.trim().to_string()
}

fn main() {
    let image_path = "captcha.png"; // 需替换为实际验证码图像
    let result = recognize_captcha(image_path);
    println!("识别出的验证码: {}", result);
}
3. 代码解析
3.1 图像预处理
为了提高 OCR 识别率,我们对验证码图像进行了优化:

转换为灰度图像:
rust

let gray_img = img.to_luma8();
二值化处理(黑白化):

let threshold = 128;
let binary_img = GrayImage::from_fn(gray_img.width(), gray_img.height(), |x, y| {
    let pixel = gray_img.get_pixel(x, y);
    if pixel[0] > threshold {
        Luma([255]) // 白色
    } else {
        Luma([0])   // 黑色
    }
});
这一步骤可以减少背景干扰,使验证码字符更清晰。

3.2 OCR 解析
初始化 Tesseract OCR:
rust

let mut tess = Tesseract::new(None, "eng").expect("无法初始化 Tesseract");
加载验证码图像:
rust

tess.set_image(Path::new(processed_path))
    .expect("无法加载图像");
获取 OCR 识别结果:
rust

let text = tess.get_text().expect("OCR 识别失败");
4. 运行程序
确保 captcha.png 存在于项目根目录,然后运行:

bash

cargo run
程序会加载验证码图像,进行预处理,并输出识别的文本。

5. 提高 OCR 识别率
5.1 选择合适的 PSM 模式
Tesseract 提供了不同的页面分割模式(PSM)。对于验证码识别,推荐使用 PSM 7(单行文本):

rust

tess.set_variable("tessedit_pageseg_mode", "7")
    .expect("无法设置 PSM 模式");
其他常见 PSM 模式:

PSM 6:假设是单行文本(默认)
PSM 7:单行纯文本(适用于验证码)
PSM 10:单字符模式(适用于单字符验证码)
5.2 只识别特定字符
如果验证码仅包含字母和数字:

rust

tess.set_variable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    .expect("无法设置字符白名单");
5.3 进一步优化
降噪处理:可以使用 OpenCV 进行降噪去背景
字符分割:如果验证码字符粘连,可以尝试 OpenCV 进行字符分割
深度学习方案:如果 Tesseract 识别效果不佳,可以结合深度学习模型(如 PaddleOCR 或 EasyOCR)