Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320

Приближение дискретного косинусного преобразования

30.05.2020, 15:44. Показов 908. Ответов 10

Студворк — интернет-сервис помощи студентам
Нашёл документ со схемой (страница 6), попробовал реализовать, но получаю совсем не верные результаты, с разницей на порядок-два. Что не так?

Прямое преобразование:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
[[nodiscard]] svc::matrix<int> svc::forward8x8binDCT2(const svc::matrix<unsigned char>& src_)
{
    svc::matrix<int> tempM = svc::matrix<unsigned char>::toInt(src_);
    
    // Смещение в диапозон [-128;127]
    tempM -= 128;
 
    int a0, a1, a2, a3, a4, a5, a6, a7;
 
    int b0, b1, b2, b3;
 
    int c0, c1, c2;
 
    int d0, d1, d2, d3;
 
    // Проход по строкам
 
    for (size_t rowC = 0; rowC < 8; ++rowC)
    {
        // Шаг 1
 
        a0 = tempM(rowC, 0) + tempM(rowC, 7);
        a7 = tempM(rowC, 0) - tempM(rowC, 7);
        a1 = tempM(rowC, 1) + tempM(rowC, 6);
        a6 = tempM(rowC, 1) - tempM(rowC, 6);
        a2 = tempM(rowC, 2) + tempM(rowC, 5);
        a5 = tempM(rowC, 2) - tempM(rowC, 5);
        a3 = tempM(rowC, 3) + tempM(rowC, 4);
        a4 = tempM(rowC, 3) - tempM(rowC, 4);
 
        // Чётная часть
        // Шаг 3
 
        b0 = a0 + a3;
        b3 = a0 - a3;
        b1 = a1 + a2;
        b2 = a1 - a2;
 
        // Шаг 4
 
        b0 += b1;
        b1 = (b0 >> 1) - b1;
        b2 = (b3 >> 1) - b2;
        b3 = (b2 >> 1) - b3;
 
        tempM(rowC, 0) = b0;
        tempM(rowC, 4) = b1;
        tempM(rowC, 6) = b2;
        tempM(rowC, 2) = b3;
 
        // Нечётная часть
        // Шаг 2
 
        c0 = (a6 >> 1) - a5;
        c1 = ((c0 * 3) >> 2) + a6;
        c2 = (c1 >> 1) - c0;
 
        // Шаг 3
 
        d0 = a4 + c2;
        d1 = a4 - c2;
        d2 = a7 - c1;
        d3 = a7 + c1;
 
        // Шаг 4
 
        d0 = (d3 >> 2) - d0;
        d3 = (d0 >> 2) - d3;
        d1 += d2;
        d2 = (d1 >> 1) - d2;
 
        tempM(rowC, 7) = d0;
        tempM(rowC, 5) = d1;
        tempM(rowC, 3) = d2;
        tempM(rowC, 1) = d3;
    }
 
    // Проход по столбцам
 
    for (size_t colC = 0; colC < 8; ++colC)
    {
        // Шаг 1
 
        a0 = tempM(0, colC) + tempM(7, colC);
        a1 = tempM(0, colC) - tempM(7, colC);
        a2 = tempM(1, colC) + tempM(6, colC);
        a3 = tempM(1, colC) - tempM(6, colC);
        a4 = tempM(2, colC) + tempM(5, colC);
        a5 = tempM(2, colC) - tempM(5, colC);
        a6 = tempM(3, colC) + tempM(4, colC);
        a7 = tempM(3, colC) - tempM(4, colC);
 
        // Чётная часть
        // Шаг 3
 
        b0 = a0 + a3;
        b3 = a0 - a3;
        b1 = a1 + a2;
        b2 = a1 - a2;
 
        // Шаг 4
 
        b0 += b1;
        b1 = (b0 >> 1) - b1;
        b2 = (b3 >> 1) - b2;
        b3 = (b2 >> 1) - b3;
 
        tempM(0, colC) = b0;
        tempM(4, colC) = b1;
        tempM(6, colC) = b2;
        tempM(2, colC) = b3;
 
        // Нечётная часть
        // Шаг 2
 
        c0 = (a6 >> 1) - a5;
        c1 = ((c0 * 3) >> 2) + a6;
        c2 = (c1 >> 1) - c0;
 
        // Шаг 3
 
        d0 = a4 + c2;
        d1 = a4 - c2;
        d2 = a7 - c1;
        d3 = a7 + c1;
 
        // Шаг 4
 
        d0 = (d3 >> 2) - d0;
        d3 = (d0 >> 2) - d3;
        d1 += d2;
        d2 = (d1 >> 1) - d2;
 
        tempM(7, colC) =d0;
        tempM(5, colC) =d1;
        tempM(3, colC) =d2;
        tempM(1, colC) =d3;
    }
 
    return tempM;
}


Обратное:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
[[nodiscard]] svc::matrix<int> svc::inverse8x8binDCT2(const svc::matrix<int>& src_)
{
    svc::matrix<int> tempM(src_);
 
    int a0, a1, a2, a3, a4, a5, a6, a7;
 
    int b0, b1, b2, b3;
 
    int c0, c1, c2, c3;
 
    int d0, d1, d2;
 
    // Проход по строкам
 
    for (size_t rowC = 0; rowC < 8; ++rowC)
    {
        a0 = tempM(rowC, 0);
        a1 = tempM(rowC, 1);
        a2 = tempM(rowC, 2);
        a3 = tempM(rowC, 3);
        a4 = tempM(rowC, 4);
        a5 = tempM(rowC, 5);
        a6 = tempM(rowC, 6);
        a7 = tempM(rowC, 7);
 
        // Чётная часть
        // Шаг 1
 
        a1 = (a0 >> 1) - a1;
        a0 = a1 - a0;
        a3 += a2 >> 1;
        a2 = (a3 >> 1) - a2;
 
        // Шаг 2
 
        b0 = a0 + a3;
        b3 = a0 - a3;
        b1 = a1 + a2;
        b2 = a1 - a2;
 
        // Нечётная часть
        // Шаг 1
 
        a6 += (a5 >> 1);
        a5 = a6 - a5;
        a7 += a4 >> 2;
        a4 = (a7 >> 2) - a4;
 
        // Шаг 2
 
        c0 = a4 + a5;
        c1 = a4 - a5;
        c2 = a7 - a6;
        c3 = a7 + a6;
 
        // Шаг 3
 
        d0 = (c2 >> 1) - c1;
        d1 = ((d0 * 3) >> 2) - c2;
        d2 = (d1 >> 2) + d0;
 
        // Шаг 4
 
        tempM(rowC, 0) = b0 + c3;
        tempM(rowC, 1) = b1 + d1;
        tempM(rowC, 2) = b2 + d2;
        tempM(rowC, 3) = b3 + c0;
        tempM(rowC, 4) = b3 - c0;
        tempM(rowC, 5) = b2 - d2;
        tempM(rowC, 6) = b1 - d1;
        tempM(rowC, 7) = b0 - c3;
    }
 
    // Проход по столбцам
 
    for (size_t colC = 0; colC < 8; ++colC)
    {
        a0 = tempM(0, colC);
        a1 = tempM(1, colC);
        a2 = tempM(2, colC);
        a3 = tempM(3, colC);
        a4 = tempM(4, colC);
        a5 = tempM(5, colC);
        a6 = tempM(6, colC);
        a7 = tempM(7, colC);
 
        // Чётная часть
        // Шаг 1
 
        a1 = (a0 >> 1) - a1;
        a0 = a1 - a0;
        a3 += a2 >> 1;
        a2 = (a3 >> 1) - a2;
 
        // Шаг 2
 
        b0 = a0 + a3;
        b3 = a0 - a3;
        b1 = a1 + a2;
        b2 = a1 - a2;
 
        // Нечётная часть
        // Шаг 1
 
        a6 += (a5 >> 1);
        a5 = a6 - a5;
        a7 += a4 >> 2;
        a4 = (a7 >> 2) - a4;
 
        // Шаг 2
 
        c0 = a4 + a5;
        c1 = a4 - a5;
        c2 = a7 - a6;
        c3 = a7 + a6;
 
        // Шаг 3
 
        d0 = (c2 >> 1) - c1;
        d1 = ((d0 * 3) >> 2) - c2;
        d2 = (d1 >> 2) + d0;
 
        // Шаг 4
 
        tempM(0, colC) = b0 + c3;
        tempM(1, colC) = b1 + d1;
        tempM(2, colC) = b2 + d2;
        tempM(3, colC) = b3 + c0;
        tempM(4, colC) = b3 - c0;
        tempM(5, colC) = b2 - d2;
        tempM(6, colC) = b1 - d1;
        tempM(7, colC) = b0 - c3;
    }
 
    // Возврат в промежуток [0;255]
    tempM += 128;
    return tempM;
}


Обрабатываться будут цветовые компоненты, поэтому сдвиги значений. matrix - простая матрица, работает правильно, проблема не в ней.

Нарисовал ещё диаграму, повторяющую схему из документа, но подписал все переменные, чтобы проще было понять.
Миниатюры
Приближение дискретного косинусного преобразования  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.05.2020, 15:44
Ответы с готовыми решениями:

Реализовать метод скрытия информации (Коха-Жао) в коэффициентах дискретно-косинусного преобразования JPEG
Здравствуйте. Нужно реализовать метод скрытия информации (Коха-Жао) в коэффициентах дискретно-косинусного преобразования JPEG. Для...

Функция преобразования дискретного сигнала
Есть дискретный сигнал, его физический смысл: тепловой поток от времени Ф(t). Сам сигнал правдоподобен. Никакой периодичности сигнала нет. ...

MMX для дискретного преобразования Хартли
Имеется задача необходимо генерировать сигнал (создать массив данных) на языке высокого уровня. После чего к набору данных надо применить...

10
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
30.05.2020, 15:47
Ссылка битая.

Добавлено через 26 секунд
А что это вообще такое JPEG или преобразование Фурье для звука?
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
30.05.2020, 15:52  [ТС]
У меня открывается, странно :/ Вот голая: https://pdfs.semanticscholar.o... 808f5d.pdf

Конечная цель - видеокодек, ввод-вывод JPEG тоже планируется.
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
30.05.2020, 16:07
Эта ссылка у меня тоже не открывается.
Так, а что там в бабочках? Там же ведь умножение, сложение и вычитание 2 членов должно быть. Так?
Где взяли класс matrix?
Изображение в оттенках серого - массив байт?

Добавлено через 6 минут
Цитата Сообщение от Zirak Посмотреть сообщение
a0 = tempM(rowC, 0) + tempM(rowC, 7);
- что за синтакисис? Почему у tempM круглые скобки, а не квадратные?

Добавлено через 1 минуту
Или это типа квадратные скобки?
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
30.05.2020, 16:09  [ТС]
Добавил скрин из документа.

По идее должно быть, но коль уж результаты не верные, может я что-то упускаю. Класс matrix сам написал. Изображение показывает преобразование над массивом из 8 элементов, не обязательно размером в 1 байт.

Цитата Сообщение от FFPowerMan Посмотреть сообщение
что за синтакисис? Почему у tempM круглые скобки, а не квадратные?
Потому что класс построен на одном контейнере (std::vector в данном случае), а не на контейнере контейнеров.
Миниатюры
Приближение дискретного косинусного преобразования  
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
30.05.2020, 16:31
Уберите matrix и его namespace. Возьмите обычный массив двумерный.
Откуда код взяли?
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
30.05.2020, 16:47  [ТС]
Весь код мой собственный. Проблема не в matrix, во-первых, потому что я matrix тестировал, и работает он правильно, по крайней мере, в рамках этой задачи, во-вторых, и с обычными массивами я пробовал, результаты всё равно неправильные.
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
30.05.2020, 16:55
Алгоритм сложный взяли, вот тут попроще будет
http://www.codenet.ru/progr/formt/jpeg_00.php
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
30.05.2020, 16:57  [ТС]
Преобразование в вещественных числах я сделал, оно простое, да. Но оно медленное.
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,249
30.05.2020, 17:07
При чем здесь вещественные числа? Алгоритм поменяй говорю.
0
76 / 68 / 10
Регистрация: 11.07.2016
Сообщений: 320
30.05.2020, 17:15  [ТС]
При том, что метод, описанный по этой ссылке производит вычисления в вещественных числах, не говоря уже о том, что там порядок умножения матриц неправильный. И я уже сказал, что у меня он уже сделан, но работает слишком медленно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.05.2020, 17:15
Помогаю со студенческими работами здесь

функция Дискретного преобразования Фурье (прямое)
Всем привет! Стоит задача реализовать функцию прямого дискретного преобразования Фурье (не Быстрое преобразование фурье/FFT). Покопался в...

Кто знает о всех возможностях дискретного вейвлет преобразования (ДВП)
Всем доброго времени суток=) Не так давно передо мной встала задача : снять данные с АЦП , обработать их в режиме realtime и сделать...

fftwFFTW является C библиотека подпрограмм для вычисления дискретного преобразования Фурье (ДПФ)
http://www.fftw.org/ эта либа только ДПФ считает? То есть всякие фильтры и тд считать не умеет?

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

Вычисление Дискретного Логарифма
Делаю курсовую. Подскажите какой алгоритм вычисление дискретного логарифма самый быстрый. Нужно работать как с маленькими, так и с очень...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru