Форум программистов, компьютерный форум CyberForum.ru

Дискретно - косинусоидальное преобразование - C++

Восстановить пароль Регистрация
 
Ermak_nk
6 / 6 / 0
Регистрация: 11.08.2012
Сообщений: 109
26.02.2013, 22:33     Дискретно - косинусоидальное преобразование #1
Добрый день. Необходимо с помощью ДКП преобразовать изображение. Инфы мало, поэтому не уверен что алгоритм верный. Код приведен ниже. DirectDTC - прямое, InverseDTC - обратное. Функции DirectDTC передается поверхность преобразованая в YCbCr и имеет расположение блоков 8х8 один за другим. С помощью ДКП преобразуются компоненты Cb и Cr, компонента Y остается не тронутой.

Заранее спасибо
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
#define PI 3.14159265358979323846
 
unsigned int SurfaceSize;
 
const int n = 8;
double DTC[n][n];
double DTCT[n][n];
 
void CreateDCTMatrix()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
        {
            if(!i)
            {
                DTC[i][j] = 1/sqrt((double)n);
                DTCT[j][i] = DTC[i][j];
            }
            else
            {
                DTC[i][j] = sqrt(2.0/n)*cos((2.0*j+1.0)*i*PI/(2.0*n));
                DTCT[j][i] = DTC[i][j];
            }
        }
}
 
unsigned char* InverseDTC(char* lpSurface, BITMAPINFOHEADER* bh)
{
    int     BlockSize, PointSize;
    __int16 Cb, Cr;
    double  TmpCb[n][n], TmpCr[n][n];
    unsigned char*  lpSurface2;
    unsigned int imgData;
 
    PointSize = bh->biBitCount/8;
    BlockSize = n*n*PointSize;
    lpSurface2 = new unsigned char[SurfaceSize];
 
    for(int k = 0; k < SurfaceSize; k += BlockSize)
    {
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize;
                TmpCb[i][j] = 0;
                TmpCr[i][j] = 0;
                for(int l = 0; l < 8; l++)
                {
                    Cb = lpSurface[imgData + i*PointSize + 1];
                    Cr = lpSurface[imgData + i*PointSize + 2];
                    TmpCb[i][j] += Cb*DTC[j][l];
                    TmpCr[i][l] += Cr*DTC[j][l];
                }
            }
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize + j*PointSize;
                lpSurface[imgData + 1] = 0;
                lpSurface[imgData + 2] = 0;
                for(int l = 0; l < 8; l++)
                {
                    lpSurface2[imgData + 1] += TmpCb[i][j]*DTCT[j][l];
                    lpSurface2[imgData + 2] += TmpCr[i][j]*DTCT[j][l];
                }
                lpSurface2[imgData] = lpSurface[imgData] + 128;
                lpSurface2[imgData] += 128;
                lpSurface2[imgData] += 128;
            }
    }
 
    delete[] lpSurface;
    return lpSurface2;
}
 
char* DirectDTC(unsigned char* lpSurface, BITMAPINFOHEADER* bh)//умножение на матрицу
{
    int     BlockSize, PointSize;
    __int16 Cb, Cr;
    double  TmpCb[n][n], TmpCr[n][n];
    char*   lpSurface2;
    unsigned int imgData;
 
    PointSize = bh->biBitCount/8;
    BlockSize = n*n*PointSize;
    lpSurface2 = new char[SurfaceSize];
 
    for(int k = 0; k < SurfaceSize; k += BlockSize)
    {
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                TmpCb[i][j] = 0;
                TmpCr[i][j] = 0;
                imgData = k + i*8*PointSize + j*PointSize;
                for(int l = 0; l < 8; l++)
                {
                    Cb = lpSurface[imgData + i*PointSize + 1];
                    Cr = lpSurface[imgData + i*PointSize + 2];
                    Cb-= 128;
                    Cr-= 128;
                    TmpCb[i][j] += Cb*DTCT[j][l];
                    TmpCr[i][l] += Cr*DTCT[j][l];
                }
            }
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize + j*PointSize;
                lpSurface[imgData + 1] = 0;
                lpSurface[imgData + 2] = 0;
                for(int l = 0; l < 8; l++)
                {
                    lpSurface2[imgData + 1] += TmpCb[i][j]*DTC[j][l];
                    lpSurface2[imgData + 2] += TmpCr[i][j]*DTC[j][l];
                }
                lpSurface2[imgData] = lpSurface[imgData] - 128;
            }
    }
    delete[] lpSurface;
    return lpSurface2;
 
}
Добавлено через 9 минут
Т.е. алгоритм такой: создается прямая и транспонированная DTC матрицы, а потом при прямом преобразовании создается временная матрица, которая равна DTCтранспонированная*матрицу данных. Потом временная матрица умножается на DTC.
При обратном - создается временная матрица, которая равно DTC*блок данных(8х8), а потом DTCтранспонированная умножается на временную, после чего данные записываются в поверхность.

Добавлено через 23 часа 38 минут
Забыл совсем сказать - на выходе получается серый квадрат с вертикальными полосами, может кто знает, где косяк? Или хотя бы подскажите, правильно ли в принципе реализован алгоритм?

Добавлено через 34 минуты
Подправил - некоторый силуэт просматривается - но всеравно выдает лажу
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
#define PI 3.14159265358979323846
 
unsigned int SurfaceSize;
 
const int n = 8;
double DTC[n][n];
double DTCT[n][n];
 
void CreateDCTMatrix()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
        {
            if(!i)
            {
                DTC[i][j] = 1/sqrt((double)n);
                DTCT[j][i] = DTC[i][j];
            }
            else
            {
                DTC[i][j] = sqrt(2.0/n)*cos((2.0*j+1.0)*i*PI/(2.0*n));
                DTCT[j][i] = DTC[i][j];
            }
        }
}
unsigned char* InverseDTC(char* lpSurface, BITMAPINFOHEADER* bh)
{
    int     BlockSize, PointSize;
    __int16 Cb, Cr;
    double  TmpCb[n][n], TmpCr[n][n];
    unsigned char*  lpSurface2;
    unsigned int imgData;
 
    PointSize = bh->biBitCount/8;
    BlockSize = n*n*PointSize;
    lpSurface2 = new unsigned char[SurfaceSize];
 
    for(int k = 0; k < SurfaceSize; k += BlockSize)
    {
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize;
                TmpCb[i][j] = 0;
                TmpCr[i][j] = 0;
                for(int l = 0; l < 8; l++)
                {
                    Cb = lpSurface[imgData + l*PointSize + 1];
                    Cr = lpSurface[imgData + l*PointSize + 2];
                    TmpCb[i][j] += Cb*DTC[l][j];
                    TmpCr[i][l] += Cr*DTC[l][j];
                }
            }
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize + j*PointSize;
                lpSurface[imgData + 1] = 0;
                lpSurface[imgData + 2] = 0;
                for(int l = 0; l < 8; l++)
                {
                    lpSurface2[imgData + 1] += TmpCb[j][l]*DTCT[l][j];
                    lpSurface2[imgData + 2] += TmpCr[j][l]*DTCT[l][j];
                }
                lpSurface2[imgData] = lpSurface[imgData] + 128;
                lpSurface2[imgData] += 128;
                lpSurface2[imgData] += 128;
            }
    }
 
    delete[] lpSurface;
    return lpSurface2;
}
 
char* DirectDTC(unsigned char* lpSurface, BITMAPINFOHEADER* bh)//умножение на матрицу
{
    int     BlockSize, PointSize;
    __int16 Cb, Cr;
    double  TmpCb[n][n], TmpCr[n][n];
    char*   lpSurface2;
    unsigned int imgData;
 
    PointSize = bh->biBitCount/8;
    BlockSize = n*n*PointSize;
    lpSurface2 = new char[SurfaceSize];
 
    for(int k = 0; k < SurfaceSize; k += BlockSize)
    {
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                TmpCb[i][j] = 0;
                TmpCr[i][j] = 0;
                imgData = k + i*8*PointSize;
                for(int l = 0; l < 8; l++)
                {
                    Cb = lpSurface[imgData + l*PointSize + 1];
                    Cr = lpSurface[imgData + l*PointSize + 2];
                    Cb-= 128;
                    Cr-= 128;
                    TmpCb[i][j] += Cb*DTCT[l][j];
                    TmpCr[i][l] += Cr*DTCT[l][j];
                }
            }
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize + j*PointSize;
                lpSurface[imgData + 1] = 0;
                lpSurface[imgData + 2] = 0;
                for(int l = 0; l < 8; l++)
                {
                    lpSurface2[imgData + 1] += TmpCb[j][l]*DTC[l][j];
                    lpSurface2[imgData + 2] += TmpCr[j][l]*DTC[l][j];
                }
                lpSurface2[imgData] = lpSurface[imgData] - 128;
            }
    }
    delete[] lpSurface;
    return lpSurface2;
 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.02.2013, 22:33     Дискретно - косинусоидальное преобразование
Посмотрите здесь:

Преобразование типов C++
C++ преобразование
C++ Преобразование С++
C++ Преобразование +'0'
C++ Преобразование
Преобразование C++
C++ Невозможно преобразование
C++ Реализовать метод скрытия информации (Коха-Жао) в коэффициентах дискретно-косинусного преобразования JPEG

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ermak_nk
6 / 6 / 0
Регистрация: 11.08.2012
Сообщений: 109
26.02.2013, 22:47  [ТС]     Дискретно - косинусоидальное преобразование #2
Результат работы вышеприведенного кода(исходное и восстановленное изображение):
Миниатюры
Дискретно - косинусоидальное преобразование   Дискретно - косинусоидальное преобразование  
Ermak_nk
6 / 6 / 0
Регистрация: 11.08.2012
Сообщений: 109
27.02.2013, 22:23  [ТС]     Дискретно - косинусоидальное преобразование #3
Всем спасибо за помощь)) Если кому интересно - вот полностью рабочий код (по крайней мере изображение кодируется и правильно восстанавливается, ибо верность алгоритма так никто и не подтвердил)
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
#define PI 3.14159265358979323846
 
unsigned int SurfaceSize;
 
const int n = 8;
double DTC[n][n];
double DTCT[n][n];
 
void CreateDCTMatrix()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
        {
            if(!i)
            {
                DTC[i][j] = 1/sqrt((double)n);
                DTCT[j][i] = DTC[i][j];
            }
            else
            {
                DTC[i][j] = sqrt(2.0/n)*cos((2.0*j+1.0)*i*PI/(2.0*n));
                DTCT[j][i] = DTC[i][j];
            }
        }
}
unsigned char* InverseDTC(char* lpSurface, BITMAPINFOHEADER* bh)
{
    int     BlockSize, PointSize;
    double Cb, Cr;
    double  TmpCb[n][n], TmpCr[n][n];
    unsigned char*  lpSurface2;
    unsigned int imgData;
 
    PointSize = bh->biBitCount/8;
    BlockSize = n*n*PointSize;
    lpSurface2 = new unsigned char[SurfaceSize];
 
    for(int k = 0; k < SurfaceSize; k += BlockSize)
    {
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize;
                TmpCb[i][j] = 0;
                TmpCr[i][j] = 0;
                for(int l = 0; l < 8; l++)
                {
                    Cb = lpSurface[imgData + l*PointSize + 1];
                    Cr = lpSurface[imgData + l*PointSize + 2];
                    TmpCb[i][j] += Cb*DTC[l][j];
                    TmpCr[i][j] += Cr*DTC[l][j];
                }
            }
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize + j*PointSize;
                Cb = 0;
                Cr = 0;
                for(int l = 0; l < 8; l++)
                {
                    Cb += TmpCb[i][l]*DTCT[l][j];
                    Cr += TmpCr[i][l]*DTCT[l][j];
                }
                lpSurface2[imgData] = lpSurface[imgData] + 128;
                lpSurface2[imgData + 1] = Cb + 128;
                lpSurface2[imgData + 2] = Cr + 128;
            }
    }
 
    delete[] lpSurface;
    return lpSurface2;
}
 
char* DirectDTC(unsigned char* lpSurface, BITMAPINFOHEADER* bh)//умножение на матрицу
{
    int     BlockSize, PointSize;
    double Cb, Cr;
    double  TmpCb[n][n], TmpCr[n][n];
    char*   lpSurface2;
    unsigned int imgData;
 
    PointSize = bh->biBitCount/8;
    BlockSize = n*n*PointSize;
    lpSurface2 = new char[SurfaceSize];
 
    for(int k = 0; k < SurfaceSize; k += BlockSize)
    {
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                TmpCb[i][j] = 0;
                TmpCr[i][j] = 0;
                imgData = k + i*8*PointSize;
                for(int l = 0; l < 8; l++)
                {
                    Cb = lpSurface[imgData + l*PointSize + 1];
                    Cr = lpSurface[imgData + l*PointSize + 2];
                    Cb-= 128;
                    Cr-= 128;
                    TmpCb[i][j] += Cb*DTCT[l][j];
                    TmpCr[i][j] += Cr*DTCT[l][j];
                }
            }
        for(int i = 0; i < 8; i++)
            for(int j = 0; j < 8; j++)
            {
                imgData = k + i*8*PointSize + j*PointSize;
                Cb = 0;
                Cr = 0;
                for(int l = 0; l < 8; l++)
                {
                    Cb += TmpCb[i][l]*DTC[l][j];
                    Cr += TmpCr[i][l]*DTC[l][j];
                }
                lpSurface2[imgData + 1] = Cb;
                lpSurface2[imgData + 2] = Cr;
                lpSurface2[imgData] = lpSurface[imgData] - 128;
            }
    }
    delete[] lpSurface;
    return lpSurface2;
}
Yandex
Объявления
27.02.2013, 22:23     Дискретно - косинусоидальное преобразование
Ответ Создать тему
Опции темы

Текущее время: 02:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru