在做人脸识别本地化方案是,遇到个数据存储的问题。
图片提取到的特征值是一个512 为的float数组,大小为512*4 = 2k
如果转换成字符串进行存储,则数据大小为 512*1*32=16K 放大了8倍。
如果有500条数据的话,就是16*500 = 8M。常见的方式是数据库或者sp,文件
第一,sqlite3最长存储4000个字符,数据库无法存储。
第一,如果存成sp或者文件,读取数据的耗时惊人,存储成sp或者文件都不现实,而且sp文件还会拖慢整体速度。
因而,调研了很长时间,找到一种存储方案。blob,sqlite3开始支持存储blob文件。
核心代码就是将512浮点数转换成bytes数组,再转换回来。代码如下:
public static byte[] fromFloatToBytes(float[] feat) {
byte[] byteRet = new byte[2048];
for (int i = 0; i < feat.length; i++) {
int accum = Float.floatToRawIntBits(feat[i]);
byteRet[i*4+0] = (byte) (accum & 0xFF);
byteRet[i*4+1] = (byte) ((accum >> 8) & 0xFF);
byteRet[i*4+2] = (byte) ((accum >> 16) & 0xFF);
byteRet[i*4+3] = (byte) ((accum >> 24) & 0xFF);
}
return byteRet;
}
public static float[] fromBytesToFloat(byte[] Array) {
int accum = 0;
float[] floatRet = new float[512];
for (int i = 0; i < Array.length; i+=4) {
accum = Array[i + 0] & 0xFF;
accum |= (long) (Array[i + 1] & 0xFF) << 8;
accum |= (long) (Array[i + 2] & 0xFF) << 16;
accum |= (long) (Array[i + 3] & 0xFF) << 24;
floatRet[i/4] = Float.intBitsToFloat(accum);
}
return floatRet;
}
然后就是将bytes数组存入数据库。我使用的Litepal定义byte数据进行存储的,当然,使用greendao或者自己写也是可以的。