Go 构建图像验证码识别 HTTP 服务

本教程展示如何使用 Go 搭建一个图像验证码识别服务,用户可以通过发送图片文件的 POST 请求,获取识别出的验证码内容。该服务将图像预处理、字符分割、模型推理打包成一个 RESTful API 接口。

一、项目结构概述

captcha-server/
├── main.go
├── model.onnx # 已训练好的字符识别模型
├── handler.go # HTTP 处理逻辑
└── utils.go # 图像处理与模型预测工具函数
二、服务接口说明
URL: /predict

方法: POST
更多内容访问ttocr.com或联系1436423940
参数: image,类型为 multipart/form-data

返回值: JSON,示例:

{ "result": "a9C7" }
三、核心代码实现
main.go

package main

import (
"log"
"net/http"
)

func main() {
LoadModel("model.onnx") // 加载 ONNX 模型
http.HandleFunc("/predict", HandleCaptcha)

log.Println("服务启动,监听端口 8080...")
log.Fatal(http.ListenAndServe(":8080", nil))

}
handler.go

package main

import (
"encoding/json"
"fmt"
"gocv.io/x/gocv"
"io"
"net/http"
)

func HandleCaptcha(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20)
file, _, err := r.FormFile("image")
if err != nil {
http.Error(w, "上传图片失败", http.StatusBadRequest)
return
}
defer file.Close()

// 读取为图像
data, _ := io.ReadAll(file)
img, err := gocv.IMDecode(data, gocv.IMReadGrayScale)
if err != nil || img.Empty() {
	http.Error(w, "图像解析失败", http.StatusBadRequest)
	return
}
defer img.Close()

result := PredictCaptcha(img)

// 返回 JSON
resp := map[string]string{"result": result}
json.NewEncoder(w).Encode(resp)

}
utils.go

package main

import (
"gocv.io/x/gocv"
"github.com/microsoft/onnxruntime-go"
"image"
)

var (
modelSession *onnxruntime.Session
labels = "0123456789abcdefghijklmnopqrstuvwxyz"
)

func LoadModel(path string) {
env, _ := onnxruntime.NewEnvironment()
session, _ := env.NewSession(path)
modelSession = session
}

func PredictCaptcha(img gocv.Mat) string {
chars := splitImage(img)
result := ""
for _, ch := range chars {
data := preprocess(ch)
c := predictChar(data)
result += string(c)
ch.Close()
}
return result
}

func splitImage(img gocv.Mat) []gocv.Mat {
step := img.Cols() / 4
var out []gocv.Mat
for i := 0; i < 4; i++ {
crop := img.Region(image.Rect(istep, 0, (i+1)step, img.Rows()))
resized := gocv.NewMat()
gocv.Resize(crop, &resized, image.Pt(28, 28), 0, 0, gocv.InterpolationLinear)
out = append(out, resized.Clone())
crop.Close()
resized.Close()
}
return out
}

func preprocess(mat gocv.Mat) []float32 {
data := make([]float32, 2828)
for y := 0; y < 28; y++ {
for x := 0; x < 28; x++ {
data[y
28+x] = float32(mat.GetUCharAt(y, x)) / 255.0
}
}
return data
}

func predictChar(data []float32) byte {
tensor, _ := onnxruntime.NewTensor([]int64{1, 1, 28, 28}, data)
outputs, _ := modelSession.Run(map[string]*onnxruntime.Tensor{"input": tensor})
maxIdx := 0
scores := outputs[0].Float32Data()
for i, s := range scores {
if s > scores[maxIdx] {
maxIdx = i
}
}
return labels[maxIdx]
}
四、测试请求
你可以使用 curl 或 Postman 进行测试:

curl -X POST http://localhost:8080/predict
-F "image=@captcha.png"
返回示例:

{"result":"a8K2"}

posted @ 2025-06-03 19:32  ttocr、com  阅读(39)  评论(0)    收藏  举报