首页 > 解决方案 > react-native-camera中YUV_420_888格式的算法旋转

问题描述

下面是来自 react-native-camera 的旋转代码,以支持 ZXING 库检测条形码。具体链接在这里

    private byte[] rotateImage(byte[] imageData, int width, int height) {
        byte[] rotated = new byte[imageData.length];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                rotated[x * height + height - y - 1] = imageData[x + y * width];
            }
        }
        return rotated;
    }

imageData是 YUV_420_888 格式

我知道它是旋转一个框架,但它是如何真正工作的?它是旋转 90 度还是 180 度?顺时针还是逆时针?

我很难用我输入的示例图像来测试它,所以完全不理解它。

标签: androidimagealgorithmreact-nativemath

解决方案


您发布的代码将每像素 1 个字节的单色(灰度)图像顺时针旋转 90 度,并将其返回到一个新的字节数组中。它不处理任何色度信息。

YUV_420_888 图像格式以 YUV 格式存储图像,其中 Y 是亮度(灰度分量),首先存储在内存中,U 和 V 是色度分量,存储在亮度之后。为了节省空间,U 和 V 以亮度分量的水平和垂直分辨率的一半存储。

因为亮度分量是先存储的,如果你只是忽略它后面的色度通道,你可以把它当作单色图像,这就是代码所做的。

要进行实际的旋转,代码会遍历 y 和 x 中的所有像素。对于每个像素,它计算旋转图像中的新像素位置并将其复制到那里。

这是一个糟糕的图表,说明正在发生的事情:

在此处输入图像描述

YUV_420_888 一次存储一行像素,从上到下,从左到右。所以计算像素位置的数学是这样的:

old_pixel_location = (y * width) + x

正如您在图像中看到的那样,旧图像宽度变为新图像高度,反之亦然。旋转图像中的像素位置具有等于 x 值的 new_y 值,以及位于图像右侧左侧的 y 个像素的 new_x 值。

new_width = height
new_height = width
new_x = (new_width - 1) - y
new_y = x

新的像素位置是:

new_pixel_location = (new_y * new_width) + new_x

// substituting gives:
new_x = (height - 1) - y
new_pixel_location = (x * height) + ((height - 1) - y)

// removing brackets and re-ordering:
old_pixel_location = x + y * width
new_pixel_location = x * height + height - y - 1

推荐阅读