用 Go + TensorFlow Serving 实现验证码识别系统
本教程展示如何在 Go 中使用 gRPC 调用 TensorFlow Serving 部署的验证码识别模型,实现验证码图片的自动识别。
一、训练模型(使用 Python)
用 PyTorch 或 TensorFlow 训练好模型,并导出为 SavedModel 格式供 TF Serving 使用:
示例:导出为 SavedModel
import tensorflow as tf
model.save("captcha_model_tf", save_format="tf")
然后使用 Docker 启动 TensorFlow Serving:
更多内容访问ttocr.com或联系1436423940
docker run -p 8501:8501
--mount type=bind,source=$(pwd)/captcha_model_tf,target=/models/captcha_model
-e MODEL_NAME=captcha_model
tensorflow/serving
二、Go 项目初始化
安装所需依赖:
go get google.golang.org/grpc
go get github.com/tensorflow/serving/tensorflow_serving/apis
生成 gRPC 客户端代码(需要 .proto 文件,可从 TensorFlow Serving GitHub 获取)。
三、图像预处理(Go + OpenCV 或图像库)
使用 Go 图像处理库对图像进行标准化处理:
import (
"image"
_ "image/png"
"os"
"github.com/nfnt/resize"
)
func preprocessImage(filepath string) []float32 {
file, _ := os.Open(filepath)
img, _, _ := image.Decode(file)
resized := resize.Resize(160, 60, img, resize.Bilinear)
var data []float32
for y := 0; y < 60; y++ {
for x := 0; x < 160; x++ {
r, g, b, _ := resized.At(x, y).RGBA()
data = append(data, (float32(r>>8)/255.0-0.5)/0.5)
data = append(data, (float32(g>>8)/255.0-0.5)/0.5)
data = append(data, (float32(b>>8)/255.0-0.5)/0.5)
}
}
return data
}
四、构建 gRPC 请求调用 TF Serving
import (
tfpb "github.com/tensorflow/serving/tensorflow_serving/apis"
"github.com/golang/protobuf/ptypes/wrappers"
"google.golang.org/grpc"
tf_core_framework "github.com/tensorflow/tensorflow/tensorflow/go/core/framework"
)
func callModel(input []float32) {
conn, _ := grpc.Dial("localhost:8500", grpc.WithInsecure())
client := tfpb.NewPredictionServiceClient(conn)
tensor := &tf_core_framework.TensorProto{
Dtype: tf_core_framework.DataType_DT_FLOAT,
TensorShape: &tf_core_framework.TensorShapeProto{
Dim: []*tf_core_framework.TensorShapeProto_Dim{
{Size: 1}, {Size: 60}, {Size: 160}, {Size: 3},
},
},
FloatVal: input,
}
req := &tfpb.PredictRequest{
ModelSpec: &tfpb.ModelSpec{
Name: "captcha_model",
SignatureName: "serving_default",
},
Inputs: map[string]*tf_core_framework.TensorProto{
"input_1": tensor,
},
}
resp, _ := client.Predict(context.Background(), req)
output := resp.Outputs["output"].FloatVal
// 解析 output 得到预测字符
}
五、结果解析
将模型输出(通常为概率分布)按字符位置进行分类解码:
func decodeOutput(output []float32, chars string) string {
result := ""
for i := 0; i < 4; i++ {
maxIdx := 0
maxVal := float32(-1.0)
for j := 0; j < 36; j++ {
idx := i*36 + j
if output[idx] > maxVal {
maxVal = output[idx]
maxIdx = j
}
}
result += string(chars[maxIdx])
}
return result
}
浙公网安备 33010602011771号