我正在开发一个Android应用,该应用从相机预览中获取YUV_420_888格式的图像输入并将其转换为RGB等价物。这是一种心跳测量应用程序,当用户触摸相机表面时,它会从用户的指尖获取红色框。使用Camera API 2完成相机的实现,并使用ImageReader捕获图像帧,其格式设置为YUV_420_888。
imageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 1);
然后使用以下功能将YUV_420_888格式捕获的图像帧转换为RGB:
public static double[] decodeYUV420SP_888toRedBlueGreenAvg(byte[] Y1, byte[] U1, byte[] V1, int width, int height) {
int Width = width;
int Height = height;
byte[] ImageRGB = new byte[Width*Height*4];
double[] rgb =new double[3];
for(int i = 0; i<Height-1; i++){
for (int j = 0; j<Width; j++){
int Y = Y1[i*Width+j]&0xFF -16;
int U = U1[(i/2)*(Width/2)+j/2]&0xFF;
int V = V1[(i/2)*(Width/2)+j/2]&0xFF;
U = U-128;
V = V-128;
int R,G,B;
/*R = (int) (Y + 1.402*(V-128));
G = (int) (Y - 0.34414 *(U-128) - 0.71414 *(V-128));
B = (int) (Y + 1.772 *(U-128));*/
//correct values
R = (int)(Y + 1.140*V);
G = (int)(Y - 0.395*U - 0.581*V);
B = (int)(Y + 2.032*U);
/*int y1192 = 1192 * Y;
R = (y1192 + 1634 * V);
G = (y1192 - 833 * V - 400 * U);
B = (y1192 + 2066 * U);*/
/* Y_temp = 4768 * (Y - 16);
R = (Y_temp + 6537 * (V - 128)) >> 12;
G = (Y_temp - 3330 * (V - 128) - 1602 * (U - 128)) >> 12;
B = (Y_temp + 8266 * (U - 128)) >> 12;*/
//test
if (R>255) {
R = 255;
} else if (R<0) {
R = 0;
}
if (G>255) {
G = 255;
} else if (G<0) {
G = 0;
}
if (B>255) {
R = 255;
} else if (B<0) {
B = 0;
}
ImageRGB[i*4*Width+j*4] = (byte)R;
ImageRGB[i*4*Width+j*4+1] = (byte)G;
ImageRGB[i*4*Width+j*4+2] = (byte)B;
ImageRGB[i*4*Width+j*4+3] = -1;
rgb[0] = R;
rgb[1] = G;
rgb[2] = B;
}
}
return rgb;}
图像保护程序类如下:
private class ImageSaver implements Runnable {
byte[] y1, u1, v1;
int width, height;
public ImageSaver(byte[] y1, byte[] u1, byte[] v1, int width, int height) {
this.y1 = y1;
this.u1 = u1;
this.v1 = v1;
this.width = width;
this.height = height;
}
@Override
public void run() {
//if data or size == null ****
if (y1 == null)
throw new NullPointerException();
if (textureView == null) throw new NullPointerException();
current value == the expected value.
if (!processing.compareAndSet(false, true)) return;
//put width + height of the camera inside the variables
int width = textureView.getWidth();
int height = textureView.getHeight();
RGBAvg = YUVtoRGB.decodeYUV420SP_888toRedBlueGreenAvg(y1, u1, v1, width, height);
然后使用rgb值进行一些处理。 这对于单摄像头设备工作正常,但对于双摄像头设备,rgb值以绿色而不是红色显示。特别是在Oppo和少数Redmi设备中,例如Oppo F9 pro和Redmi 6 pro。
任何帮助将不胜感激!