'View .bin file (YCbCr 4:2:2 format)

I am given a .bin file. I know that the elements in this file correspond to Y Cb Cr values (4:2:2). Also, the data type is 8 bits. How can I view this?

I found a pretty good site: http://rawpixels.net/ which does what is expected but for YUV format. I want for YCbCr format.

Priliminary google search gives conversion to RGB, which is not desired. I have attached an example .bin file on dropbox. The size of image is 720 X 576.



Solution 1:[1]

From Wikipedia

Y?CbCr is often confused with the YUV color space, and typically the terms YCbCr and YUV are used interchangeably, leading to some confusion; when referring to signals in video or digital form, the term "YUV" mostly means "Y?CbCr".

If you are on a linux-based system and have access to ffmpeg, the following command correctly displays the data

ffplay -f rawvideo -video_size 720x576 -pix_fmt yuyv422 38.bin

enter image description here

Another good tool for displaying of RGB/YCbCr images is vooya which is free for linux but not for windows.

My own tool, yuv-viewer works as well.

Hope this helps.

Solution 2:[2]

You can up-sample the 4:2:2 down-sampled chroma like this:

////////////////////////////////////////////////////////////////////////////////
// unpack.c
// Mark Setchell
//
// Convert YCbCr 4:2:2 format file to full YCbCr without chroma subsampling
//
// Compile with:
//    gcc -o unpack unpack.c
// Run with:
//    ./unpack < input.bin > output.bin
////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/types.h>

int main(){
    unsigned char ibuf[4];  // Input data buffer format: Y Cb Y Cr
    unsigned char obuf[6];  // Output data buffer format: Y Cb Cr Y Cb Cr

    // Read 4 bytes at a time, and upsample chroma
    while(fread(ibuf,4,1,stdin)==1){
       obuf[0]=ibuf[0];
       obuf[1]=ibuf[1];
       obuf[2]=ibuf[3];
       obuf[3]=ibuf[2];
       obuf[4]=ibuf[1];
       obuf[5]=ibuf[3];
       fwrite(obuf,6,1,stdout);
    }
    return 0;
}

Then you would run this to up-sample:

./unpack < input.bin > output.bin

and then use ImageMagick convert to get a PNG (or JPEG, or TIF) like this:

convert -size 720x576 -depth 8 yuv:result.bin  image.png

enter image description here

In theory, ImageMagick should be able to do the up sampling itself (and not need a C program) with a command line like this, but I can't seem to make it work:

convert -interlace none -sampling-factor 4:2:2 -size 720x576 -depth 8 yuv:input.bin image.jpg

If anyone knows why - please comment!

Solution 3:[3]

This is a slightly different version of my other answer, insofar as it up-samples the chroma, and also converts the YUV to RGB and then creates a NetPBM PNM format file. That means that you only need to install the pnmtopng utility from NetPBM to get to a PNM image - and NetPBM is much lighter weight and simpler to install than ImageMagick.

////////////////////////////////////////////////////////////////////////////////
// yuv2pnm.c
// Mark Setchell
//
// Convert YUV 4:2:2 format file to RGB PNM format without chroma subsampling
//
// Compile with:
//    gcc -o yuv2pnm yuv2pnm.c
//
// Run with:
//    ./yuv2pnm < input.bin > output.pnm
//
// and then use ImageMagick to go to PNG format, or JPEG or TIF, with
//
//    convert output.pnm image.png
//
// or, all in one line (still with ImageMagick) to JPEG:
//
//    ./yuv2pnm < input.bin | convert pnm:- image.jpg
//
// or, use the (simpler-to-install) NetPBM's "pnmtopng" to convert to a PNG file
//
//    ./yuv2pnm < input.bin | pnmtopng - > image.png
////////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#define MIN(a,b)    (a<b) ? a : b

void YUV2RGB(unsigned char Y,unsigned char U, unsigned char V,unsigned char *RGB)
{
    int R,G,B;
    R = Y + (1.370705 * (V-128));
    G = Y - (0.698001 * (V-128)) - (0.337633 * (U-128));
    B = Y + (1.732446 * (U-128));
    RGB[0] = MIN(255,R);
    RGB[1] = MIN(255,G);
    RGB[2] = MIN(255,B);
}

int main(int argc,char* argv[]){

    unsigned char buf[4];   // Input data buffer format:  Y Cb Y Cr
    unsigned char RGB[6];   // Output data buffer format: R G B R G B
    int width=720;
    int height=576;

    // Write PNM header
    fprintf(stdout,"P6\n");
    fprintf(stdout,"%d %d\n",width,height);
    fprintf(stdout,"255\n");    

    // Read 4 bytes at a time, upsample chroma and convert to 2 RGB pixels
    while(fread(buf,4,1,stdin)==1){
       YUV2RGB(buf[0],buf[1],buf[3],&RGB[0]);
       YUV2RGB(buf[2],buf[1],buf[3],&RGB[3]);
       fwrite(RGB,6,1,stdout);
    }
    return 0;
}

NetPBM format is described here. Note PNM is an abbreviation that includes PPM.

Solution 4:[4]

Find below formula to convert YUV data into RGB.

R = Y + 1.4075 * (V - 128)
G = Y - 0.3455 * (U - 128) - (0.7169 * (V - 128))
B = Y + 1.7790 * (U - 128)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fredrik Pihl
Solution 2 Mark Setchell
Solution 3 Mark Setchell
Solution 4 abhishek kumar