Как работает эта реализация 1D IDCT?

У меня есть реализация обратного дискретного косинусного преобразования, и я пытаюсь понять, как они попали в этот код. До сих пор я понял, что это, вероятно, оптимизированная реализация Кули-Тьюки Radix-2 Decimation вовремя для DCT вместо DFT (дискретного преобразования Фурье).

Однако я все еще не понимаю, что именно происходит на каждом этапе. Я подумал, что константы Wx, вероятно, являются факторами вращения.

Может ли кто-нибудь дать ссылку на объяснение или дать какое-то объяснение этому коду?

//Twiddle factors
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */

//Discrete Cosine Transform on a row of 8 DCT coefficients.
NJ_INLINE void njRowIDCT(int* blk) {
    int x0, x1, x2, x3, x4, x5, x6, x7, x8;
    int t;
    if (!((x1 = blk[4] << 11)
        | (x2 = blk[6])
        | (x3 = blk[2])
        | (x4 = blk[1])
        | (x5 = blk[7])
        | (x6 = blk[5])
        | (x7 = blk[3])))
    {
        blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = blk[0] << 3;
        return;
    }
    x0 = (blk[0] << 11) + 128;  //For rounding at fourth stage

    //First stage
    /*What exactly are we doing here? Do the x values have a meaning?*/
    x8 = W7 * (x4 + x5);
    x4 = x8 + (W1 - W7) * x4;
    x5 = x8 - (W1 + W7) * x5;
    x8 = W3 * (x6 + x7);
    x6 = x8 - (W3 - W5) * x6;
    x7 = x8 - (W3 + W5) * x7;

    //Second stage
    x8 = x0 + x1;
    x0 -= x1;
    x1 = W6 * (x3 + x2);
    x2 = x1 - (W2 + W6) * x2;
    x3 = x1 + (W2 - W6) * x3;
    x1 = x4 + x6;
    x4 -= x6;
    x6 = x5 + x7;
    x5 -= x7;

    //Third stage
    x7 = x8 + x3;
    x8 -= x3;
    x3 = x0 + x2;
    x0 -= x2;
    x2 = (181 * (x4 + x5) + 128) >> 8;
    x4 = (181 * (x4 - x5) + 128) >> 8;

    //Fourth stage
    blk[0] = (x7 + x1) >> 8;  //bit shift is to emulate 8 bit fixed point precision
    blk[1] = (x3 + x2) >> 8;
    blk[2] = (x0 + x4) >> 8;
    blk[3] = (x8 + x6) >> 8;
    blk[4] = (x8 - x6) >> 8;
    blk[5] = (x0 - x4) >> 8;
    blk[6] = (x3 - x2) >> 8;
    blk[7] = (x7 - x1) >> 8;

}

person Tony The Lion    schedule 04.01.2012    source источник
comment
Красивый! Я люблю алгоритмический код, которому нужны обфускаторы, когда они у вас есть.   -  person Dr. Andrew Burnett-Thompson    schedule 04.01.2012


Ответы (2)


Я не эксперт в DCT, но я написал несколько Реализации БПФ в свое время, поэтому я попытаюсь ответить на этот вопрос. Пожалуйста, отнеситесь к следующему с щепоткой соли.

void njRowIDCT(int* blk)

Вы правильно говорите, что алгоритм выглядит как 8-битный Radix-2 DCT, который использует арифметику с фиксированной запятой с точностью 24: 8. Я предполагаю точность, потому что последний этап сдвигается вправо на 8, чтобы получить желаемое (это и контрольный комментарий;)

Поскольку его длина равна 8, его мощность равна 3 (2 ^ 3 = 8), что означает, что в DCT 3 ступени. Пока все это очень похоже на БПФ. «Четвертый этап» кажется просто масштабированием для восстановления исходной точности после арифметики с фиксированной запятой.

Насколько я понимаю, этап ввода - это инверсия битов из входного массива blk в локальные переменные x0-x7. x8 кажется временной переменной. Извините, я не могу быть более описательным, чем это.

Этап реверсирования битов

Реверс битов ввода

Обновить

Взгляните на DSP для ученых и инженеров. Он дает ясное и точное объяснение тем, связанных с обработкой сигналов. Эта глава посвящена DCT (перейдите к стр. 497).

Wn (коэффициенты вращения) соответствуют базовым функциям в этой главе, хотя обратите внимание, что это описание DCT 8x8 (2D).

Что касается трех этапов, которые я упомянул, сравните с описанием 8-точечного БПФ:

8ptFFTGraph

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

Тот или кто-то, кто знает, о чем они говорят, шаг вперед ;-)

Я вернусь к этой странице и буду редактировать по мере расшифровки кода

person Dr. Andrew Burnett-Thompson    schedule 04.01.2012
comment
Спасибо за +1, хотя на данный момент это неполный и слегка искривленный ответ. Буду признателен за отзывы в комментариях - если вы знаете, что добавить к этому, я здесь не для славы, будьте счастливы +1 к вашим ответам - person Dr. Andrew Burnett-Thompson; 05.01.2012
comment
Большое спасибо за ваши усилия, это определенно помогает :) Если вы что-то узнаете, пожалуйста, добавьте в ответ - person Tony The Lion; 05.01.2012
comment
Я думаю, что диаграмма, которая у вас здесь, на самом деле перевернута по отношению к коду. В коде более глубокие факторы поворота выполняются на этапе 1, тогда как на диаграмме они представлены на этапе 3. - person Mysticial; 05.01.2012
comment
А что касается инверсии битов, то не похоже, что выходные данные кода упорядочены или инвертированы. Похоже, это какое-то отражение / вращение ... хотя я не вижу для этого мотивации. - person Mysticial; 05.01.2012
comment
@TonyTheLion, подойдет! Что касается реверсирования битов, если вы посмотрите на индекс массива blk до x0-x7, он действительно соответствует этой диаграмме: i.stack.imgur.com/ZizHD.png, и индексы немного поменяны местами. Вторая диаграмма, которую я опубликовал, представляет собой диаграмму БПФ, НЕ DCT, но я опубликовал, поскольку там может быть полезная информация (например: этапы, манипуляции с коэффициентом поворота) - person Dr. Andrew Burnett-Thompson; 05.01.2012
comment
@Mystical, да вторая диаграмма БПФ НЕ DCT. Факторы вращения, кажется, применяются на этапах 1, 2 в DCT. Почему? Точно сказать не могу. Хм ... - person Dr. Andrew Burnett-Thompson; 05.01.2012
comment
@ Доктор Эндрю Бёрнетт-Томпсон. Помогло бы я, если бы я тоже разместил код для ColIDCT? - person Tony The Lion; 05.01.2012
comment
@TonyTheLion уверен, что чем больше, тем лучше. Вы тоже пробовали math.stackexchange.com? Он не основан на программировании, но кто-то может знать об алгоритме больше. С уважением, - person Dr. Andrew Burnett-Thompson; 05.01.2012

И ДПФ, и ДКП представляют собой просто линейные преобразования, которые могут быть представлены как единое комплексное матричное умножение (иногда сокращенное для строго реального ввода). Таким образом, вы можете просто объединить приведенные выше уравнения, чтобы получить формулу для каждого последнего члена, которая должна в конечном итоге эквивалентна одной строке матрицы линейного преобразования (без учета проблем округления). Затем посмотрите, как приведенная выше кодовая последовательность вручную выполняет общую оптимизацию подвыражения или рефакторинг между и / или внутри вычислениями строк.

person hotpaw2    schedule 04.01.2012
comment
+1 от меня @hotpaw, что ты думаешь об этом Q? Как ты думаешь, мы сможем решить эту проблему вместе? Как я уже сказал, я не эксперт по DCT. С Уважением - person Dr. Andrew Burnett-Thompson; 05.01.2012