我正在使用查找表来转换颜色空间和编码变体之间的原始像素数据。这是我的LUT的定义:
// 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;
}
}
}
它初始化如下:
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将原始像素数据复制到QImage():
await
LUT的值是静态的,每次程序启动时都必须初始化。有没有办法通过预处理器初始化它?或者将它保存在文件中是否值得推荐?
编辑:转换用于时间关键的视频应用程序,其中每个帧都必须单独处理。
非常感谢!
答案 0 :(得分:-1)
我为这个表创建了一维数组,保存和加载这样的数组很方便。我认为在运行时使用这个数组不会降低性能。但我没有测试它的性能差异。
#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 %d\n", testValue.data[0], testValue.data[1], testValue.data[2]);
read(LUT, "LUT_data");
testValue = LUT_value(5,3,7);
printf("%d %d %d\n", testValue.data[0], testValue.data[1], testValue.data[2]);
free(LUT);
}