RGB到XYZ,图像转换

时间:2019-05-29 09:57:02

标签: c++

original image -原始图片

xyz conversion image -xyz转换图片

我希望将图像从RGB转换为XYZ颜色空间。

此代码正确吗?

它使图像更暗。

for( int i = 0; i <= stripSize * stripMax; i++ )
{
    floatvalue[i] = buffer[i] / 255.0f;
    if( floatvalue[i] <= 0.04045f )
    {
        floatvalue[i] = floatvalue[i] / 12.92f;
    }
    else
    {
        floatvalue[i] = powf( (floatvalue[i] + 0.055) / (1.055), 2.4f );
    }

    floatvalue[i] = floatvalue[i] * 100.0f;
}

for( int i = 0; i <= stripSize * stripMax; i = i + 3 )
{
    conversion_x = 0.4124f * floatvalue[i] + 0.3576f * floatvalue[i + 1] + 0.1805f * floatvalue[i + 2];
    xyz_buffer[i] = conversion_x;

    conversion_y = 0.2126f * floatvalue[i] + 0.7152f * floatvalue[i + 1] + 0.0722f * floatvalue[i + 2];
    xyz_buffer[i + 1] = conversion_y;

    conversion_z = 0.0193f * floatvalue[i] + 0.1192f * floatvalue[i + 1] + 0.9505f * floatvalue[i + 2];
    xyz_buffer[i + 2] = conversion_z;
}

1 个答案:

答案 0 :(得分:0)

这应该可以工作。我之前已经使用过很多次。我当然对其做了一些修改,以便将其从原始缓冲区转换为xyz。.它取自我在此处编写的代码:https://github.com/Brandon-T/CMML/blob/master/src/color.c#L17

#include <iostream>
#include <cstdint>
#include <cmath>

typedef struct rgb32_t
{
    std::uint8_t r;
    std::uint8_t g;
    std::uint8_t b;
    std::uint8_t a;
} rgb32;

typedef struct xyz_t
{
    float x, y, z;
} xyz;

void rgb_to_xyz(rgb32 *px, xyz *res)
{
    float r = (px->r / 255.0f);
    float g = (px->g / 255.0f);
    float b = (px->b / 255.0f);
    r = (r > 0.04045f) ? pow(((r + 0.055f) / 1.055f), 2.4f) * 100.0f : r / 12.92f;
    g = (g > 0.04045f) ? pow(((g + 0.055f) / 1.055f), 2.4f) * 100.0f : g / 12.92f;
    b = (b > 0.04045f) ? pow(((b + 0.055f) / 1.055f), 2.4f) * 100.0f : b / 12.92f;
    res->x = r * 0.4124f + g * 0.3576f + b * 0.1805f;
    res->y = r * 0.2126f + g * 0.7152f + b * 0.0722f;
    res->z = r * 0.0193f + g * 0.1192f + b * 0.9505f;
}

xyz* convert_to_xyz(std::uint8_t* pixels, std::size_t width, std::size_t height, std::uint16_t bpp = 24)
{
    if (pixels)
    {
        xyz* result = new xyz[width * height];
        for (std::size_t i = 0; i < height; ++i)
        {
            for (std::size_t j = 0; j < width; ++j)
            {
                rgb32 pixel;
                pixel.b = *(pixels++);
                pixel.g = *(pixels++);
                pixel.r = *(pixels++);
                pixel.a = (bpp > 24 ? * (pixels++) : 0xFF);

                rgb_to_xyz(&pixel, result);
                ++result;
            }

            if (bpp == 24)
                pixels += (-width * 3) & 3;
        }
        return result;
    }
    return nullptr;
}

int main() {
    int width = 100;
    int height = 100;
    int bits_per_pixel = 32;

    std::uint8_t *pixels = nullptr; //replace with correct buffer of pixels..


    xyz* xyz_buffer = convert_to_xyz(pixels, width, height, bits_per_pixel);

    //View the xyz pixels..


    delete[] xyz_buffer;


    return 0;
}