2016-11-30 4 views
0

Я работаю с камерой2, а в ImageReader у меня есть формат YUV_420_888. Я огляделся и нашел некоторые формулы для преобразования его в RGB. Но у меня проблема с некоторыми цветами. Вот код, который преобразует его в RGB:YUV_420_888 для преобразования RGB

ByteBuffer buffer0 = image.getPlanes()[0].getBuffer(); 
byte[] Y1 = new byte[buffer0.remaining()]; 
buffer0.get(Y1); 
ByteBuffer buffer1 = image.getPlanes()[1].getBuffer(); 
byte[] U1 = new byte[buffer1.remaining()]; 
buffer1.get(U1); 
ByteBuffer buffer2 = image.getPlanes()[2].getBuffer(); 
byte[] V1 = new byte[buffer2.remaining()]; 
buffer2.get(V1); 
int Width = image.getWidth(); 
int Heigh = image.getHeight(); 
byte[] ImageRGB = new byte[image.getHeight()*image.getWidth()*4]; 

for(int i = 0; i<Heigh-1; i++){ 
    for (int j = 0; j<Width; j++){ 
     int Y = Y1[i*Width+j]&0xFF; 
     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.140*V); 
     G = (int)(Y - 0.395*U - 0.581*V); 
     B = (int)(Y + 2.032*U); 
     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; 
    } 
} 

И когда я точка камеру на какой-то цвет this происходит. Любая идея, почему и как я могу это исправить?

EDIT: Вот код, который я использовал для размещения на SurfaceView, но я думаю, что его правильно

Bitmap bm = Bitmap.createBitmap(image.getWidth(), image.getHeight(), 

Bitmap.Config.ARGB_8888); 
bm.copyPixelsFromBuffer(ByteBuffer.wrap(ImageRGB)); 
Bitmap scaled = Bitmap.createScaledBitmap(bm, surfaceView.getWidth(), surfaceView.getHeight(), true); 
Canvas c; 
c = surfaceHolder.lockCanvas(); 
c.drawBitmap(scaled, 0, 0, null); 
surfaceHolder.unlockCanvasAndPost(c); 
image.close(); 

ответ

2

Это не выглядит как правильно YUV-> RGB преобразования. Цветовое пространство камеры 2 для YUV_420_888 с устройства камеры - это цветовое пространство JFIF YUV (то же, что и внутри файлов JPEG). К сожалению, в настоящее время это не зафиксировано.

JFIF YUV-> RGB преобразование определяется быть следующим в JPEG JFIF specification:

R = Y + 1.402 (Cr-128) 
G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128) 
B = Y + 1.772 (Cb-128) 

Так что попробуйте начать с. И для полного прояснения, Cb = U, Cr = V.

+0

Это лучше, но все же не идеально. [Здесь] (https://s14.postimg.org/pplh5spch/Screenshot_2016_11_30_23_26_13.png) является ссылкой для изображения, которое я получаю после изменения. Я буду обновлять оригинальное сообщение для публикации на SurfaceView, возможно, я тоже что-то не так понял ... – Nikola010

+0

В чем проблемы с этим изображением? Нет ничего, что сразу выглядит неправильно окрашенным мне или иным образом коррумпированным, но это трудно сказать, так как я не знаю, как он должен выглядеть. –

+0

Здесь я взял два новых изображения, [один] (http://postimg.org/image/4ecm0k4lt/) с моим приложением камеры, [второй] (http://postimg.org/image/im2ap7hap/) - снимок экрана из мое приложение. Если вы посмотрите на облака, вы можете увидеть тот же цвет, что и на первой фотографии ноутбука, здесь, но гораздо меньше. – Nikola010

0

Существует ошибка в коде

if (B>255) { 
     B = 255; //was R = 255; 
    } else if (B<0) { 
     B = 0; 
    } 

И попробуйте использовать оба варианта

R = Y + 1.402 * V 
G = Y - 0.34414 * U - 0.71414 * V 
B = Y + 1.772 * U 

Or from here:

R = yValue + (1.370705 * V); 
G = yValue - (0.698001 * V) - (0.337633 * U); 
B = yValue + (1.732446 * U); 
Смежные вопросы