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

本项目使用 Go 语言开发了一个轻量级图像验证码识别 Web API,前端可以通过 HTTP POST 上传图片,服务将返回识别结果,适用于系统集成或批量处理场景。

一、项目功能
提供 HTTP 接口上传验证码图像(PNG/JPG)

服务器端自动处理、切割图像字符

使用 ONNX 模型进行字符识别

返回 JSON 格式的识别结果
更多内容访问ttocr.com或联系1436423940
二、技术栈
编程语言:Go

Web 框架:Gin

图像处理:gocv

推理引擎:onnxruntime-go

三、目录结构

captcha-api/
├── main.go
├── handler.go
├── model.go
├── imageutil.go
├── model.onnx
四、关键代码
main.go

package main

import (
"github.com/gin-gonic/gin"
)

func main() {
LoadModel("model.onnx")

r := gin.Default()
r.POST("/predict", PredictHandler)
r.Run(":8080") // 启动服务,监听 8080 端口

}
handler.go

package main

import (
"net/http"

"github.com/gin-gonic/gin"

)

func PredictHandler(c *gin.Context) {
file, err := c.FormFile("image")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "缺少图像"})
return
}

tmp := "./tmp.png"
c.SaveUploadedFile(file, tmp)

code, err := RecognizeCaptcha(tmp)
if err != nil {
	c.JSON(http.StatusInternalServerError, gin.H{"error": "识别失败"})
	return
}
c.JSON(http.StatusOK, gin.H{"code": code})

}
model.go

package main

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

var session *onnxruntime.Session
var charset = "0123456789abcdefghijklmnopqrstuvwxyz"

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

func RecognizeCaptcha(imgPath string) (string, error) {
img := gocv.IMRead(imgPath, gocv.IMReadGrayScale)
defer img.Close()

codes := ""
chars := SplitIntoChars(img)

for _, ch := range chars {
	input := Preprocess(ch)
	tensor, _ := onnxruntime.NewTensor([]int64{1, 1, 28, 28}, input)
	outputs, _ := session.Run(map[string]*onnxruntime.Tensor{"input": tensor})
	probs := outputs[0].Float32Data()

	maxIdx := 0
	for i, p := range probs {
		if p > probs[maxIdx] {
			maxIdx = i
		}
	}
	codes += string(charset[maxIdx])
}
return codes, nil

}
imageutil.go

package main

import (
"gocv.io/x/gocv"
"image"
)

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

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
}
五、接口使用说明
上传识别请求

POST http://localhost:8080/predict
Content-Type: multipart/form-data
参数: image=文件
响应示例

{
"code": "b6f3"
}

posted @ 2025-06-03 20:42  ttocr、com  阅读(30)  评论(0)    收藏  举报