TensorFlow识别复杂验证码以及搭建生产环境(9)—— 基于Java的调用

0x00 基本环境

需要添加以下依赖的Jar包

这里写图片描述

0x01 JwxtCaptchaCrack.java

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import net.coobird.thumbnailator.Thumbnails;
import org.tensorflow.framework.DataType;
import org.tensorflow.framework.TensorProto;
import org.tensorflow.framework.TensorShapeProto;
import tensorflow.serving.Model;
import tensorflow.serving.Predict;
import tensorflow.serving.PredictionServiceGrpc;

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class JwxtCaptchaCrack {
    String host;
    int port;
    public JwxtCaptchaCrack(String host, int port){
        this.host = host;
        this.port = port;
    }

    /**
     * 教务系统验证码所在的路径
     * */
    public String crackCaptcha(String file) throws IOException {
        //#记个时
        long t = System.currentTimeMillis();
//        String file = "D:\\\\jwxt\\\\new_test\\\\4am7.jpg";
        //读取文件,强制修改图片大小,设置输出文件格式bmp(模型定义时输入数据是无编码的)
        BufferedImage im = Thumbnails.of(file).forceSize(180, 60).outputFormat("bmp").asBufferedImage();
        //转换图片到图片数组,匹配输入数据类型为Float
        Raster raster = im.getData();
        List<Float> floatList = new ArrayList<>();
        float [] temp = new float[raster.getWidth() * raster.getHeight() * raster.getNumBands()];
        float [] pixels  = raster.getPixels(0,0,raster.getWidth(),raster.getHeight(),temp);
        float []img = new float[pixels.length / 3];
        //在图片处理的同时顺便
        for (int i = 0 ; i < pixels.length / 3 ; i++){
            floatList.add((pixels[i*3] + pixels[i*3+1] + pixels[i*3+2])/(3*255));
        }
//        System.out.println("time cost:" + (System.currentTimeMillis() - t));

        //#创建连接,注意usePlaintext设置为true表示用非SSL连接
        ManagedChannel channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build();
        //这里还是先用block模式
        PredictionServiceGrpc.PredictionServiceBlockingStub stub = PredictionServiceGrpc.newBlockingStub(channel);
        //创建请求
        Predict.PredictRequest.Builder predictRequestBuilder = Predict.PredictRequest.newBuilder();
        //模型名称和模型方法名预设
        Model.ModelSpec.Builder modelSpecBuilder = Model.ModelSpec.newBuilder();
        modelSpecBuilder.setName("crack_captcha");
        modelSpecBuilder.setSignatureName("serving_default");
        predictRequestBuilder.setModelSpec(modelSpecBuilder);
        //设置入参,访问默认是最新版本,如果需要特定版本可以使用tensorProtoBuilder.setVersionNumber方法
        TensorProto.Builder tensorProtoBuilder = TensorProto.newBuilder();
        tensorProtoBuilder.setDtype(DataType.DT_FLOAT);
        TensorShapeProto.Builder tensorShapeBuilder = TensorShapeProto.newBuilder();
        tensorShapeBuilder.addDim(TensorShapeProto.Dim.newBuilder().setSize(1));
        tensorShapeBuilder.addDim(TensorShapeProto.Dim.newBuilder().setSize(60*180));
        tensorProtoBuilder.setTensorShape(tensorShapeBuilder.build());
        tensorProtoBuilder.addAllFloatVal(floatList);
        predictRequestBuilder.putInputs("image", tensorProtoBuilder.build());
        //访问并获取结果
        Predict.PredictResponse predictResponse = stub.predict(predictRequestBuilder.build());
        String tmp = "";
        for (int i = 0 ;i < 4 ; i ++){

            long l = predictResponse.getOutputsOrThrow("out").getInt64Val(i);
            if (l < 10){
                tmp += (char)(l+'0');
            }else {
                tmp += (char)(l-10 + 'a');
            }
        }
//        System.out.println("cost time: " + (System.currentTimeMillis() - t));
        return tmp;
    }
}


0x02 Main.java

import java.io.IOException;


public class Main {

    public static void main(String[] args) throws IOException {
        //部署的tensorflow-serving服务器的ip以及端口
        JwxtCaptchaCrack jwxtCaptchaCrack = new JwxtCaptchaCrack("192.168.190.128",9000);
        jwxtCaptchaCrack.crackCaptcha("D:\\jwxt\\new_test\\2bc2.jpg");
    }
}

0x03 输出

这里写图片描述

0x04 总结

至此从训练集的收集到训练测试以及部署整个的流程都走完了。

题外话,博主也基于这个项目实现了自动识别学校教务系统的验证码然后查成绩的项目。

这里写图片描述

0x05 后记

在整个项目的开完以及之后的本系列的博文写作中,得到了很多人的帮助与支持。在此向他们表示由衷的的感谢。
特别是

####不愿透露姓名的YY同学提供的带GPU的设备支持。

以及温柔可爱善解人意的ZP同学的支持。
还有IMUDGES的支持。
有任何关于本系列博文的问题以及其他见解
联系博主:胡鹏(hupengATwebpragueDOTcom)

0x06 补充

在实际上发现导出另一种格式的PB文件,可以用Java直接调用而不依赖于Tensorflow Serving服务
给个链接 https://blog.csdn.net/huplion/article/details/80567050
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值