使用 Go 语言识别图像验证码(调用 ONNX 模型)

在本教程中,我们将介绍如何使用 Go 实现图像验证码识别功能,重点内容包括:

使用 Go 生成图像验证码

调用 ONNX 模型识别图像内容

完整构建一个识别服务

一、准备工作
我们会使用以下工具:

Go >= 1.18
更多内容访问ttocr.com或联系1436423940
fogleman/gg:生成验证码图像

microsoft/onnxruntime-go:加载 ONNX 模型进行推理

安装依赖:

go get github.com/fogleman/gg
go get github.com/microsoft/onnxruntime-go
二、生成验证码图片
使用 fogleman/gg 生成简单的 4 位图像验证码:

package main

import (
"fmt"
"image/color"
"math/rand"
"os"
"time"

"github.com/fogleman/gg"

)

const charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

func generateCode(n int) string {
rand.Seed(time.Now().UnixNano())
code := make([]byte, n)
for i := range code {
code[i] = charset[rand.Intn(len(charset))]
}
return string(code)
}

func generateCaptchaImage(code string, filename string) error {
const W, H = 160, 60
dc := gg.NewContext(W, H)
dc.SetColor(color.White)
dc.Clear()
dc.SetRGB(0, 0, 0)
if err := dc.LoadFontFace("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 36); err != nil {
return err
}
dc.DrawStringAnchored(code, W/2, H/2, 0.5, 0.5)
return dc.SavePNG(filename)
}

func main() {
code := generateCode(4)
filename := code + ".png"
if err := generateCaptchaImage(code, filename); err != nil {
fmt.Println("生成失败:", err)
return
}
fmt.Println("验证码已生成:", filename)
}
运行后生成一个形如 9F3A.png 的验证码图片。

三、调用 ONNX 模型进行识别
我们假设已有一个训练好的验证码识别模型(输入为 160×60 RGB 图像,输出为 4 个字符类别),并将其导出为 captcha.onnx。

ONNX 推理示例代码:

package main

import (
"fmt"
"image"
"os"

"github.com/microsoft/onnxruntime-go"
"gocv.io/x/gocv"

)

func preprocessImage(filepath string) ([]float32, error) {
img := gocv.IMRead(filepath, gocv.IMReadColor)
if img.Empty() {
return nil, fmt.Errorf("failed to read image")
}
defer img.Close()

gocv.Resize(&img, &img, image.Pt(160, 60), 0, 0, gocv.InterpolationLinear)

blob := gocv.BlobFromImage(img, 1.0/255.0, image.Pt(160, 60), gocv.NewScalar(0, 0, 0, 0), true, false)
data, err := blob.DataPtrFloat32()
return data, err

}

func predict(filepath string) (string, error) {
session, err := onnxruntime.NewSession("captcha.onnx")
if err != nil {
return "", err
}
defer session.Close()

inputData, err := preprocessImage(filepath)
if err != nil {
	return "", err
}

tensor, err := onnxruntime.NewTensor(onnxruntime.TENSOR_FLOAT, []int64{1, 3, 60, 160}, inputData)
if err != nil {
	return "", err
}

output, err := session.Run(map[string]*onnxruntime.Tensor{"input": tensor})
if err != nil {
	return "", err
}

charset := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result := ""
for i := 0; i < 4; i++ {
	idx := argmax(output["output"][i*36 : (i+1)*36])
	result += string(charset[idx])
}
return result, nil

}

func argmax(data []float32) int {
max := data[0]
idx := 0
for i, v := range data {
if v > max {
max = v
idx = i
}
}
return idx
}
⚠️ 注意:你需要使用 gocv 进行图像处理,同时准备好训练好的 captcha.onnx 模型。

四、运行识别流程
结合上面两个模块,可以完整运行:

生成一张验证码图片

使用 Go 读取该图片并送入 ONNX 模型进行识别

输出识别结果

例如:

go run generate.go # 生成验证码图像 9F3A.png
go run predict.go # 推理输出 Predicted: 9F3A

posted @ 2025-05-30 11:58  ttocr、com  阅读(136)  评论(0)    收藏  举报