2009-12-27 1 views
3

У меня есть буфер со многими положительными 16-битными значениями (которые хранятся как удваиваются), которые я хотел бы квантовать до 8 бит (0-255 значений).Имеет ли C функцию квантования?

В соответствии с Wikipedia процесс будет:

  • Нормализировать 16 бит значения. То есть найти самое большое и разделить с этим.
  • Используйте формулу Q (x) с M = 8.

Так что, если у C есть функция, которая может выполнить это квантование, или кто-нибудь знает о реализации C, которую я мог бы использовать?

Много любви, Луиз

+0

На моей машине двойной на самом деле 64-битный. – avakar

+0

'double' - 64 бит. 'float' - 32 бит. – LiraNuna

+0

:) Ой, ребята, вы правы. –

ответ

2

Предполагая, что значение d находится в интервале [0.0, max]:

unsigned char quantize(double d, double max) 
{ 
    return (unsigned char)((d/max) * 255.0); 
} 

Я не уверен, что вы подразумеваете под "16-битовых значений;" значения двойной точности 64-бит в любой системе с использованием IEEE-754. Однако, если у вас есть значения другого числового типа, процесс фактически тот же.

+0

Если вы хотите быть переносным, вам нужно наложить «unsigned char». Или еще лучше, бросьте бросок полностью. – avakar

+0

Ничего себе. Какое замечательное решение! Как вы пришли из формулы Q (x) из Википедии в эту элегантную функцию? – Louise

3

Это звучит как обработка звуковых сигналов, когда ваш вход 16 данных PCM, ваш выход - 8 бит данных ИКМ, и вы используете удвоения в качестве промежуточного значения.

Однако 8-битные данные волны PCM НЕ просто квантованы, представление представляет собой значения без знака, превышающие 128 нотации. (например, показатели экспоненты хранятся в числах с плавающей запятой)

Поиск наибольшего значения сначала будет не только квантованием, но и масштабированием. Таким образом, в псевдокоде

double dMax = max_of_all_values(); // 
... 
foreach (dValue in array_of_doubles) 
{ 
    signed char bValue = (signed char)((dValue/dMax)*127.0); 
} 

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

Примечание: этот подписанный символ НЕ является правильным, если на выходе представлены 8-битные данные PCM, но поскольку вопросы не требуют особого запроса, я оставил его.

Редактировать: если это необходимо использовать в качестве пиксельных данных, то вы хотите получить значения без знака. Я вижу, что Джеймс уже дал правильный ответ для неподписанных значений, когда вход без знака (значения дБ из нормализованных данных должны быть все отрицательные, фактически)

+0

Очень впечатляет, что вы могли видеть, над чем я работал = = Я преобразовал 16-битный вход в дБ, потому что я хочу построить его как спектрограмму. Но, к сожалению, GIMP пока не поддерживает 16 бит на цветной канал, поэтому я должен квантовать 8 бит. Я работаю в сером цвете. У GIMP есть поддержка GEGL, которая дает 32-битный цветный канал, но API-интерфейс плагина еще не поддерживает это, из того, что я могу сказать. – Louise

1

Неясно, из вашего вопроса, с чего кодируется «положительных 16-битных значений (которые хранятся как двойные) «не имеет никакого реального смысла; они либо 16 бит, либо они двойные, они не могут быть обоими.

Однако при условии, что это 16 бит без знака данных нормированные до 1,0 (так что значения в диапазоне от 0,0 < = с < = 1,0), то все, что нужно сделать, чтобы расширить их 8bit целочисленных значений является умножение каждого образец по 255.

unsigned char s8 = s * 255 ; 

Если диапазон не равен 0.0 < = сек < = 1,0, а 0,0 < < = S = макс тогда:

unsigned char s8 = s/max * 255 ; 

В любом случае, нет функции "квантование", кроме одного вы можете написать самостоятельно; но необходимое преобразование, без сомнения, будет простым арифметическим выражением (хотя и не столь простым, если данные, возможно, сжаты, например, например, μ-lay или A-law).

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

  • Нет связанных вопросов^_^