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