当前位置: 首页 > 知识库问答 >
问题:

Camera2 api ImageFormat.yuv_420_888旋转图像的结果

金钊
2023-03-14

很多关于camera2 api和RAW图像格式的问题已经提出,但是在网上搜索我仍然没有找到答案(这就是为什么我在这里顺便说一句)。

我正在尝试使用ImageReader和设置RepeatingRequest对摄像头捕获的帧进行一些实时图像处理。正如之前的一些帖子中所建议的,我正在获取RAW格式的图像(特别是ImageFormat.yuv_420_888),以获得大约30fps的帧速率:

  imageReader = ImageReader.newInstance(width, height, ImageFormat.YUV_420_888, 2); 

我的图像处理算法需要一个RGB图像作为输入,所以我需要从YUV转换成RGB。为此,我使用ScriptIntrinsicYuvToRGB

  private static Bitmap YUV_420_888_toRGBIntrinsics(Image image) {

    if (image == null) return null;

    int W = image.getWidth();
    int H = image.getHeight();

    Image.Plane Y = image.getPlanes()[0];
    Image.Plane U = image.getPlanes()[1];
    Image.Plane V = image.getPlanes()[2];

    int Yb = Y.getBuffer().remaining();
    int Ub = U.getBuffer().remaining();
    int Vb = V.getBuffer().remaining();

    byte[] data = new byte[Yb + Ub + Vb];


    Y.getBuffer().get(data, 0, Yb);
    V.getBuffer().get(data, Yb, Vb);
    U.getBuffer().get(data, Yb + Vb, Ub);



    rs = RenderScript.create(context);
    ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));

    Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
    Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);

    Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
    Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);


    final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888); 

    in.copyFromUnchecked(data);

    yuvToRgbIntrinsic.setInput(in);
    yuvToRgbIntrinsic.forEach(out);
    out.copyTo(bmpout);
    image.close();
    return bmpout ;
}

这个方法是相当快的,因为我可以转换1080p的图像在不到20ms。唯一的问题是图像结果被旋转了270度(即图片是在风景模式下拍摄的)。即使我在camera builder设置中设置了JPEG_ORIENTATION,CapturerRequestBuilder.set(capturerRequest.JPEG_ORIENTATION,characteristics.get(cameracharacteristics.sensor_Orientation));,结果仍然相同。

我的问题是:

  • 有没有办法通过renderscript的内部特性返回旋转后的图像?
  • 是否存在不分配内存的“旋转”函数?
  • 有YUV类型的图像旋转设置吗?我尝试过的其他解决方案--矩阵旋转、YUV阵列旋转--都相当慢。此外,我认为将图像旋转90/180/270是一个很容易的任务,如果在拍摄完图像之后完成,只需要保存行而不是列(以某种方式)。

共有1个答案

田易安
2023-03-14

不,YUV输出没有内置的旋转。为了最大限度地减少开销,它总是从图像传感器原样产生。您可以读取SENSOR_ORIENTATION字段以确定图像传感器如何放置在设备上;通常情况下,图像传感器的长边与Android设备的长边对齐,但仍有两个旋转是有效的。

此外,如果你的目标是使图像“直立”,那么你还需要从加速度计读取设备的方位,并将其添加到旋转中。

您正在进行一个拷贝,将图像中的帧放入分配中,因此进行90/180/270度旋转相对简单,尽管需要占用大量内存带宽。

你还可以看看谷歌的一个示例应用程序HdrViewfinderDemo,它将相机数据传送到RenderScript,而不需要进行中间复制,然后转换为RGB以绘制到SurfaceView。它现在没有旋转,但是您可以通过rsgetElementatYUV_uchar_*调整查找,以执行90次增量。

 类似资料:
  • 问题内容: 我需要能够单独旋转图像(在Java中)。到目前为止,我发现的唯一东西是g2d.drawImage(image,affinetransform,ImageObserver)。不幸的是,我需要在特定点绘制图像,并且没有一种方法带有参数1.分别旋转图像和2.允许我设置x和y。任何帮助表示赞赏 问题答案: 这就是你可以做到的。这段代码假设存在一个名为“ image”的缓冲图像(如你的评论所说)

  • 本节,我们通过平移和旋转画布上下文来旋转图像,然后在变换后的上下文中绘制图像。 图4-11 旋转图像 绘制步骤 按照以下步骤,来旋转图像: 1. 定义画布上下文: window.onload = function(){ var canvas  = document.getElementById("myCanvas"); var context = canvas.getContext("2

  • 在Javafx中旋转图像? 我正在写 但是图像不会相对于图像的中心旋转。

  • 问题内容: 我想找出悬停时如何制作 旋转或旋转的图像 。我想知道如何在以下代码上使用 CSS 模仿该功能: 问题答案: 您可以将CSS3过渡与一起使用,以 在悬停时旋转图像 。 旋转图像:

  • 问题内容: 我有一张Pan Card的图像,当我尝试将其旋转45度并保存时,会得到裁剪的图像。旋转图像的代码是: 问题答案: 使用AffineTransform看一下这个例子: http://www.billthelizard.com/2008/07/rotate-image-in- java.html 有一些代码可以加载图像,这就是核心:

  • 问题内容: 我有一个方法需要旋转,将其存储在新变量中,然后返回new 。这是我的尝试,图像似乎为空或什么。它只是不显示在屏幕上: 当我取出图像时,在屏幕上绘制的图像就很好,没有问题,但是当然没有旋转。 问题答案: 因此,基于此答案中的示例,您应该能够设计一种旋转方法,该方法可以将源图像旋转给定的度数,例如…