Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:预览帧,从YCbCr_420_SP(NV21)格式转换为RGB格式,以绿色显示正确的图片_Android_Camera_Rgb_Yuv - Fatal编程技术网

Android:预览帧,从YCbCr_420_SP(NV21)格式转换为RGB格式,以绿色显示正确的图片

Android:预览帧,从YCbCr_420_SP(NV21)格式转换为RGB格式,以绿色显示正确的图片,android,camera,rgb,yuv,Android,Camera,Rgb,Yuv,我发布了这个问题,因为我在以下帖子中没有找到解决我问题的答案: 我的数据和相机分辨率(选择BestPreviewSize后)来自: 在转换为RGB之后,我使用: int[] pixels=new int[yuvData.length]; // int size = dataWidth*dataHeight; // int[] pixels=new int[size]; replacing yuvData.length by size is not working too p

我发布了这个问题,因为我在以下帖子中没有找到解决我问题的答案:

我的数据和相机分辨率(选择BestPreviewSize后)来自:

在转换为RGB之后,我使用:

  int[] pixels=new int[yuvData.length];
  // int size = dataWidth*dataHeight;
 //  int[] pixels=new int[size]; replacing yuvData.length by size is not working too
  pixels=decodeYUV420SP(pixels,yuvData, dataWidth, dataHeight);
    Bitmap bitmap = Bitmap.createBitmap(dataWidth, dataHeight, Bitmap.Config.RGB_565);
    bitmap.setPixels(pixels, 0, dataWidth, 0, 0, dataWidth, dataHeight);
我尝试了两种方法,一种是使用RenderScript,另一种是使用decodeYUV420SP:

public Bitmap convertYUV420_NV21toRGB8888_RenderScript(byte [] data,int W, int H, CaptureActivityOCR fragment) { 
    // https://stackoverflow.com/questions/20358803/how-to-use-scriptintrinsicyuvtorgb-converting-byte-yuv-to-byte-rgba 
  RenderScript rs;
  ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
  rs = RenderScript.create(fragment.getActivity());
  yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); //Create an intrinsic for converting YUV to RGB. 

  Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
  Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); //an Allocation will be populated with empty data when it is first created

  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); //an Allocation will be populated with empty data when it is first created

  in.copyFrom(data);//Populate Allocations with data.

  yuvToRgbIntrinsic.setInput(in); //Set the input yuv allocation, must be U8(RenderScript). 
  yuvToRgbIntrinsic.forEach(out); //Launch the appropriate kernels,Convert the image to RGB. 


  Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
  out.copyTo(bmpout); //Copy data out of Allocation objects.
  return bmpout;

}

int[]decodeYUV420SP(int[]rgb,字节[]yuv420sp,int-width,int-height){
Log.e(“摄像头”、“解码V420SP”);
//TODO自动生成的方法存根
最终整数帧大小=宽度*高度;
对于(int j=0,yp=0;j>1)*宽度,u=0,v=0;
对于(int i=0;i262143)r=262143;
如果(g<0)g=0;否则如果(g>262143)g=262143;
如果(b<0)b=0;否则如果(b>262143)b=262143;
rgb[yp]=0xff000000|((r>2)和0xff00)|((b>>10)和0xff);
}
}
返回rgb;
} 
但我仍然不知道为什么我得到了一些好的形象,但在绿色。(我有另一个黑白相间的类似方法正在运行) 除了上面的链接,我尝试了所有与这个主题相关的帖子,所以如果有人能帮我获得另一个提示,请?我可能会对申请的尺寸感到困惑

在OnPreviewFrame方法之后和转换为RGB方法之前的某个地方,我使用另一种方法和下面的说明,因为我需要旋转接收到的数据。我想知道这是否是问题的根源:

  byte[] rotatedData = new byte[data.length];
  for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++)
          rotatedData[x * height + height - y - 1] = data[x + y * width];
  }
  int tmp = width;
  width = height;
  height = tmp;
byte[]rotatedData=新字节[data.length];
对于(int y=0;y

请帮帮我?

我认为你的轮换程序是错误的。 它适用于亮度(Y),因此您可以在黑白图片上获得良好的效果,但在色度上却没有。如果宽度和高度是图片的尺寸,则根本不旋转色度值。 因此,您需要为色度添加第二个循环,并移动字节对(V和U)

如果您在没有此旋转的情况下尝试此操作,但仍有绿色图片,则问题也可能出在decodeYUV420SP函数中

yuv到rgba的转换没有一个通用公式。它必须与另一个匹配。
看看这里和这里

这个适合我

B = 1.164(Y - 16)                   + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)

这似乎与您使用的是唯一的浮动版本相同,因此您可以尝试其他版本

我建议在RenderScript旋转后旋转位图:

if (bmpout == null) {
     bmpout = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
rgbaAllocation.copyTo(bmpout);

if (matrixPostRotate90 == null) {
    matrixPostRotate90 = new Matrix();
    matrixPostRotate90.postRotate(90);
}

Bitmap rotatedBitmap = Bitmap.createBitmap(bmpout, 0, 0, w, h, matrixPostRotate90, true);

这个YUV到RGB公式使用浮点,比上面显示的公式慢。
B = 1.164(Y - 16)                   + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)
if (bmpout == null) {
     bmpout = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
}
rgbaAllocation.copyTo(bmpout);

if (matrixPostRotate90 == null) {
    matrixPostRotate90 = new Matrix();
    matrixPostRotate90.postRotate(90);
}

Bitmap rotatedBitmap = Bitmap.createBitmap(bmpout, 0, 0, w, h, matrixPostRotate90, true);