2014-09-02 2 views
0

Хорошо. Согласно заголовку Я пытаюсь выяснить способ - функция, которая возвращает символ, который доминирует в строке. Я мог бы понять это ... но, похоже, что-то не так с моей логикой, и я потерпел неудачу в этом. Если кто-то может придумать это без проблем, я буду очень рад вам.Получить символ доминанта из строки

Я говорю «в строке», чтобы сделать его более упрощенным. Я на самом деле делаю это из буферизованных данных, содержащих BMP-образ. Попытка вывести базовый цвет (доминирующий пиксель).

То, что я сейчас в том, что функция незавершенной я начал:

RGB 
bitfox_get_primecolor_direct 
(char *FILE_NAME) 
{ 
    dword size = bmp_dgets(FILE_NAME, byte); 
    FILE* fp = fopen(convert(FILE_NAME), "r"); 
    BYTE *PIX_ARRAY = malloc(size-54+1), *PIX_CUR = calloc(sizeof(RGB), sizeof(BYTE)); 
    dword readed, i, l; 
    RGB color, prime_color; 

    fseek(fp, 54, SEEK_SET); readed = fread(PIX_ARRAY, 1, size-54, fp); 
    for(i = 54; i<size-54; i+=3) 
    { 
     color = bitfox_pixel_init(PIXEL_ARRAY[i], PIXEL_ARRAY[i+1], PIXEL_ARRAY[i+2); 
     memmove(PIX_CUR, color, sizeof(RGB)); 
     for(l = 54; l<size-54; l+=3) 
     { 
      if (PIX_CUR[2] == PIXEL_ARRAY[l] && PIX_CUR[1] == PIXEL_ARRAY[l+1] && 
       PIX_CUR[0] == PIXEL_ARRAY[l+2]) 
       { 

} 

Обратите внимание, что RGB является структурой, содержащей 3 байта (R, G и B). Я знаю, что ничего, кроме .. Это все, что у меня есть сейчас. Есть ли способ закончить это?

+0

доминирующим, вы имеете в виду цвет, который встречается чаще всего на изображении? – thurizas

+0

Я бы преобразовал ваши значения rgb в одно 32-битное значение, порядок байтов не будет иметь значения, если вы согласны, что упрощает их сравнение. Тогда я просто подсчитаю, сколько раз я видел каждое значение и возвращаю тот, у которого наибольшее количество. –

+0

@thurizas да. Это то, что я имею в виду. – Edenia

ответ

1

Если вы хотите, чтобы это было сделано быстро выложите в него стопку ОЗУ (если доступно, конечно). Вы можете использовать большую таблицу прямого поиска с трио RGB для создания последовательности 24-битных индексов в смежный массив счетчиков. В частичном псевдо-частичном коде что-то вроде этого:

// create a zero-filled 2^24 array of unsigned counters. 
uint32_t *counts = calloc(256*256*256, sizeof(*counts)); 
uint32_t max_count = 0 

// enumerate your buffer of RGB values, three bytes at a time: 
unsigned char rgb[3]; 
while (getNextRGB(src, rgb)) // returns false when no more data. 
{ 
    uint32_t idx = (((uint32_t)rgb[0]) << 16) | (((uint32_t)rgb[1]) << 8) | (uint32_t)rgb[2]; 
    if (++counts[idx] > max_count) 
     max_count = idx; 
} 

R = (max_count >> 16) & 0xFF; 
G = (max_count >> 8) & 0xFF; 
B = max_count & 0xFF; 

// free when you have no more images to process. for each new 
// image you can memset the buffer to zero and reset the max 
// for a fresh start. 
free(counts); 

Thats it. Если вы можете позволить себе выбросить большой кусок памяти (это будет 64 МБ в этом случае, при 4 байтах на запись при записи 16,7 М), тогда выполнение этого станет O (N). Если у вас есть последовательность изображений для обработки, вы можете просто memset() массив вернуться к нулям, очистить max_count и повторить для каждого дополнительного файла. Наконец, не забудьте освободить память, когда закончите.

Удачи.

+0

Благодарим вас, очень размахивая, голосуйте. Я могу позволить себе/64 МБ/Причина, по которой его быстро происходит из-за оператора сдвига. Это быстрее, чем арифметика. И номера регулярных выражений. – Edenia

+0

Его быстро, потому что вам не нужно ничего сортировать, ни много чего другого для этого теста, кроме приращения и теста. Возможность индексирования уникального счетчика для каждого возможного тэга RGB заставляет его работать, и это индексирование является просто смещением в линейный буфер. Я не думаю, что возможно иметь более быстрый алгоритм (моя реализация сомнительна, как всегда, но алгоритм звучит), если у вас есть RAM, чтобы бросить на него. – WhozCraig

+0

О, по сравнению с тем, что я начал, это, безусловно, быстрее. На первом взгляде легко дать такое утверждение. Я до сих пор не понимаю, как реализовать эту функцию в функции, которая возвращает RGB (как структуру) наиболее часто появляющегося пикселя. Но я буду рассматривать его снова. – Edenia

Смежные вопросы