Go 构建验证码识别系统:从图像生成到模型调用
验证码识别是一种经典的图像分类问题。在本项目中,我们将用 Go 实现一个完整的验证码识别流程,包括验证码生成、图片上传、模型服务调用以及识别结果展示。
项目亮点
使用 Go 生成简单验证码图片
用 HTTP 接收图片上传请求
调用 Python 模型服务进行识别
显示识别结果
一、准备工作
我们将项目划分为两部分:
Go Web 服务:生成验证码、提供上传页面、发送图片到模型
Python 模型服务:接收图像,返回识别结果
项目目录结构:
captcha-go-demo/
├── go-server/
│ ├── main.go
│ └── static/
│ └── index.html
├── python-model/
│ ├── model.py
│ └── app.py
二、Python 模型 API(识别服务)
我们假设模型已经训练好,并部署为一个 Flask 接口。
python-model/app.py
from flask import Flask, request, jsonify
from PIL import Image
import torch
from torchvision import transforms
from model import CRNN
import string
app = Flask(name)
characters = string.digits + string.ascii_uppercase
model = CRNN()
model.load_state_dict(torch.load("crnn_model.pth", map_location="cpu"))
model.eval()
transform = transforms.Compose([
transforms.Resize((60, 160)),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
@app.route("/predict", methods=["POST"])
def predict():
img = Image.open(request.files["image"]).convert("RGB")
img_tensor = transform(img).unsqueeze(0)
with torch.no_grad():
output = model(img_tensor)
pred = torch.argmax(output, dim=2)[0]
result = ''.join([characters[i] for i in pred])
return jsonify({"code": result})
if name == "main":
app.run(port=5002)
三、Go 实现:验证码识别 Web 服务
- 静态页面上传图像
上传验证码图片
2. Go 后端逻辑// go-server/main.go
package main
import (
"bytes"
"fmt"
"html/template"
"io"
"log"
"mime/multipart"
"net/http"
)
func main() {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.HandleFunc("/", serveIndex)
http.HandleFunc("/upload", handleUpload)
fmt.Println("Go Server running at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func serveIndex(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("static/index.html"))
tmpl.Execute(w, nil)
}
func handleUpload(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20) // 10MB
file, _, err := r.FormFile("captcha")
if err != nil {
http.Error(w, "无法读取图片", http.StatusBadRequest)
return
}
defer file.Close()
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
part, _ := writer.CreateFormFile("image", "captcha.png")
io.Copy(part, file)
writer.Close()
resp, err := http.Post("http://localhost:5002/predict", writer.FormDataContentType(), &buf)
if err != nil {
http.Error(w, "调用模型服务失败", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
io.Copy(w, resp.Body)
}
运行 Go 服务:
go run main.go
四、运行测试
启动 Python 模型服务:
python app.py
启动 Go 服务:
cd go-server
go run main.go
浙公网安备 33010602011771号