Camera2 api Imageformat.yuv_420_888旋转后的图像结果

问题描述:

很多关于camera2 api和RAW图像格式的问题,但在网上搜索我还没有找到答案(这就是为什么我在这里btw)。Camera2 api Imageformat.yuv_420_888旋转后的图像结果

我正在尝试使用ImageReader使用ImageReader以及setRepeatingRequest与前置摄像头对摄像头拍摄的帧进行一些实时图像处理。如上所述,在一些先前的文章建议,我获取图像中,以便一个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 ; 
} 

这种方法是相当快的,因为我可以在小于20ms转换1080的图像。唯一的问题是图像结果旋转了270度(即图像以横向模式拍摄)。即使我在相机编辑器设置中设置了JPEG_ORIENTATION,captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION));的结果仍然相同。

这里我的问题:

  • 是否有办法找回通过的renderScript内在一个旋转的图像?
  • 有没有不分配内存的“旋转”功能?
  • 是否有YUV类型的图像旋转设置? 我尝试过的其他解决方案 - 矩阵旋转,YUV阵列旋转 - 非常缓慢。此外,我认为将图像旋转90/180/270是一件容易的事情,如果在拍摄后完成,只需要保存行而不是列(以某种方式)。

不,没有内置的YUV输出旋转。为了尽量减少开销,它始终是从图像传感器生产的。您可以阅读SENSOR_ORIENTATION字段以确定图像传感器如何放置在设备上;通常情况下,图像传感器的长边与Android设备的长边对齐,但仍然会产生两次有效的旋转。此外,如果您的目标是让图像“直立”,那么您还需要阅读加速度计的设备方向,并将其添加到旋转中。

您正在做一个副本,已经从图像获取帧到分配,所以做90/180/270度旋转然后是相对直接的,虽然内存带宽密集型。

你也可以看一看谷歌的示例应用程序HdrViewfinderDemo,它将相机数据导入到RenderScript中,而不需要中间拷贝,然后转换为RGB以绘制成SurfaceView。它现在没有旋转,但可以通过rsGetElementAtYuv_uchar_ *完成90次增量调整查找。