2014-09-01 6 views
1

일부 코드는 수행했지만 일부 비교에서는 가장 가까운 값이 잘못되었습니다. 예 : 올바른C에서 색상 표 배열을 사용하여 가장 가까운 RGB 값 찾기

: 잘못된

Rgb value | Value from array 
0xFFFFFD = 0xFFFFFF 

: 고정 코드

Rgb value | Value from array 
0xF4F939 = 0xFF0000 (should be 0xFFFF00) 

콘솔 출력 : (수정)

,451,515,
C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap>24_to_8_bit_palett 
e 
The closest color of 0xFFFFFD is: '0xFFFFFF' 

C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap> 

콘솔 출력 :

C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap>24_to_8_bit_palett 
e 
The closest color of 0xF4F939 is: '0xFF0000' 

C:\Users\honguito\Desktop\Bat\Game_Batch_Files\24_to_8_bitmap> 

그 RGB 색상 코드 배열에 나와있는 (잘못된) :

다음
int data[] = { 
    0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 
    0xC0C0C0, 0xC0DCC0, 0xA6CAF0, 0x402000, 0x602000, 0x802000, 0xA02000, 
    0xC02000, 0xE02000, 0x004000, 0x204000, 0x404000, 0x604000, 0x804000, 
    0xA04000, 0xC04000, 0xE04000, 0x006000, 0x206000, 0x406000, 0x606000, 
    0x806000, 0xA06000, 0xC06000, 0xE06000, 0x008000, 0x208000, 0x408000, 
    0x608000, 0x808000, 0xA08000, 0xC08000, 0xE08000, 0x00A000, 0x20A000, 
    0x40A000, 0x60A000, 0x80A000, 0xA0A000, 0xC0A000, 0xE0A000, 0x00C000, 
    0x20C000, 0x40C000, 0x60C000, 0x80C000, 0xA0C000, 0xC0C000, 0xE0C000, 
    0x00E000, 0x20E000, 0x40E000, 0x60E000, 0x80E000, 0xA0E000, 0xC0E000, 
    0xE0E000, 0x000040, 0x200040, 0x400040, 0x600040, 0x800040, 0xA00040, 
    0xC00040, 0xE00040, 0x002040, 0x202040, 0x402040, 0x602040, 0x802040, 
    0xA02040, 0xC02040, 0xE02040, 0x004040, 0x204040, 0x404040, 0x604040, 
    0x804040, 0xA04040, 0xC04040, 0xE04040, 0x006040, 0x206040, 0x406040, 
    0x606040, 0x806040, 0xA06040, 0xC06040, 0xE06040, 0x008040, 0x208040, 
    0x408040, 0x608040, 0x808040, 0xA08040, 0xC08040, 0xE08040, 0x00A040, 
    0x20A040, 0x40A040, 0x60A040, 0x80A040, 0xA0A040, 0xC0A040, 0xE0A040, 
    0x00C040, 0x20C040, 0x40C040, 0x60C040, 0x80C040, 0xA0C040, 0xC0C040, 
    0xE0C040, 0x00E040, 0x20E040, 0x40E040, 0x60E040, 0x80E040, 0xA0E040, 
    0xC0E040, 0xE0E040, 0x000080, 0x200080, 0x400080, 0x600080, 0x800080, 
    0xA00080, 0xC00080, 0xE00080, 0x002080, 0x202080, 0x402080, 0x602080, 
    0x802080, 0xA02080, 0xC02080, 0xE02080, 0x004080, 0x204080, 0x404080, 
    0x604080, 0x804080, 0xA04080, 0xC04080, 0xE04080, 0x006080, 0x206080, 
    0x406080, 0x606080, 0x806080, 0xA06080, 0xC06080, 0xE06080, 0x008080, 
    0x208080, 0x408080, 0x608080, 0x808080, 0xA08080, 0xC08080, 0xE08080, 
    0x00A080, 0x20A080, 0x40A080, 0x60A080, 0x80A080, 0xA0A080, 0xC0A080, 
    0xE0A080, 0x00C080, 0x20C080, 0x40C080, 0x60C080, 0x80C080, 0xA0C080, 
    0xC0C080, 0xE0C080, 0x00E080, 0x20E080, 0x40E080, 0x60E080, 0x80E080, 
    0xA0E080, 0xC0E080, 0xE0E080, 0x0000C0, 0x2000C0, 0x4000C0, 0x6000C0, 
    0x8000C0, 0xA000C0, 0xC000C0, 0xE000C0, 0x0020C0, 0x2020C0, 0x4020C0, 
    0x6020C0, 0x8020C0, 0xA020C0, 0xC020C0, 0xE020C0, 0x0040C0, 0x2040C0, 
    0x4040C0, 0x6040C0, 0x8040C0, 0xA040C0, 0xC040C0, 0xE040C0, 0x0060C0, 
    0x2060C0, 0x4060C0, 0x6060C0, 0x8060C0, 0xA060C0, 0xC060C0, 0xE060C0, 
    0x0080C0, 0x2080C0, 0x4080C0, 0x6080C0, 0x8080C0, 0xA080C0, 0xC080C0, 
    0xE080C0, 0x00A0C0, 0x20A0C0, 0x40A0C0, 0x60A0C0, 0x80A0C0, 0xA0A0C0, 
    0xC0A0C0, 0xE0A0C0, 0x00C0C0, 0x20C0C0, 0x40C0C0, 0x60C0C0, 0x80C0C0, 
    0xA0C0C0, 0xFFFBF0, 0xA0A0A4, 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 
    0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF 
}; 

가장 가까운 수를 얻기 위해 I 해야한다 :

일부 사용되지 않는 변수와 예전의 코드가 있습니다

#include <stdio.h> 

int main() { 

    //int pcolor = 0xF4F939; 
    int pcolor = 0xFFFFFD; 
    //int pcolor = 0x700000; 
    //int pcolor = 0x21A0C0; 
    int cmp[256]; 
    int cmp2[256]; 
    int data[] = { 
     0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, 0x008080, 
     0xC0C0C0, 0xC0DCC0, 0xA6CAF0, 0x402000, 0x602000, 0x802000, 0xA02000, 
     0xC02000, 0xE02000, 0x004000, 0x204000, 0x404000, 0x604000, 0x804000, 
     0xA04000, 0xC04000, 0xE04000, 0x006000, 0x206000, 0x406000, 0x606000, 
     0x806000, 0xA06000, 0xC06000, 0xE06000, 0x008000, 0x208000, 0x408000, 
     0x608000, 0x808000, 0xA08000, 0xC08000, 0xE08000, 0x00A000, 0x20A000, 
     0x40A000, 0x60A000, 0x80A000, 0xA0A000, 0xC0A000, 0xE0A000, 0x00C000, 
     0x20C000, 0x40C000, 0x60C000, 0x80C000, 0xA0C000, 0xC0C000, 0xE0C000, 
     0x00E000, 0x20E000, 0x40E000, 0x60E000, 0x80E000, 0xA0E000, 0xC0E000, 
     0xE0E000, 0x000040, 0x200040, 0x400040, 0x600040, 0x800040, 0xA00040, 
     0xC00040, 0xE00040, 0x002040, 0x202040, 0x402040, 0x602040, 0x802040, 
     0xA02040, 0xC02040, 0xE02040, 0x004040, 0x204040, 0x404040, 0x604040, 
     0x804040, 0xA04040, 0xC04040, 0xE04040, 0x006040, 0x206040, 0x406040, 
     0x606040, 0x806040, 0xA06040, 0xC06040, 0xE06040, 0x008040, 0x208040, 
     0x408040, 0x608040, 0x808040, 0xA08040, 0xC08040, 0xE08040, 0x00A040, 
     0x20A040, 0x40A040, 0x60A040, 0x80A040, 0xA0A040, 0xC0A040, 0xE0A040, 
     0x00C040, 0x20C040, 0x40C040, 0x60C040, 0x80C040, 0xA0C040, 0xC0C040, 
     0xE0C040, 0x00E040, 0x20E040, 0x40E040, 0x60E040, 0x80E040, 0xA0E040, 
     0xC0E040, 0xE0E040, 0x000080, 0x200080, 0x400080, 0x600080, 0x800080, 
     0xA00080, 0xC00080, 0xE00080, 0x002080, 0x202080, 0x402080, 0x602080, 
     0x802080, 0xA02080, 0xC02080, 0xE02080, 0x004080, 0x204080, 0x404080, 
     0x604080, 0x804080, 0xA04080, 0xC04080, 0xE04080, 0x006080, 0x206080, 
     0x406080, 0x606080, 0x806080, 0xA06080, 0xC06080, 0xE06080, 0x008080, 
     0x208080, 0x408080, 0x608080, 0x808080, 0xA08080, 0xC08080, 0xE08080, 
     0x00A080, 0x20A080, 0x40A080, 0x60A080, 0x80A080, 0xA0A080, 0xC0A080, 
     0xE0A080, 0x00C080, 0x20C080, 0x40C080, 0x60C080, 0x80C080, 0xA0C080, 
     0xC0C080, 0xE0C080, 0x00E080, 0x20E080, 0x40E080, 0x60E080, 0x80E080, 
     0xA0E080, 0xC0E080, 0xE0E080, 0x0000C0, 0x2000C0, 0x4000C0, 0x6000C0, 
     0x8000C0, 0xA000C0, 0xC000C0, 0xE000C0, 0x0020C0, 0x2020C0, 0x4020C0, 
     0x6020C0, 0x8020C0, 0xA020C0, 0xC020C0, 0xE020C0, 0x0040C0, 0x2040C0, 
     0x4040C0, 0x6040C0, 0x8040C0, 0xA040C0, 0xC040C0, 0xE040C0, 0x0060C0, 
     0x2060C0, 0x4060C0, 0x6060C0, 0x8060C0, 0xA060C0, 0xC060C0, 0xE060C0, 
     0x0080C0, 0x2080C0, 0x4080C0, 0x6080C0, 0x8080C0, 0xA080C0, 0xC080C0, 
     0xE080C0, 0x00A0C0, 0x20A0C0, 0x40A0C0, 0x60A0C0, 0x80A0C0, 0xA0A0C0, 
     0xC0A0C0, 0xE0A0C0, 0x00C0C0, 0x20C0C0, 0x40C0C0, 0x60C0C0, 0x80C0C0, 
     0xA0C0C0, 0xFFFBF0, 0xA0A0A4, 0x808080, 0xFF0000, 0x00FF00, 0xFFFF00, 
     0x0000FF, 0xFF00FF, 0x00FFFF, 0xFFFFFF 
    }; 

    int nearIndex,nearest, result; 

    nearest = findKey(data, pcolor);  
    printf("The closest color of 0x%X is: '0x%X'\n", pcolor, nearest); 
    //system("pause"); 
} 


int findKey(int Array1[], int key){ 
    int diff = abs(key - Array1[0]); 
    int Num1 = 0; 
    int Num2 = 0; 
    for (int a = 0; a < 256; a++) { 
      if (diff > abs(key - Array1[a])) { 
      diff = abs(key - Array1[a]); 
      Num1 = Array1[a]; 
     } 
    } 
    return Num1; 
    } 

:

nearest = findKey(data, pcolor); 

는 그리고 이것은 전체 코드입니다.

아이디어가 있으십니까?

+0

사실 "가까운"(절대 차이)에 대한 코드에서 사용하는 정의에 따르면 코드는 정확합니다. 0xFF0000과 0x21A0C0의 차이는 0xFFF000과 같은 값보다 작습니다. – cnicutar

+0

오, 틀렸어. 두 번째 코드 블록에서 0x21A0C0 대신 0xF4F939가 나온다. 그 죄송합니다! – Honguito98

+0

그것은 여전히 ​​같은 상황입니다. – cnicutar

답변

2

"광학"가장 가까운 색을 찾으려면 비교할 두 색의 색 구성 요소 사이의 차이를 추정해야합니다.

이렇게하려면 24 비트 값을 8 비트 색상 구성 요소 인 r, g, b로 분할해야합니다.

그런 다음 구성 요소를 비교합니다.

이렇게하는 순진한 방법은 각 구성 요소의 차이의 절대 값을 합계하는 것입니다.

더 정확한 수식이 인터넷 검색으로 발견 될 수 있습니다.

// two colors to compare 

int c1; 
int c2; 

// split c1 and c2 into their respective color components 

r1 = c1/0x010000; 
g1 = (c1 % 0x010000)/0x00100; 
b1 = c1 % 0x000100; 

r2 = c2/0x010000; 
g2 = (c2 % 0x010000)/0x00100; 
b2 = c2 % 0x000100; 

// color "distance" 

diff = abs(r1 - r2) + abs(g1 - g2) + abs (b1 - b2); 
+0

처음에는 pcolor와 data [] 배열 사이에 RGB 합성 diff를 얻으려고했습니다. 그러나 나는 RGB hex 코드를 3 개의 변수로 분리하려고 시도하지 않았습니다. P.S : 논리 교대를 사용하여 RGB 16 진 코드를 분할하는 것이 더 효율적인 다른 방법이 있습니다. P.S. 2 : 도와 줘서 고마워! – Honguito98

+0

확실한 방법은 색상을 분할하는 더 효율적인 방법입니다. 내 코드는 단지 아이디어를 제공하는 것이었다. 또한 컴포넌트의 값을 기반으로 색상을 비교할 수있는보다 정확한 전문가 수식이있을 수 있습니다. 그러나 다시 한 번 아이디어를내는 것입니다. "먼저 색상을 구성 요소로 분할합니다."환영합니다. – Paolo

+0

[John Hascall] (http://stackoverflow.com/a/25715571/2564301) 노트에 대답은 유클리드 거리를 가장 잘 측정 한 것입니다. – usr2564301

1

나는 3 차원 거리 공식을 사용하여 (만 비교하는 걱정 때문에, 당신은 마지막에 sqrt()를 건너 뛸 수 있습니다)가 '가까운'색상을 계산하는 더 정확한 방법이 될 것이라고 생각합니다.

dist_r = abs(r1 - r2); 
dist_g = abs(g1 - g2); 
dist_b = abs(b1 - b2); 
dist_3d_sqd = (dist_r * dist_r) + (dist_g * dist_g) + (dist_b * dist_b 

실제로 당신은 너무 abs() 호출을 건너 뛸 수 있지만, 그들을 퍼팅은 아마도 그것을 명확하게?

관련 문제