用 Go 实现简洁图像验证码识别系统
一、项目概述
本项目使用 Go 实现了一个图像验证码识别程序,通过加载预训练模型、对验证码图片进行预处理和分割,使用 ONNX Runtime 进行字符识别,最终返回完整验证码字符串。适用于后端服务自动化处理验证码任务。
二、使用技术
编程语言:Go 1.20+
图像处理库:image, image/png, image/color, github.com/disintegration/imaging
模型推理:github.com/microsoft/onnxruntime-go
更多内容访问ttocr.com或联系1436423940
模型格式:ONNX,支持常见 CNN 结构
三、项目结构
simple-captcha-go/
├── main.go // 启动程序
├── preprocess.go // 图像处理
├── predict.go // 模型推理
├── model.onnx // 已训练的 ONNX 模型
四、关键代码
- main.go
package main
import "fmt"
func main() {
model := LoadModel("model.onnx")
code, err := Recognize("test.png", model)
if err != nil {
fmt.Println("识别失败:", err)
} else {
fmt.Println("识别结果:", code)
}
}
2. preprocess.go
package main
import (
"image"
"image/png"
"os"
"github.com/disintegration/imaging"
)
func SplitImage(path string) ([]image.Image, error) {
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
img, err := png.Decode(file)
if err != nil {
return nil, err
}
width := img.Bounds().Dx() / 4
height := img.Bounds().Dy()
var chars []image.Image
for i := 0; i < 4; i++ {
rect := image.Rect(i*width, 0, (i+1)*width, height)
crop := imaging.Crop(img, rect)
resized := imaging.Resize(crop, 28, 28, imaging.Lanczos)
chars = append(chars, resized)
}
return chars, nil
}
3. predict.go
package main
import (
"github.com/microsoft/onnxruntime-go"
"image"
)
var charset = "0123456789abcdefghijklmnopqrstuvwxyz"
func LoadModel(path string) *onnxruntime.Session {
env, _ := onnxruntime.NewEnvironment()
session, _ := env.NewSession(path)
return session
}
func Recognize(path string, model *onnxruntime.Session) (string, error) {
chars, err := SplitImage(path)
if err != nil {
return "", err
}
code := ""
for _, img := range chars {
input := imageToTensor(img)
tensor, _ := onnxruntime.NewTensor([]int64{1, 1, 28, 28}, input)
outputs, _ := model.Run(map[string]*onnxruntime.Tensor{"input": tensor})
probs := outputs[0].Float32Data()
maxIdx := 0
for i, p := range probs {
if p > probs[maxIdx] {
maxIdx = i
}
}
code += string(charset[maxIdx])
}
return code, nil
}
func imageToTensor(img image.Image) []float32 {
data := make([]float32, 2828)
for y := 0; y < 28; y++ {
for x := 0; x < 28; x++ {
r, g, b, _ := img.At(x, y).RGBA()
gray := float32(0.299float32(r>>8) + 0.587float32(g>>8) + 0.114float32(b>>8)) / 255
data[y*28+x] = gray
}
}
return data
}
五、运行结果
当运行 go run main.go 后,若输入的 test.png 是一个标准的四字符验证码图片,则程序输出类似:
识别结果:x8d3