用 Go 构建图像验证码识别服务(调用 Python 模型接口)

本项目将介绍如何使用 Go 构建一个图像验证码识别服务,模型部分使用 Python(PyTorch),识别逻辑通过 HTTP 接口与 Go 服务集成。

一、项目架构说明
更多内容访问ttocr.com或联系1436423940
captcha-recognizer/
├── go-server/ # Go Web 服务
│ └── main.go
├── python-model/ # Python 推理服务
│ ├── model.pt
│ └── app.py
├── testdata/
│ └── sample.png
Python 提供 /predict 接口,接收验证码图片并返回识别结果。

Go 作为主服务,接受用户请求,转发给 Python 进行识别。

二、Python 模型服务(Flask)

pip install flask torch torchvision pillow
python-model/app.py:

from flask import Flask, request, jsonify
from PIL import Image
import torch
import torchvision.transforms as transforms
import io

加载模型(你自己的模型路径)

model = torch.load("model.pt", map_location=torch.device("cpu"))
model.eval()

字符集

characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

图像预处理

transform = transforms.Compose([
transforms.Resize((60, 160)),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

app = Flask(name)

@app.route("/predict", methods=["POST"])
def predict():
file = request.files["image"]
image = Image.open(file.stream).convert("RGB")
img_tensor = transform(image).unsqueeze(0)

with torch.no_grad():
    output = model(img_tensor)
    pred = torch.argmax(output, dim=2)
    pred_str = "".join([characters[i] for i in pred[0]])

return jsonify({"result": pred_str})

运行:

cd python-model
python app.py
三、Go 服务端代码
在 go-server/main.go:

package main

import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"

"github.com/gin-gonic/gin"

)

func main() {
r := gin.Default()

r.POST("/upload", func(c *gin.Context) {
	file, err := c.FormFile("image")
	if err != nil {
		c.JSON(400, gin.H{"error": "no file"})
		return
	}
	temp := "temp.png"
	if err := c.SaveUploadedFile(file, temp); err != nil {
		c.JSON(500, gin.H{"error": "save failed"})
		return
	}

	// 转发给 Python 接口
	result, err := forwardToPython(temp)
	if err != nil {
		c.JSON(500, gin.H{"error": "predict failed"})
		return
	}
	c.JSON(200, gin.H{"captcha": result})
})

r.Run(":8080")

}

func forwardToPython(filepath string) (string, error) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

part, err := writer.CreateFormFile("image", filepath)
if err != nil {
	return "", err
}
file, err := os.Open(filepath)
if err != nil {
	return "", err
}
defer file.Close()
io.Copy(part, file)
writer.Close()

req, err := http.NewRequest("POST", "http://localhost:5000/predict", body)
req.Header.Set("Content-Type", writer.FormDataContentType())

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
	return "", err
}
defer resp.Body.Close()

buf := new(bytes.Buffer)
buf.ReadFrom(resp.Body)

return buf.String(), nil

}
运行 Go 服务:

cd go-server
go run main.go
四、测试接口
使用 curl 测试:

curl -X POST -F "image=@testdata/sample.png" http://localhost:8080/upload
返回:

{"captcha": "4GHT"}

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