YUV学习之二

上回对YUV文件进行了简单的介绍,下面主要是项目中的部分实验内容,首先生成YUV文件,没有文件我就用RGB转换,很点单opencv中有现成的,转化成420格式,但是转化后需要我们按照420规则保存到YUV文件中,具体代码是:

    Mat src = imread("1.bmp");
    Mat dst;
    cvtColor(src, dst, CV_BGR2YUV_I420);
    int length = src.cols*src.rows * 3 / 2;
    uchar *pBufY = new uchar[length];
    errno_t er;
    FILE *fp;
    er = fopen_s(&fp, "result_288.yuv", "w+");
    if (!fp)
    {
        printf("pFileOut open error \n");
        system("pause");
        exit(-1);
    }
    memcpy(pBufY, dst.data, length*sizeof(uchar));
    fwrite(pBufY, length*sizeof(uchar), 1, fp);
    fclose(fp);
    delete pBufY;

其中主要是fopen_s和fwrite的结合还有memcpy,会用这个就行了。

接着我进行了将8位的YUV转化生16YUV,在转化的同时我又进行了插值放大和增强。具体代码:

YUV sg;
    errno_t err;
    FILE *pFile;
    err = fopen_s(&pFile, "result.yuv", "rb");//读取8位图像
    if (pFile == 0) return;
    Mat imgY;
    int len = Width*Height;
    imgY.create(Size(Width, Height), CV_16UC3);
    uchar *Y = new uchar[len];
    uchar *U = new uchar[len / 4];
    uchar *V = new uchar[len / 4];
    _fseeki64(pFile, 0, SEEK_SET);
    fread(Y, len, 1, pFile);
    fread(U, 1, len / 4, pFile);
    fread(V, 1, len / 4, pFile);
    //foo(Y, U, V, src);
    Mat imageY = sg.uint8to16(Y, Width, Height);
    Mat imageU = sg.uint8to16(U, Width / 2, Height / 2);
    Mat imageV = sg.uint8to16(V, Width / 2, Height / 2);
    float amount = 1;
    int threshold = 0;
    resize(imageY, imageY, Size(Width * 2, Height * 2), 0, 0, 2);
    resize(imageU, imageU, Size(imageU.cols * 2, imageU.rows * 2), 0, 0, 2);
    resize(imageV, imageV, Size(imageV.cols * 2, imageV.rows * 2), 0, 0, 2);

    Mat imageBlur;
    GaussianBlur(imageY, imageBlur, Size(0, 0), 3, 3, 4);
    Mat lowcontrastmask = abs(imageY - imageBlur) < threshold;
    Mat imgDst = imageY*(1 + amount) + imageBlur * (-amount);
    imageY.copyTo(imgDst, lowcontrastmask);

    ////////////////////////////////////////////
    //              save
    ////////////////////////////////////////////
    int len2 = imgDst.cols*imgDst.rows;
    UINT16 *pBufy = new UINT16[len2 * 3 / 2];

    memcpy(pBufy, imgDst.data, len2*sizeof(UINT16));
    memcpy(pBufy + len2, imageU.data, len2*sizeof(UINT16) / 4);
    memcpy(pBufy + len2 * 5 / 4, imageV.data, len2*sizeof(UINT16) / 4);

    errno_t err1;
    FILE *pFiles;
    err1 = fopen_s(&pFiles, "result_576.yuv", "wb+");
    if (!pFiles)
    {
        printf("FileOut open error \n");
        system("pause");
        exit(-1);
    }
    fwrite(pBufy, len2 * 3 * sizeof(UINT16) / 2, 1, pFiles);
    fclose(pFiles);
    delete pBufy;

这里只讨论转化过程和存储时注意的事项,忘记一个事情就是转化代码没放上去

Mat YUV::uint8to16(uchar *Y, int width, int height)
{
    IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
    cvSetData(img, Y, width);
    Mat image(img, 0);
    image.convertTo(image, CV_16UC1, 257.0);
    return image;
}

保存的时候注意memcpy是按照其实地址,按照字节为单位进行拷贝,其中长度为size,所以我在保存Y之后,需要偏移Y长度的地址,再保持U,最后V也是这个道理,由于16位是2个字节,不要忘记加上去。对于16位的yuv需要下载的YUV播放器的支持,还好同事帮忙给了一个,成功显示。
这周任务完成,估计下次就写反卷积算法了,少玩点,多学点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值