当前位置: 首页 > news >正文

用 Go + Tesseract 实现英文数字验证码识别

一、为什么选 Go

二进制部署方便、启动速度快,适合在服务器或微服务中部署 OCR 接口。

gosseract 是成熟的 Go 对 Tesseract 的封装,调用简单。

可与 Go 的并发模型天然结合,便于批量或并发识别。

二、环境准备

  1. 安装 Go(1.18+ 推荐)
    更多内容访问ttocr.com或联系1436423940
    macOS(Homebrew):

brew install go

Ubuntu:

sudo apt update
sudo apt install golang-go

验证:

go version

  1. 安装 Tesseract OCR

macOS:

brew install tesseract

Ubuntu / Debian:

sudo apt install tesseract-ocr libtesseract-dev libleptonica-dev

确认:

tesseract --version

  1. 安装 ImageMagick(用于外部预处理,可选)

可用 convert 进行灰度/二值化(脚本里会示例使用)。
macOS:

brew install imagemagick

Ubuntu:

sudo apt install imagemagick

  1. 安装 Go 依赖

我们用 gosseract 和 gocv/imaging(可选)做图像处理。最简单用 imaging。

go get github.com/otiai10/gosseract/v2
go get github.com/disintegration/imaging

三、思路与流程概览

准备或收集验证码图片(示例用 captcha.png),建议清晰且为英文数字组合。

对图像做预处理:灰度、对比增强、二值化、去噪(可用 ImageMagick 或 Go 的 imaging 做基本处理)。

用 gosseract 调用 Tesseract 做 OCR,设置字符白名单(只识别 A-Z、0-9)提高准确率。

清洗识别结果(去掉非字母数字字符),输出最终验证码字符串。

可扩展为批量处理、并发识别或 REST 接口。

四、示例工程(文件清单)

main.go — 主识别程序(含预处理和识别)

(可选)Dockerfile — 容器化部署

测试图片:captcha.png

五、详细代码(main.go)
package main

import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"sync"

"github.com/disintegration/imaging"
"github.com/otiai10/gosseract/v2"

)

// 使用 ImageMagick 的 convert 进行更强的二值化/去噪(如果安装了 ImageMagick)
// 如果不想依赖 convert,可用 imaging 做灰度与简单增强
func preprocessWithConvert(src, dst string) error {
// 灰度、增强对比、自动阈值二值化
// 这个命令可按需调整 threshold 值
cmd := exec.Command("convert", src,
"-colorspace", "Gray",
"-contrast-stretch", "0.5%",
"-threshold", "50%",
dst)
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("convert error: %v, output: %s", err, string(out))
}
return nil
}

// 纯 Go 预处理(不依赖 ImageMagick): 灰度、调整对比/锐化、二值化
func preprocessWithImaging(src, dst string) error {
img, err := imaging.Open(src)
if err != nil {
return err
}
// 灰度
gray := imaging.Grayscale(img)
// 轻微提高清晰度(可选)
// gray = imaging.Sharpen(gray, 0.5)
// 增强对比度
gray = imaging.AdjustContrast(gray, 20) // -100..100
// 二值化(手动阈值)
b := imaging.AdjustFunc(gray, func(c float64) float64 {
// c in 0..1
if c > 0.6 { // 阈值可调
return 1.0
}
return 0.0
})
return imaging.Save(b, dst)
}

func cleanText(s string) string {
// 保留大小写字母和数字
re := regexp.MustCompile([^A-Za-z0-9])
return re.ReplaceAllString(s, "")
}

func ocrSingle(imagePath string) (string, error) {
// 先做预处理到临时文件
tmp := strings.TrimSuffix(imagePath, filepath.Ext(imagePath)) + "_proc.png"

// 尝试用 ImageMagick 的 convert(若安装),否则用 Go imaging
if _, err := exec.LookPath("convert"); err == nil {if err := preprocessWithConvert(imagePath, tmp); err != nil {log.Printf("convert preproc failed: %v, fallback to imaging", err)if err := preprocessWithImaging(imagePath, tmp); err != nil {return "", err}}
} else {if err := preprocessWithImaging(imagePath, tmp); err != nil {return "", err}
}client := gosseract.NewClient()
defer client.Close()
// 设置语言为英文,并限制可识别字符白名单
client.SetLanguage("eng")
client.SetWhitelist("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
if err := client.SetImage(tmp); err != nil {return "", err
}
text, err := client.Text()
if err != nil {return "", err
}
// 清洗结果
clean := cleanText(text)
// 可删临时文件
_ = os.Remove(tmp)
return clean, nil

}

func ocrBatch(paths []string, concurrency int) map[string]string {
res := make(map[string]string)
var mu sync.Mutex
wg := sync.WaitGroup{}
sem := make(chan struct{}, concurrency)

for _, p := range paths {p := pwg.Add(1)sem <- struct{}{}go func() {defer wg.Done()defer func() { <-sem }()out, err := ocrSingle(p)if err != nil {log.Printf("ocr error %s: %v", p, err)out = ""}mu.Lock()res[p] = outmu.Unlock()}()
}
wg.Wait()
return res

}

func main() {
if len(os.Args) < 2 {
fmt.Println("usage: go run main.go ")
return
}
target := os.Args[1]
info, err := os.Stat(target)
if err != nil {
log.Fatalf("stat error: %v", err)
}
if info.IsDir() {
// 遍历目录下 png/jpg
var files []string
err := filepath.Walk(target, func(path string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
if fi.IsDir() {
return nil
}
ext := strings.ToLower(filepath.Ext(path))
if ext == ".png" || ext == ".jpg" || ext == ".jpeg" {
files = append(files, path)
}
return nil
})
if err != nil {
log.Fatalf("walk error: %v", err)
}
results := ocrBatch(files, 4) // 并发 4 个
for k, v := range results {
fmt.Printf("%s -> %s\n", k, v)
}
} else {
out, err := ocrSingle(target)
if err != nil {
log.Fatalf("ocr failed: %v", err)
}
fmt.Println("识别结果:", out)
}
}

说明(代码关键点)

preprocessWithConvert:如果系统安装了 ImageMagick 的 convert,优先用其二值化能力(通常效果更好);否则用 imaging 做灰度+对比调整+手动阈值二值化。阈值和对比数值可根据你的验证码样式调参。

gosseract:设置 SetWhitelist 只允许英文字母和数字,能大幅减少误识别的字符。

并发:ocrBatch 使用 goroutine 和信号量(channel)限制并发数,适合在服务器批量处理场景。

清洗:用正则去掉非字母数字字符。

六、运行示例

构建并运行(假设文件名 captcha.png 在当前目录):

go run main.go captcha.png

批量识别目录:

go run main.go ./captchas_dir

http://www.sczhlp.com/news/91009/

相关文章:

  • 基于MATLAB的CNN大气散射传播率计算与图像去雾实现
  • 高清素材图片的网站国内做网站大公司
  • 做网站模版目前做啥网站能致富
  • 企业网站建设运营网站做多个语言有什么好处
  • 广州番禺区是乡下吗湘潭sem优化价格
  • 上海建设银行官方网站建筑电工证查询网站
  • 网络彩票建立网站网站 html5
  • 中英文 网站线上编程课
  • 优质做网站哪家正规查询建设资质的网站
  • 化妆品网站建设的策划python怎么开发网站
  • 大连模板网站制作公众号开发者模式怎么关闭
  • 网站如何设置长尾词自己做一个网页怎么做
  • 软件工程第一次作业:自我介绍+软工五问
  • 接网站建设单子注意事项立邦刷新服务多少钱一平米
  • 网站 广州网站改版业务
  • dw做单页网站教程网站提示页面设计
  • 网站专题页怎么做沈阳个人网站建设
  • 稀奇古怪好玩有用的网站广东建设银行招聘网站
  • 炸裂:SpringAI新版发布,终于支持断线重连了!
  • spring 事务实战:声明式vs 编程式
  • 杭州模板建站定制东莞东城国际酒店
  • 删除网站备案深圳手机网站建设多少钱
  • 怎么在网站上面做悬浮广告做网站 做应用
  • 物联网网站开发做汽车价格的网站
  • 重庆哪个网站建设比较好.htaccess 伪静态 wordpress
  • 企业对比网站网站建设背景朝阳
  • solo博客容器化运行访问
  • 绍兴网站建站模板网站flash
  • 科讯cms怎么做网站地图泰州网站建设定制
  • 哪些网站可以做淘宝店招做企业网站需要购什么