I have a RGBA image in binary format(.raw) and I am trying to convert the image into YCbCr using C++. However the converted image when viewed using ffplay give me a green image. What could I be doing wrong? I have a code to reproduce the problem I am facing. The input image looks like this: https://drive.google.com/file/d/1oDswYmmSV0pfNe-u8Do06WWVu2v1B-rg/view?usp=sharing and the snapshot of the converted image is https://drive.google.com/file/d/1G8Rut3CXILqbmlGrFQsnushy2CLKu40w/view?usp=sharing. The input RGBA .raw image can be obtained here: https://drive.google.com/file/d/19JhMjRdibGCgaUsE6DBGAXGTRiT2bmTM/view?usp=sharing
#include <fstream>
#include <iostream>
#include <vector>
#include <array>
typedef unsinged char byte;
int main(){
std::ifstream infile;
std::ofstream outfile;
const unsigned width = 1280;
const unsigned height = 720;
std::vector<std::array<byte, 4>> imageBuffer;
std::vector<std::array<byte, 3>> output;
imageBuffer.resize(width*height);
output.resize(width*height);
infile.open("input.raw", std::ios::binary);
if(infile){
infile.read(reinterpret_cast<char*>(&imageBuffer[0]), width*height*4*sizeof(char));
}
for (unsigned y=0; y<height; ++y){
for(unsigned x=0; x<width; ++x){
byte R, G, B, A;
R = imageBuffer[y*width + x][0];
G = imageBuffer[y*width + x][1];
B = imageBuffer[y*width + x][2];
byte Y, Cb, Cr;
Y = 0.257*R + 0.504*G + 0.098*B + 16;
Cb = -0.148*R - 0.291*G + 0.439*B + 128;
Cr = 0.439*R - 0.368*G - 0.071*B + 128;
output[y*width + x][0] = Y;
output[y*width + x][1] = Cb;
output[y*width + x][2] = Cr;
}
}
std::ofstream os("output444.yuv", std::ios::binary);
if(!os)
return false;
os.write(reinterpret_cast<char*>(&output[0]), 1280*720*3*sizeof(char));}
Your code is fine for
YUV_4_4_4 8-bit-Packed
. You can view it withYUView
: https://github.com/IENT/YUView/releases and select the settings:It will display just fine.
However, if you are seeing it
Green
or whatever wrong colours, it means the program reading it is expecting a different format. Most likely it is expectingplanar
format which means you need to write allY
bytes first. Then writeCb
bytes, thenCr
bytes.So it'd look like (
YCbCr_4_4_4_Planar
):instead of packed which looks like (Your code above =
YCbCr_4_4_4_Packed
/Interleaved
):Below I wrote some code that can handle multiple formats. It'll take a
RAW
image format and convert it to either: