YUV 422 PACKED格式raw图怎么转PNG图

如题,python如何转化,cv2.COLOR_YUV2RGB_Y422,用这个参数转出来图片色彩不对。该用哪个呢

确定是RGB吗,不是RGBA也不是BGR。
或者在这个420p的基础上稍微修改,改成422的

void bgr2yuv420p(uchar *rgb24, int width, int height, uchar *yuv420p)
{
    uchar *ptrY, *ptrU, *ptrV;
    memset(yuv420p, 0, width * height * 3 / 2);
    ptrY = yuv420p; ptrU = yuv420p + width * height;
    ptrV = ptrU + (width * height * 1 / 4);
    uchar y, u, v, r, g, b;
    int index = 0;
    for (int j = 0; j < height; j++)
    {
        for (int i = 0; i < width; i++)
        {
            index = width * j * 3 + i * 3;
            b = rgb24[index];
            g = rgb24[index + 1];
            r = rgb24[index + 2];
            y = (uchar) ((66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
            u = (uchar) ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
            v = (uchar) ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
            *(ptrY++) = clipValue(y, 0, 255);
            if (j % 2 == 0 && i % 2 == 0)
            {
                *(ptrU++) = clipValue(u, 0, 255);
            }
            else if (i % 2 == 0)
            {
                *(ptrV++) = clipValue(v, 0, 255);
            }
        }
    }
}


int yuv420p2bgr(uchar *data, int width, int height,Mat &bgrimg)
{
    if(!data)
    {
        std::cerr<<"invalid input & output argument-yuv420pdata in yuv420p2bgr()!"<<endl;
    }

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //YYYYYYYYUUVV
            uchar Y=data[x+y*width];
            if(Y==126)
            {
                //鑳屾櫙---鐏拌壊
                bgrimg.ptr<uchar>(y)[3*x]=127;;
                bgrimg.ptr<uchar>(y)[3*x+1]=127;
                bgrimg.ptr<uchar>(y)[3*x+2]=127;
            }
            else if(Y==82)
            {
                //鐭跨偣---绾㈣壊
                bgrimg.ptr<uchar>(y)[3*x]=0;;
                bgrimg.ptr<uchar>(y)[3*x+1]=0;
                bgrimg.ptr<uchar>(y)[3*x+2]=255;
            }
            else if(Y==41)
            {
                //搴熺偣----榛勮壊
                bgrimg.ptr<uchar>(y)[3*x]=0;
                bgrimg.ptr<uchar>(y)[3*x+1]=200;
                bgrimg.ptr<uchar>(y)[3*x+2]=200;
            }
            else
            {
                cout<<"Error: Invalid input image data value in yuv420p2bgr()!"<<endl;
                return -1;
            }

        }
    }
    return 0;
}

或者直接试另几个,yuv422转RGB也有很多选项,自己试下,https://docs.opencv.org/4.5.2/d8/d01/group__imgproc__color__conversions.html#gga4e0972be5de079fed4e3a10e24ef5ef0a8199112edf021b1586c75ca20a46ecd1

img

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    首先,需要了解YUV 422 PACKED格式的raw图像的结构。该格式中,每个像素点由2个Y值和1个UV值组成。UV值在水平方向上交替存储。例如,第一个像素点的UV值存储在字节0和2中,第二个像素点的UV值存储在字节2和4中,依此类推。

    接下来,可以使用Python中的PIL库进行转换。具体步骤如下:

    1. 读取raw图像到一个bytearray类型的变量中。
    with open('raw_image.raw', 'rb') as f:
        data = bytearray(f.read())
    
    1. 将YUV 422 PACKED格式的数据转换成RGBA格式的数据。
    from PIL import Image
    
    # 计算图像的宽度和高度
    width = <图像宽度>
    height = <图像高度>
    
    # 将YUV 422 PACKED格式的数据转换成RGBA格式的数据
    img_yuv = Image.frombytes('YCbCr', (width, height), bytes(data))
    img_rgba = img_yuv.convert('RGBA')
    
    1. 将RGBA格式的数据保存成PNG图像。
    img_rgba.save('output.png')
    

    以上是将YUV 422 PACKED格式的raw图像转换成PNG图像的Python代码。其中,第二部分代码中的Image.frombytes函数可以指定YUV 422 PACKED格式的数据类型为YCbCr,并将图像的宽度和高度传入。convert函数则可以将YUV 422 PACKED格式的数据转换成RGBA格式的数据。

    值得注意的是,该方法可能需要根据不同数据源的特征调整参数,特别是提前提取图像的尺寸、yuv格式,以保证色彩正确。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^