项目里面用到了tflite,用于做简单的图片处理,不是判断图片是什么类型,就是传进去图片,生成新图片,类似于前面一篇讲的GPUImage的滤镜功能,但是比滤镜功能更加强大。
我这里要做的就是集成,拿人家训练好的模型直接来用,我不用去训练模型。
第一步 依赖
1 | //依赖库 |
第二步 加载训练模型
网上很多介绍资料都是把训练模型直接copy到项目main目录下的assets目录(不存在就创建)与java目录平级,自然,这样的加载方式就是
1 | // load infer model |
一个tflite文件就好几M,甚至十几M,全部copy到项目里面不显示,所以,我们一般项目里面用都是先下载,然后再使用,那,这样的方式,我们要怎么加载训练模型呢?
我们先分析一下再assets目录下面怎么加载的?说白了就是新建一个Interpreter对象,就是加载模型。上面的方法都过时了,我们可以找到Interpreter类,里面你会看到如下的方法
1 | //第一个参数传tflite文件,第二个参数传一个Interpreter静态内部类对象 |
第三步 执行run方法
1 | tflite.run(in, out); |
通过执行这个run方法,获取我们需要的东西,第一个参数,输入对象,第二个参数,输出参数。
重点,敲黑板
重点,敲黑板
重点,敲黑板
重点就在这里,这里的输入和输出参数要怎么传?我这里训练模型是用Python做的,它需要传入一个四维数组,所以,输出我们自然也要用一个四维数组接收。
这里的四维数组怎么传递呐?就要说到Android里面的bitmap知识了,它的每个像素点都是一个ARGB数组。即透明度,红色,绿色,蓝色。我们前面的灰色滤镜之类的东西,实际上就是改变RGB三原色的值,让颜色变成灰色,然后改变亮度之类的就是改变每个管道的透明度。网上有很多这样的知识。
再来说说这个四维数组,我项目里面用到的这个四维数组:1 X 256 X 256 X 3,这几个值怎么理解呢?
1 | 1:表示一张图片 |
那我们怎么把bitmap对象,转换成我们需要的四维数组呐?
1 | //定义了一个一维数组,里面就是我们需要的参数,便于修改 |
上面代码注释写的很清楚了吧?每一行都有注释,for循环的作用也标的很清楚,通过这个方法,我们得到的就是我们想要的四维数组了,这里的四维数组的格式,图片的大小,都是tflite文件建模型的时候设置好的,看你们训练模型的工程师是怎么定义的,你就怎么传。
然后,新建一个一模一样格式的数组去接收输出值,也是一个四维数组,那么,我们怎么把这个四维数组转换成我们需要的bitmap呢?
1 | //创建bitmap的方法, |
就是这个方法,传一个一维颜色数组,图片的宽高,还有一个图片的格式,那我们这里就是要把这个四维数组转成一个一维的颜色数组了。
1 | /** |
至此,我们就拿到了,我们需要的bitmap对象了,然后再做后续的逻辑即可。