2016-11-06 10 views
0

룩업 테이블을 사용하여 색상 공간과 코딩 변형 사이에서 미가공 픽셀 데이터를 변환하고 있습니다.전처리기를 통해 3D 룩업 테이블 (LUT)을 초기화 하시겠습니까?

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

rgb LUTYUVTORGB[256][256][256]; 

그것은 다음과 같이 초기화된다 : 이것은 내 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; 
     } 
    } 
} 

후 QImage()에 픽셀 데이터를 복사하는 데 적용되는 LUT :

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의 값은 정적이므로 프로그램을 시작할 때마다 초기화해야합니다. 전처리기를 통해 초기화하는 방법이 있습니까? 또는 파일로 저장하는 것이 좋습니다.

EDIT : 변환은 모든 프레임을 개별적으로 처리해야하는 시간이 중요한 비디오 응용 프로그램에서 사용됩니다.

대단히 감사드립니다.

+1

왜 큰 (64MiB) 찾아보기 테이블이 필요합니까? 변환은 매우 간단하여 즉시 수행 할 수 있습니다. – Leon

+0

내 구조는 파일로 저장하는 것이 좋습니다. –

+0

@ Reeon 모든 프레임을 개별적으로 처리해야하는 시간이 중요한 비디오 응용 프로그램에서 변환이 사용된다고 언급 했어야합니다. – tlaloc

답변

-1

이 테이블에 대해 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); 
}  
+2

다차원 배열은 이미 메모리에서 연속되어 있으므로 "직렬화 가능"으로 만들기 위해 다시 고칠 필요가 없습니다. – dtech

+0

@ddriver 감사합니다. 두 어레이가 동일한 성능을 테스트했습니다. –