Converting YUV into BGR or RGB in OpenCV
In newer version of OPENCV
there is a built in function can be used to do YUV
to RGB
conversion
cvtColor(src,dst,CV_YUV2BGR_YUY2);
specify the YUV
format after the underscore, like this CV_YUYV2BGR_xxxx
It looks to me like you're decoding a YUV422 stream as YUV444. Try this modification to the code you provided:
for(int i = 0, j=0; i < 1280 * 720 * 3; i+=6, j+=4){ m_RGB->imageData[i] = pData[j] + pData[j+3]*((1 - 0.299)/0.615); m_RGB->imageData[i+1] = pData[j] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587)); m_RGB->imageData[i+2] = pData[j] + pData[j+1]*((1 - 0.114)/0.436); m_RGB->imageData[i+3] = pData[j+2] + pData[j+3]*((1 - 0.299)/0.615); m_RGB->imageData[i+4] = pData[j+2] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587)); m_RGB->imageData[i+5] = pData[j+2] + pData[j+1]*((1 - 0.114)/0.436);}
I'm not sure you've got your constants correct, but at worst your colors will be off - the image should be recognizable.
I use the following C++ code using OpenCV to convert yuv data (YUV_NV21) to rgb image (BGR in OpenCV)
int main(){ const int width = 1280; const int height = 800; std::ifstream file_in; file_in.open("../image_yuv_nv21_1280_800_01.raw", std::ios::binary); std::filebuf *p_filebuf = file_in.rdbuf(); size_t size = p_filebuf->pubseekoff(0, std::ios::end, std::ios::in); p_filebuf->pubseekpos(0, std::ios::in); char *buf_src = new char[size]; p_filebuf->sgetn(buf_src, size); cv::Mat mat_src = cv::Mat(height*1.5, width, CV_8UC1, buf_src); cv::Mat mat_dst = cv::Mat(height, width, CV_8UC3); cv::cvtColor(mat_src, mat_dst, cv::COLOR_YUV2BGR_NV21); cv::imwrite("yuv.png", mat_dst); file_in.close(); delete []buf_src; return 0;}
and the converted result is like the image yuv.png.
you can find the testing raw image from here and the whole project from my Github Project