通过预处理器初始化3D查找表(LUT)

Initialize 3D lookup table (LUT) via preprocessor?

本文关键字:LUT 查找 3D 预处理 处理器 初始化      更新时间:2023-10-16

我使用查找表在颜色空间和编码变体之间转换原始像素数据。这是我的LUT的定义:

typedef struct
{
    unsigned char data[3];
} rgb;
rgb LUTYUVTORGB[256][256][256];

它是这样初始化的:

// loop through all possible values
for (int in_1 = 0; in_1 < 256; in_1++) {
    for (int in_2 = 0; in_2 < 256; in_2++) {
        for (int in_3 = 0; in_3 < 256; in_3++) {
            int out_1, out_2, out_3;
            // LUT YUV -> RGB
            // convert to rgb (http://softpixel.com/~cwright/programming/colorspace/yuv/)
            out_1 = (int)(in_1 + 1.4075 * (in_3 - 128));
            out_2 = (int)(in_1 - 0.3455 * (in_2 - 128) - (0.7169 * (in_3 - 128)));
            out_3 = (int)(in_1 + 1.7790 * (in_2 - 128));
            // clamp values
            if (out_1 < 0) { out_1 = 0; } else if (out_1 > 255) { out_1 = 255; }
            if (out_2 < 0) { out_2 = 0; } else if (out_2 > 255) { out_2 = 255; }
            if (out_3 < 0) { out_3 = 0; } else if (out_3 > 255) { out_3 = 255; }
            // set values in LUT
            LUTYUVTORGB[in_1][in_2][in_3].data[0] = (unsigned char)out_1;
            LUTYUVTORGB[in_1][in_2][in_3].data[1] = (unsigned char)out_2;
            LUTYUVTORGB[in_1][in_2][in_3].data[2] = (unsigned char)out_3;
        }
    }
}
然后应用LUT将原始像素数据复制到QImage():
for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
        xpos = (y*w + x); // don't calculate 3 times
        buff[x * 3 + 0] = psImage->comps[0].data[xpos];
        buff[x * 3 + 1] = psImage->comps[1].data[xpos];
        buff[x * 3 + 2] = psImage->comps[2].data[xpos];
    }
    memcpy(image.scanLine(y), buff, bytes_per_line);
}

LUT的值是静态的,每次程序启动时都必须初始化。有没有办法通过预处理器初始化它?还是建议将其保存在文件中?

编辑:转换用于时间关键的视频应用程序,其中每帧都必须单独处理。

提前感谢!

我已经为这个表创建了一维数组,方便保存和加载这样的数组。我认为在运行时使用这个数组不会降低性能。但我没有测试它的性能差异。

#include <stdio.h>
#include <stdlib.h>
#define LUTSIZE 0x1000000
typedef struct
{
    unsigned char data[3];
} rgb;
rgb *LUT;
inline int LUT_index(int in_1, int in_2, int in_3) {
    return in_1 * 0x10000 + in_2 * 0x100 + in_3 * 0x1;
}
inline rgb LUT_value(int in_1, int in_2, int in_3) {
    return LUT[LUT_index(in_1,in_2,in_3)];
}
void save(rgb *LUT, char* fileName) {
    FILE* file = fopen(fileName,"wb");
    int index;
    for (int in_1 = 0; in_1 < 256; in_1++) {
        for (int in_2 = 0; in_2 < 256; in_2++) {
            for (int in_3 = 0; in_3 < 256; in_3++) {
                int out_1, out_2, out_3;
                // LUT YUV -> RGB
                // convert to rgb (http://softpixel.com/~cwright/programming/colorspace/yuv/)
                out_1 = (int)(in_1 + 1.4075 * (in_3 - 128));
                out_2 = (int)(in_1 - 0.3455 * (in_2 - 128) - (0.7169 * (in_3 - 128)));
                out_3 = (int)(in_1 + 1.7790 * (in_2 - 128));
                // clamp values
                if (out_1 < 0) { out_1 = 0; } else if (out_1 > 255) { out_1 = 255; }
                if (out_2 < 0) { out_2 = 0; } else if (out_2 > 255) { out_2 = 255; }
                if (out_3 < 0) { out_3 = 0; } else if (out_3 > 255) { out_3 = 255; }
                index = LUT_index(in_1,in_2,in_3);
                // set values in LUT
                LUT[index].data[0] = (unsigned char)out_1;
                LUT[index].data[1] = (unsigned char)out_2;
                LUT[index].data[2] = (unsigned char)out_3;
            }
        }
    }
    fwrite((void*)LUT, sizeof(rgb),LUTSIZE,file);
    fclose(file);
}
void read(rgb *LUT, char* fileName) {
    FILE* file = fopen(fileName, "rb");
    fread((void*)LUT,sizeof(rgb),LUTSIZE,file);
    fclose(file);
}
int main(int argc, char *argv[])
{
    LUT = (rgb*)malloc(LUTSIZE * sizeof(rgb));
    save(LUT, "LUT_data");
    rgb testValue = LUT_value(5,3,7);
    printf("%d %d %dn", testValue.data[0], testValue.data[1], testValue.data[2]);
    read(LUT, "LUT_data");
    testValue = LUT_value(5,3,7);
    printf("%d %d %dn", testValue.data[0], testValue.data[1], testValue.data[2]);
    free(LUT);
}