YUV与RGB图像的互转

  • RGB图像转YUV420通道图像代码

void rgb2YUV(cv::Mat srcImg)
{
    cv::imshow("srcImg", srcImg);
    int w = srcImg.cols;
    int h = srcImg.rows;
    int bufLen = w*h*3/2;
    unsigned char* pYuvBuf = new unsigned char[bufLen];
    FILE* pFileOut = fopen("test.yuv", "w+");
    cv::Mat yuvImg;
    cv::cvtColor(srcImg, yuvImg, CV_BGR2YUV_I420);
    imwrite("/Users/Guigu/Desktop/testyuv.jpg", yuvImg);
    memcpy(pYuvBuf, yuvImg.data, bufLen*sizeof(unsigned char));

    cv::imshow("YUV", yuvImg);
    waitKey(10);

    fwrite(pYuvBuf, bufLen*sizeof(unsigned char), 1, pFileOut);
    fclose(pFileOut);
    delete[] pYuvBuf; 
}
  • YUV图像转RGB图像代码

void YUV2rgb()
{
    int w = 1024;
    int h = 768;
    printf("yuv file w: %d, h: %d \n", w, h);    
    FILE* pFileIn = fopen("../Desktop/test.yuv", "rb+");
    int bufLen = w*h*3/2;
    unsigned char* pYuvBuf = new unsigned char[bufLen];
    int iCount = 0;

    fread(pYuvBuf, bufLen*sizeof(unsigned char), 1, pFileIn);

    cv::Mat yuvImg;
    yuvImg.create(h*3/2, w, CV_8UC1);
    memcpy(yuvImg.data, pYuvBuf, bufLen*sizeof(unsigned char));
    cv::Mat rgbImg;
    cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);

    cv::imshow("rgbimg", rgbImg);
    //imwrite("../Desktop/oupt.jpg", rgbImg);
    cv::waitKey(1);
    delete[] pYuvBuf;
    fclose(pFileIn);  
}
  • Tips: 测试的时候发现图像的长宽需要为偶数,原因可能是因为YUV的图像大小为RGB的weight*height*3/2,所有weight*height需要为2的倍数才行。
    如读入的图像长宽不为偶数,可同过如下方式把它变为偶数。
    Mat img_temp = imread(path,1);
    int x_=0;
    int y_=0;
    int w_=img_temp.cols%2==0?img_temp.cols:img_temp.cols-1;
    int h_=img_temp.rows%2==0?img_temp.rows:img_temp.rows-1;
    Rect roi(x_,y_,w_,h_);

    Mat img=img_temp(roi).clone();

关于YUV空间的详细介绍,可以参考下面这篇文章,看了就知道上面乘的系数为什么是3/2了。
http://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html

Reference:
http://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html
http://blog.csdn.net/carson2005/article/details/38351717

你可能感兴趣的:(图像处理)