Кодирование источника

Представление разделов

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

Разбиение квантования задает несколько смежных, непересекающиеся области значений значений в наборе вещественных чисел. Чтобы задать раздел в MATLAB® окружение, перечислите различные конечные точки различных областей значений в векторе.

Например, если раздел разделяет действительную числовую линию на четыре набора

  • {x: x ≤ 0}

  • {x: 0 < x ≤ 1}

  • {x: 1 < x ≤ 3}

  • {x: 3 < x}

тогда можно представлять разбиение как трехэлементный вектор

partition = [0,1,3];

Длина вектора разбиения на один меньше, чем количество интервалов разбиения.

Представление кодовых книг

Кодовая книга сообщает квантователю, какое общее значение следует присвоить входам, которые попадают в каждую область значений раздела. Представьте кодовую книгу как вектор, чья длина совпадает с количеством интервалов разбиения. Для примера, вектор

codebook = [-1, 0.5, 2, 3];

является одной возможной кодовой книгой для раздела [0,1,3].

Определите, в каком интервале находится каждый вход

quantiz функция также возвращает вектор, который сообщает, в каком интервале находится каждый вход. Для примера в выход ниже сказано, что значения входа находятся в пределах интервалов, обозначенных 0, 6 и 5, соответственно. Здесь 0-й интервал состоит из вещественных чисел, меньших или равных 3; 6-й интервал состоит из вещественных чисел больше 8, но меньше или равен 9; и 5-й интервал состоит из вещественных чисел, больше 7, но меньше или равно 8.

partition = [3,4,5,6,7,8,9];
index = quantiz([2 9 8],partition)

Это выход

index =

     0
     6
     5

Если вы продолжаете этот пример, определяя вектор кодовой книги, такой как

codebook = [3,3,4,5,6,7,8,9];

затем приведенное ниже уравнение связывает вектор index к квантованному сигналу quants.

quants = codebook(index+1);

Эта формула для quants именно то, что quantiz function использует, если вместо этого описать пример более кратко, как показано ниже.

partition = [3,4,5,6,7,8,9];
codebook = [3,3,4,5,6,7,8,9];
[index,quants] = quantiz([2 9 8],partition,codebook);

Оптимизация параметров квантования

Обзор разделов

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

Примечание

Обучающие данные, которые вы используете, должны быть типичными для видов сигналов, которые вы фактически будете квантовать.

Пример: Оптимизация параметров квантования

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

% Start with the setup from 2nd example in "Quantizing a Signal."
t = [0:.1:2*pi];
sig = sin(t);
partition = [-1:.2:1];
codebook = [-1.2:.2:1];
% Now optimize, using codebook as an initial guess.
[partition2,codebook2] = lloyds(sig,codebook);
[index,quants,distor] = quantiz(sig,partition,codebook);
[index2,quant2,distor2] = quantiz(sig,partition2,codebook2);
% Compare mean square distortions from initial and optimized
[distor, distor2] % parameters.

Это выход

ans =

    0.0148    0.0024

Дифференциальный импульс Кода модуляция

Обзор разделов

Квантование в разделе Квантование Сигнала не требует априорного знания о переданном сигнале. На практике можно часто делать образованные догадки о настоящем сигнале на основе прошлых передач сигнала. Использование таких образованных догадок, чтобы помочь квантовать сигнал, известно как прогнозирующее квантование. Наиболее распространенным методом прогнозирующего квантования является дифференциальная импульсно код модуляция (DPCM).

Функции dpcmenco, dpcmdeco, и dpcmopt может помочь вам реализовать прогнозирующий квантователь DPCM с линейным предиктором.

Терминология DPCM

Чтобы определить энкодер для такого квантователя, вы должны предоставить не только раздел и кодовую книгу, как описано в Represent Partitions и Represent Codooks, но и предиктор. Предиктор является функцией, которую DPCM энкодера использует, чтобы произвести образованное предположение на каждом шаге. Линейный предиктор имеет вид

y(k) = p(1)x(k-1) + p(2)x(k-2) + ... + p(m-1)x(k-m+1) + p(m)x(k-m)

где x - исходный сигнал, y(k) пытается предсказать значение x(k), и p является m-кортеж реальных чисел. Вместо квантования x сам DPCM энкодера квантует прогнозирующую ошибку x-y. Целое число m выше называется прогнозирующим порядком. Особый случай, когда   m = 1 называется дельта-модуляцией.

Представление предикторов

Если догадка о kth значение сигнала x, на основе более ранних значений xявляется

y(k) = p(1)x(k-1) + p(2)x(k-2) +...+ p(m-1)x(k-m+1) + p(m)x(k-m)

тогда соответствующий вектор предиктора для функций тулбокса

predictor = [0, p(1), p(2), p(3),..., p(m-1), p(m)]

Примечание

Начальный нуль в векторе-предикторе имеет смысл, если вы рассматриваете вектор как полиномиальную передаточную функцию фильтра с конечной импульсной характеристикой (КИХ).

Пример: Кодирование и декодирование DPCM

Простой специальный случай DPCM квантует различие между текущим значением сигнала и его значением на предыдущем шаге. Таким образом, предиктор просто      y(k) = x (k - 1). Приведенный ниже код реализует эту схему. Он кодирует пилообразный сигнал, декодирует его и строит графики как исходных, так и декодированных сигналов. Сплошная линия является исходным сигналом, в то время как штриховая линия является восстановленными сигналами. Пример также вычисляет среднюю квадратную ошибку между исходным и декодированным сигналами.

predictor = [0 1]; % y(k)=x(k-1)
partition = [-1:.1:.9];
codebook = [-1:.1:1];
t = [0:pi/50:2*pi];
x = sawtooth(3*t); % Original signal
% Quantize x using DPCM.
encodedx = dpcmenco(x,codebook,partition,predictor);
% Try to recover x from the modulated signal.
decodedx = dpcmdeco(encodedx,codebook,predictor);
plot(t,x,t,decodedx,'--')
legend('Original signal','Decoded signal','Location','NorthOutside');
distor = sum((x-decodedx).^2)/length(x) % Mean square error

Это выход

distor =

    0.0327

Оптимизация параметров DPCM

Обзор разделов

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

В этом разделе описываются аналогичные процедуры для использования dpcmopt функция в сочетании с двумя функциями dpcmenco и dpcmdeco, которые впервые появляются в предыдущем разделе.

Примечание

Обучающие данные, которые вы используете с dpcmopt должно быть типичным для видов сигналов, которые вы фактически будете квантовать с dpcmenco.

Пример: Сравнение оптимизированных и неоптимизированных параметров DPCM

Этот пример аналогичен примеру в последнем разделе. Однако, где был создан последний пример predictor, partition, и codebook прямолинейным, но бессистемным способом этот пример использует ту же кодовую книгу (теперь называется initcodebook) как начальное предположение для нового оптимизированного параметра кодовой книги. Этот пример также использует предсказательный порядок, 1, как желаемый порядок нового оптимизированного предиктора. dpcmopt функция создает эти оптимизированные параметры, используя пилообразный сигнал x как обучающие данные. Далее в этом примере квантуются сами обучающие данные; в теории оптимизированные параметры подходят для квантования других данных, которые аналогичны x. Заметьте, что среднее квадратное искажение здесь намного меньше, чем искажение в предыдущем примере.

t = [0:pi/50:2*pi];
x = sawtooth(3*t); % Original signal
initcodebook = [-1:.1:1]; % Initial guess at codebook
% Optimize parameters, using initial codebook and order 1.
[predictor,codebook,partition] = dpcmopt(x,1,initcodebook);
% Quantize x using DPCM.
encodedx = dpcmenco(x,codebook,partition,predictor);
% Try to recover x from the modulated signal.
decodedx = dpcmdeco(encodedx,codebook,predictor);
distor = sum((x-decodedx).^2)/length(x) % Mean square error

Это выход

distor =

    0.0063

Компандируйте сигнал

Обзор разделов

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

Для получения дополнительной информации см. quantiz и compand.

Сжатие и расширение последовательности данных с помощью Mu-закон

Сгенерируйте последовательность данных.

data = 2:2:12
data = 1×6

     2     4     6     8    10    12

Сжатие последовательности данных с помощью компрессора mu-закон. Установите значение для mu равным 255. Теперь последовательность сжатых данных находится в диапазоне от 8,1 до 12.

compressed = compand(data,255,max(data),'mu/compressor')
compressed = 1×6

    8.1644    9.6394   10.5084   11.1268   11.6071   12.0000

Разверните последовательность сжатых данных с помощью расширителя mu-закон. Расширенная последовательность данных почти идентична исходной последовательности данных.

expanded = compand(compressed,255,max(data),'mu/expander')
expanded = 1×6

    2.0000    4.0000    6.0000    8.0000   10.0000   12.0000

Вычислите различие между исходной последовательностью данных и расширенной последовательностью.

diffvalue = expanded - data
diffvalue = 1×6
10-14 ×

   -0.0444    0.1776    0.0888    0.1776    0.1776   -0.3553

Сжатие и расширение последовательности данных с помощью A-закона

Сгенерируйте последовательность данных.

data = 1:5;

Сжатие последовательности данных с помощью компрессора A-закона. Установите значение A равным 87,6. Теперь последовательность сжатых данных находится в диапазоне от 3,5 до 5.

compressed = compand(data,87.6,max(data),'A/compressor')
compressed = 1×5

    3.5296    4.1629    4.5333    4.7961    5.0000

Разверните последовательность сжатых данных с помощью расширителя A-закона. Расширенная последовательность данных почти идентична исходной последовательности данных.

expanded = compand(compressed,87.6,max(data),'A/expander')
expanded = 1×5

    1.0000    2.0000    3.0000    4.0000    5.0000

Вычислите различие между исходной последовательностью данных и расширенной последовательностью.

diffvalue = expanded - data
diffvalue = 1×5
10-14 ×

         0         0    0.1332    0.0888    0.0888

Кодирование Хаффмана

Обзор разделов

Кодирование Хаффмана предлагает способ сжатия данных. Средняя длина кода Хаффмана зависит от статистической частоты, с которой источник производит каждый символ из своего алфавита. Словарь кода Хаффмана, который связывает каждый символ данных с кодовым словом, имеет свойство, что никакое кодовое слово в словаре не является префиксом любого другого кодового слова в словаре.

huffmandict, huffmanenco, и huffmandeco функции поддерживают кодирование и декодирование Хаффмана.

Примечание

Для длинных последовательностей из источников, имеющих искаженные распределения и малые алфавиты, арифметическое кодирование сжимается лучше, чем кодирование Хаффмана. Чтобы узнать, как использовать арифметическое кодирование, см. «Арифметическое кодирование».

Кодирование Хаффмана требует статистической информации об источнике кодируемых данных. В частности, p входной параметр в huffmandict функция перечисляет вероятность, с которой источник создает каждый символ в своем алфавите.

Например, рассмотрим источник данных, который производит 1с с вероятностью 0,1, 2с с вероятностью 0,1 и 3с с вероятностью 0,8. Основным вычислительным шагом в кодировании данных из этого источника с помощью кода Хаффмана является создание словаря, который связывает каждый символ данных с кодовым словом. Пример здесь создает такой словарь и затем показывает вектор кодового слова, сопоставленный с конкретным значением из источника данных.

Создайте словарь кода Хаффмана с помощью MATLAB

В этом примере показано, как создать словарь кода Хаффмана с помощью huffmandict функция.

Создайте вектор символов данных и присвойте вероятность каждому.

symbols = [1 2 3];
prob = [0.1 0.1 0.8];

Создайте словарь кода Хаффмана. Наиболее вероятный символ данных 3 связан с однозначным кодовым словом, в то время как менее вероятные символы данных связаны с двухзначными кодовыми словами.

dict = huffmandict(symbols,prob)
dict=3×2 cell array
    {[1]}    {[1 1]}
    {[2]}    {[1 0]}
    {[3]}    {[  0]}

Отображение второй строки словаря. Выходы также показывают, что энкодер Хаффмана, принимающий символ данных 2 заменяет последовательность 1 0.

dict{2,:}
ans = 2
ans = 1×2

     1     0

Создайте и декодируйте код Хаффмана, используя MATLAB

Пример выполняет кодирование и декодирование Хаффмана с использованием источника, чей алфавит имеет три символа. Заметьте, что huffmanenco и huffmandeco функции используют словарь, созданный huffmandict.

Сгенерируйте последовательность данных для кодирования.

sig = repmat([3 3 1 3 3 3 3 3 2 3],1,50);

Задайте набор символов данных и вероятность, связанная с каждым элементом.

symbols = [1 2 3];
p = [0.1 0.1 0.8];

Создайте словарь кода Хаффмана.

dict = huffmandict(symbols,p);

Закодируйте и декодируйте данные. Проверьте, что исходные данные, sigи декодированные данные, dhsig, идентичны.

hcode = huffmanenco(sig,dict);
dhsig = huffmandeco(hcode,dict);
isequal(sig,dhsig)
ans = logical
   1

Арифметическое кодирование

Обзор разделов

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

arithenco и arithdeco функции поддерживают арифметическое кодирование и декодирование.

Представление параметров арифметического кодирования

Арифметическое кодирование требует статистической информации об источнике кодируемых данных. В частности, counts входной параметр в arithenco и arithdeco functions перечисляет частоту, с которой источник создает каждый символ в своем алфавите. Определить частоты можно путем изучения набора тестовых данных из источника. Набор тестовых данных может иметь любой размер, который вы выбираете, пока каждый символ в алфавите имеет ненулевую частоту.

Для примера, перед кодированием данных из источника, который производит 10 x, 10 y и 80 z в типичном 100-символьном наборе тестовых данных, задайте

counts = [10 10 80];

В качестве альтернативы, если больший набор тестовых данных из источника содержит 22 x, 23 y и 185 z, то задайте

counts = [22 23 185];

Создайте и декодируйте арифметический код с помощью MATLAB

Кодируйте и декодируйте последовательность из источника, имеющего три символа.

Создать вектор последовательности, содержащий символы из набора {1,2,3}.

seq = [3 3 1 3 3 3 3 3 2 3];

Установите counts вектор для определения энкодера, который формирует 10 таковые, 20 двоек и 70 третей из типового 100-символьного набора тестовых данных.

counts = [10 20 70];

Примените функции арифметического энкодера и декодера.

code = arithenco(seq,counts);
dseq = arithdeco(code,counts,length(seq));

Проверьте, что выходы декодера совпадают с исходной входной последовательностью.

isequal(seq,dseq)
ans = logical
   1

Квантование сигнала

Пример скалярного квантования 1

Код ниже показывает, как quantiz функция использует partition и codebook чтобы сопоставить вектор действительных чисел, samp, к новому вектору, quantized, записи которого: -1, 0,5, 2 или 3.

partition = [0,1,3];
codebook = [-1, 0.5, 2, 3];
samp = [-2.4, -1, -.2, 0, .2, 1, 1.2, 1.9, 2, 2.9, 3, 3.5, 5];
[index,quantized] = quantiz(samp,partition,codebook);
quantized

Ниже приведен выход.

quantized =

  Columns 1 through 6

   -1.0000   -1.0000   -1.0000   -1.0000    0.5000    0.5000

  Columns 7 through 12

    2.0000    2.0000    2.0000    2.0000    2.0000    3.0000

  Column 13

    3.0000

Пример скалярного квантования 2

Этот пример более четко иллюстрирует природу скалярного квантования. После квантования дискретизированной синусоиды она строит графики исходных и квантованных сигналов. График контрастирует с xони составляют синусоидальную кривую с точками, которые составляют квантованный сигнал. Вертикальная координата каждой точки является значением в векторе codebook.

t = [0:.1:2*pi]; % Times at which to sample the sine function
sig = sin(t); % Original signal, a sine wave
partition = [-1:.2:1]; % Length 11, to represent 12 intervals
codebook = [-1.2:.2:1]; % Length 12, one entry for each interval
[index,quants] = quantiz(sig,partition,codebook); % Quantize.
plot(t,sig,'x',t,quants,'.')
legend('Original signal','Quantized signal');
axis([-.2 7 -1.2 1.2])

См. также

Функции