Capturing image frames in YUV_420_888 format using ImageReader in Camera API 2 not giving correct results in...
I'm working on an android app which takes image input from camera preview in YUV_420_888 format and converts it into its RGB equivalent. It is a heart beat measuring app which takes red color frames from user's finger tip when the user touches the camera surface. The camera implementation is done using Camera API 2 and the images frames are captured using ImageReader whose format is set to YUV_420_888.
imageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 1);
The image frames captured in YUV_420_888 format is then converted into RGB using the following function:
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;}
The image saver class is as follows:
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);
Then some processing is done using the rgb values.
This is working fine for single camera devices but for dual camera device the rgb values are coming as green colors rather than red. Especially in Oppo and few Redmi devices devices such as Oppo F9 pro and Redmi 6 pro.
Any help will be highly appreciated!
android android-camera2
add a comment |
I'm working on an android app which takes image input from camera preview in YUV_420_888 format and converts it into its RGB equivalent. It is a heart beat measuring app which takes red color frames from user's finger tip when the user touches the camera surface. The camera implementation is done using Camera API 2 and the images frames are captured using ImageReader whose format is set to YUV_420_888.
imageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 1);
The image frames captured in YUV_420_888 format is then converted into RGB using the following function:
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;}
The image saver class is as follows:
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);
Then some processing is done using the rgb values.
This is working fine for single camera devices but for dual camera device the rgb values are coming as green colors rather than red. Especially in Oppo and few Redmi devices devices such as Oppo F9 pro and Redmi 6 pro.
Any help will be highly appreciated!
android android-camera2
add a comment |
I'm working on an android app which takes image input from camera preview in YUV_420_888 format and converts it into its RGB equivalent. It is a heart beat measuring app which takes red color frames from user's finger tip when the user touches the camera surface. The camera implementation is done using Camera API 2 and the images frames are captured using ImageReader whose format is set to YUV_420_888.
imageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 1);
The image frames captured in YUV_420_888 format is then converted into RGB using the following function:
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;}
The image saver class is as follows:
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);
Then some processing is done using the rgb values.
This is working fine for single camera devices but for dual camera device the rgb values are coming as green colors rather than red. Especially in Oppo and few Redmi devices devices such as Oppo F9 pro and Redmi 6 pro.
Any help will be highly appreciated!
android android-camera2
I'm working on an android app which takes image input from camera preview in YUV_420_888 format and converts it into its RGB equivalent. It is a heart beat measuring app which takes red color frames from user's finger tip when the user touches the camera surface. The camera implementation is done using Camera API 2 and the images frames are captured using ImageReader whose format is set to YUV_420_888.
imageReader = ImageReader.newInstance(smallest.getWidth(), smallest.getHeight(), ImageFormat.YUV_420_888, 1);
The image frames captured in YUV_420_888 format is then converted into RGB using the following function:
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;}
The image saver class is as follows:
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);
Then some processing is done using the rgb values.
This is working fine for single camera devices but for dual camera device the rgb values are coming as green colors rather than red. Especially in Oppo and few Redmi devices devices such as Oppo F9 pro and Redmi 6 pro.
Any help will be highly appreciated!
android android-camera2
android android-camera2
edited Jan 2 at 13:47
Sarthak Jana
asked Jan 2 at 13:33
Sarthak JanaSarthak Jana
64
64
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54007316%2fcapturing-image-frames-in-yuv-420-888-format-using-imagereader-in-camera-api-2-n%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54007316%2fcapturing-image-frames-in-yuv-420-888-format-using-imagereader-in-camera-api-2-n%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown