使用 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
浙公网安备 33010602011771号