很多關於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是一件容易的事情,如果在拍攝後完成,只需要保存行而不是列(以某種方式)。