用 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[y28+x] = float32(mat.GetUCharAt(y, x)) / 255.0
}
}
return data
}
五、接口使用说明
上传识别请求
POST http://localhost:8080/predict
Content-Type: multipart/form-data
参数: image=文件
响应示例
{
"code": "b6f3"
}
浙公网安备 33010602011771号