【问题标题】:How to create a ByteBuffer from Bitmap using grayscale pixel value?如何使用灰度像素值从位图创建 ByteBuffer?
【发布时间】:2018-08-25 18:57:07
【问题描述】:

我正在尝试在我的 android 应用程序中使用 tflite 模型。当我必须从位图创建一个 ByteBuffer 并将其用作模型的输入时,就会出现问题。

问题:位图是 ARGB_8888(32 位),而我需要(8 位)灰度图像。

Bitmap转ByteBuffer的方法:

mImgData = ByteBuffer
                .allocateDirect(4 * 28 * 28 * 1);

private void convertBitmapToByteBuffer(Bitmap bitmap) throws NullPointerException {
    if (mImgData == null) {
        throw new NullPointerException("Error: ByteBuffer not initialized.");
    }

    mImgData.rewind();

    for (int i = 0; i < DIM_IMG_SIZE_WIDTH; i++) {
        for (int j = 0; j < DIM_IMG_SIZE_HEIGHT; j++) {
            int pixelIntensity = bitmap.getPixel(i, j);
            unpackPixel(pixelIntensity, i, j);
            Log.d(TAG, String.format("convertBitmapToByteBuffer: %d -> %f", pixelIntensity, convertToGrayScale(pixelIntensity)));
            mImgData.putFloat(convertToGrayScale(pixelIntensity));
        }
    }

}

private float convertToGrayScale(int color) {
    return (((color >> 16) & 0xFF) + ((color >> 8) & 0xFF) + (color & 0xFF)) / 3.0f / 255.0f;
}

但是,所有像素值都是 -1 或 -16777216。请注意,here 提到的 unpackPixel 方法不起作用,因为无论如何所有值都具有相同的 int 值。 (张贴以下更改以供参考。)

private void unpackPixel(int pixel, int row, int col) {
    short red,green,blue;
    red = (short) ((pixel >> 16) & 0xFF);
    green = (short) ((pixel >> 8) & 0xFF);
    blue = (short) ((pixel >> 0) & 0xFF);
}

【问题讨论】:

    标签: java android bitmap


    【解决方案1】:

    您可以在像素值上调用Color.red() 或绿色/蓝色,它将返回灰度强度。然后使用putFloat() 将其放入字节缓冲区。使用bitmap.getPixels() 获取单个数组中的所有像素值也比bitmap.getPixel(i, j) 快​​。以下是我在 tflite 模型中加载灰度图像的方法:

    private ByteBuffer getByteBuffer(Bitmap bitmap){
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        ByteBuffer mImgData = ByteBuffer
                .allocateDirect(4 * width * height);
        mImgData.order(ByteOrder.nativeOrder());
        int[] pixels = new int[width*height];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        for (int pixel : pixels) {
            mImgData.putFloat((float) Color.red(pixel));
        }
        return mImgData;
    }
    

    如果您需要标准化值,只需除以 255:

    float value = (float) Color.red(pixel)/255.0f;
    mImgData.putFloat(value);
    

    然后你可以在你的解释器中使用它:

    ByteBuffer input = getByteBuffer(bitmap);
    tflite.run(input, outputValue);
    

    希望这可以帮助人们在未来寻找这个!

    【讨论】:

      猜你喜欢
      • 2015-05-30
      • 2017-08-21
      • 2015-06-29
      • 2020-02-21
      • 2020-05-15
      • 1970-01-01
      • 2015-12-01
      • 2015-10-26
      • 1970-01-01
      相关资源
      最近更新 更多