Создание Bitmap ByteBuffer для квантованной модели Tensorflow Lite - PullRequest
1 голос
/ 28 мая 2020

Я хотел бы использовать модель квантованного tenorflow lite, но текущий ByteBuffer, который у меня есть, использует плавающую точку. Я бы хотел, чтобы это было целочисленное представление. Сейчас модели требуется 270000 байт, а я пытаюсь передать ей 1080000 байт. Это так же просто, как преобразование float в int?

public ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {

    // Preallocate memory for bytebuffer
    ByteBuffer byteBuffer = ByteBuffer.allocate(inputSize*inputSize*pixelSize);
    byteBuffer.order(ByteOrder.nativeOrder());

    // Initialize pixel data array and populate from bitmap
    int [] intArray = new int[inputSize*inputSize];
    bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0 , 0,
            bitmap.getWidth(), bitmap.getHeight());

    int pixel = 0;      // pixel indexer
    for (int i=0; i<inputSize; i++) {
        for (int j=0; j<inputSize; j++) {
            int input = intArray[pixel++];

            byteBuffer.putfloat((((input >> 16 & 0x000000FF) - imageMean) / imageStd));
            byteBuffer.putfloat((((input >> 8 & 0x000000FF) - imageMean) / imageStd));
            byteBuffer.putfloat((((input & 0x000000FF) - imageMean) / imageStd));
        }
    }
    return byteBuffer;
}

Спасибо за любые советы, которые вы можете дать.

1 Ответ

1 голос
/ 29 мая 2020

Преобразование float в int - неправильный подход. Хорошая новость заключается в том, что квантованные входные значения, ожидаемые моделью (8-битные значения r, g, b в последовательности), точно соответствуют представлению пикселей Bitmap, за исключением того, что модель не ожидает альфа-канала, поэтому процесс преобразования должно быть на самом деле проще, чем при использовании входов с плавающей запятой.

Вот что вы можете попробовать вместо этого. (Я предполагаю, что pixelSize равно 3)

int pixel = 0;      // pixel indexer
for (int i=0; i<inputSize; i++) {
    for (int j=0; j<inputSize; j++) {
        int input = intArray[pixel++];   // pixel containing ARGB.
        byteBuffer
            .put((byte)((input >> 16) & 0xFF))    // R
            .put((byte)((input >>  8) & 0xFF))    // G
            .put((byte)((input      ) & 0xFF));   // B
    }
}
...