Search code examples
c++image-processingrgbcolor-schemeyuv

YUV420 to RGB conversion not giving the same image?


I am creating dummy YUV420 image using following code-snippet.I want to create a copy of the same image in RGB format using the Y,U and V components.

I referred Wiki entry on YUV to RGB conversion but it doesnt give the same image as of YUV. Any suggestions ?

Edit : img is a QImage in RGB32 format (ARGB).

This is YUV420 image :enter image description here

This is what RGB conversion giving : enter image description here

 int clamp(int val){
        if(val>255) return 255;
        if(val<0) return 0;
        return val;
    }

    -----
    int h=height;
    int w=width;
    for(y=0;y<h ;y++){
        for(x=0;x<w;x++){

               int hy=y/2;
               int hx=x/2;

               //Populate YUV420 image      
               char compY=x+y+i*3; //Y component
               char compU=128+hy+(i)*2; //U component
               char compV=64+hx+(i)*5;  //V component

               //encoder.setInputPicturePixelData(0,y* l0+x,compY);
               //encoder.setInputPicturePixelData(1,hy*l1+hx,compU);                                 //encoder.setInputPicturePixelData(2,hy*l2+hx,compV);
               //encoder.setInputPicturePixelData(2,hy*l2+hx,compV);

              //Now create the RGB image 

               char R=clamp(compY+1.402*(compV-128));
               char G=clamp(compY-0.3444*(compU-128)-0.714*(compV-128));
               char B=clamp(compY+1.772*(compU-128));

               int RGBval=0xFF<<24 | R<<16 |  G<<8 | B;
               img->setPixel(x,y,RGBval);


             }
    }

Solution

  • char compY=x+y+i*3;

    Your image has width of 359 pixels, and you do not check if x or y are within [0..255] range. The value will probably overflow and wrap around.

    int RGBval=0xFF<<24 | R<<16 | G<<8 | B;

    Qt has qRgb and qRgba functions. You should use them instead of writing macros yourself.

    char R=clamp(compY+1.402*(compV-128));

    In C++ char is normally signed, and stores valus in range [-128..127]. So if you subtract 128 from any positive char value, you'll get negative number. Which is probably not what you want.

    Innstead of char use quint8, unsigned char or uint8_t.