RGB到XYZ,图像转换

  • 本文关键字:图像 转换 XYZ RGB c++
  • 更新时间 :
  • 英文 :


原始图像-- 原始图像

XYZ 转换图像-- 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;
}

这应该有效。我以前用过很多次。我当然稍微修改了它,以便它将从原始缓冲区转换为 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;
}

最新更新