Capturing image frames in YUV_420_888 format using ImageReader in Camera API 2 not giving correct results in...












1















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!










share|improve this question





























    1















    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!










    share|improve this question



























      1












      1








      1








      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!










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 2 at 13:47







      Sarthak Jana

















      asked Jan 2 at 13:33









      Sarthak JanaSarthak Jana

      64




      64
























          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
          });


          }
          });














          draft saved

          draft discarded


















          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
















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

          Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

          A Topological Invariant for $pi_3(U(n))$