I420转rgb

1.自己写转换方法

unsigned char* I420ToRGB(unsigned char* src, int width, int height){
    const int R = 0;
    const int G = 1;
    const int B = 2;
    int numOfPixel = width * height;
    int positionOfU = numOfPixel;
    int positionOfV = numOfPixel/4 + numOfPixel;
    unsigned char* rgb = new unsigned char[numOfPixel*3];

    for(int i=0; i<height; i++){
        int startY = i*width;
        int step = (i/2)*(width/2);
        int startU = positionOfV + step;
        int startV = positionOfU + step;
        for(int j = 0; j < width; j++){
            int Y = startY + j;
            int V = startV + j/2;
            int U = startU + j/2;
            int index = Y*3;
            rgb[index+B] = (unsigned char)((src[Y]&0xff) + 1.4075 * ((src[V]&0xff)-128));
            rgb[index+G] = (unsigned char)((src[Y]&0xff) - 0.3455 * ((src[U]&0xff)-128) - 0.7169*((src[V]&0xff)-128));
            rgb[index+R] = (unsigned char)((src[Y]&0xff) + 1.779 * ((src[U]&0xff)-128));
        }
    }

    return rgb;
}

2.借用opencv


#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

unsigned char* I420ToRGB(unsigned char* src, int width, int height){
    int numOfPixel = width * height;
    unsigned char* rgb = new unsigned char[numOfPixel*3];

    cv::Mat yuvImg;
    cv::Mat rgbImg(height, width, CV_8UC3);
    yuvImg.create(height * 3/2, width, CV_8UC1);
    memcpy(yuvImg.data, src, numOfPixel*3/2);
    cv::cvtColor(yuvImg, rgbImg, cv::ColorConversionCodes::COLOR_YUV2RGB_I420);

    memcpy_s(rgb, numOfPixel*3, rgbImg.data, numOfPixel*3);

    return rgb;
}

顺便opencv实现yuv转rgb

    //unsigned char *src 存的是YUYV的裸数据;
    cv::Mat yuvImg;
    cv::Mat rgbImg(height, width,CV_8UC3);
    yuvImg.create(height, width, CV_8UC2);
    memcpy(yuvImg.data, src, numOfPixel*2);
    cv::cvtColor(yuvImg, rgbImg, cv::ColorConversionCodes::COLOR_YUV2BGR_YUYV);

3.ffmpeg,实际运用中发现如果编解码视频opencv太费cpu了,于是尝试了ffmpeg


unsigned char* SCVidyoInstance::I420ToRGB(unsigned char* src, int width, int height){

    int numOfPixel = width * height;
    unsigned char* rgba = new unsigned char[numOfPixel*4];

    AVFrame  *frmArgb = av_frame_alloc();
    AVFrame  *frm420p = av_frame_alloc();

    //绑定数据缓冲区
    avpicture_fill((AVPicture *)frmArgb, rgba, AV_PIX_FMT_RGBA, width, height);
    avpicture_fill((AVPicture *)frm420p, src, AV_PIX_FMT_YUV420P, width, height);

    //指定原数据格式,分辨率及目标数据格式,分辨率
    struct SwsContext *sws = sws_getContext(width, height, AV_PIX_FMT_YUV420P, width, height, AV_PIX_FMT_RGBA,
                                            SWS_BILINEAR, NULL, NULL, NULL);

    //转换
    sws_scale(sws, frm420p->data, frm420p->linesize, 0, height, frmArgb->data, frmArgb->linesize);
    av_frame_free(&frmArgb);
    av_frame_free(&frm420p);
    sws_freeContext(sws);

    return rgba;
}

cpu使用率瞬间降低了不少

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值