Дискретное косинусоидное преобразование (DCT) представляет изображение как сумму синусоидов меняющихся величин и частот. dct2
функция вычисляет двумерное дискретное косинусоидальное преобразование (DCT) изображения. DCT имеет свойство, что для типичного изображения большая часть визуально значимой информации об изображении сконцентрирована всего в нескольких коэффициентах DCT. По этой причине DCT часто используется в приложениях сжатия изображений. Например, DCT является основой международного стандартного алгоритма сжатия изображений с потерями, известного как JPEG. (Название получило от рабочей группы, разработавшей стандарт: Объединенная группа фотоэкспертов.)
Двумерный DCT матрицы M-на-N A
определяется следующим образом.
Значения Bpq называются коэффициентами DCT A
. (Обратите внимание, что матричные индексы в MATLAB® всегда начинаться с 1, а не с 0; поэтому MATLAB элементов матрицы A(1,1)
и B(1,1)
соответствуют математическим величинам A00 и B00, соответственно.)
DCT является обратным преобразованием, и его обратное задается как
Обратное уравнение DCT может быть интерпретировано как означающее, что любая M-на-N матрица A
может быть записана как сумма MN функций вида
Эти функции называются базисными функциями DCT. Коэффициенты DCT, Bpq, могут быть расценены как веса, применяемые к каждой функции базиса. Для матриц 8 на 8 64 базисные функции проиллюстрированы этим изображением.
64 базисных функции матрицы 8 на 8
Горизонтальные частоты увеличиваются слева направо, а вертикальные - сверху вниз. Постоянная функция базиса в верхнем левом углу часто называется функцией базиса DC, а соответствующая B00 коэффициентов DCT часто называется коэффициентом DC.
Существует два способа вычислить DCT с помощью программного обеспечения Image Processing Toolbox™. Первый метод - использовать dct2
функция. dct2
использует основанный на FFT алгоритм для быстрого расчета с большими входами. Вторым методом является использование матрицы преобразования DCT, которая возвращается функцией dctmtx
и может быть более эффективным для малых квадратных входов, таких как 8 на 8 или 16 на 16. Матрица преобразования M-на-M T
дается
Для матрицы M-на-M A
, T*A
- матрица M-на-M, столбцы которой содержат одномерный DCT столбцов A
. Двумерный DCT A
может быть вычислено следующим B=T*A*T'
. Начиная с T
является действительной ортонормальной матрицей, её обратная сторона такая же, как и транспонирование. Поэтому обратный двумерный DCT B
задается T'*B*T
.
В этом примере показано, как сжать изображение с помощью дискретного косинусоидного преобразования (DCT). Пример вычисляет двумерный DCT блоков 8 на 8 в вход изображении, отбрасывает (устанавливает на нуль) все коэффициенты, кроме 10 из 64 DCT в каждом блоке, а затем восстанавливает изображение, используя двумерный обратный DCT каждого блока. В примере используется метод transform матрицы расчета.
DCT используется в алгоритме сжатия изображений JPEG. Вход изображение разделён на блоки 8 на 8 или 16 на 16, и двумерный DCT вычисляется для каждого блока. Затем коэффициенты DCT квантуются, кодируются и передаются. Приемник JPEG (или устройство чтения файлов) декодирует квантованные коэффициенты DCT, вычисляет обратный двумерный DCT каждого блока, а затем помещает блоки обратно вместе в одно изображение. Для типичных изображений многие коэффициенты DCT имеют значения, близкие к нулю. Эти коэффициенты могут быть отброшены, не оказывая серьезного влияния на качество восстановленного изображения.
Прочтите изображение в рабочую область и преобразуйте его в double
классов.
I = imread('cameraman.tif');
I = im2double(I);
Вычислите двумерный DCT блоков 8 на 8 в изображении. Функция dctmtx
возвращает матрицу преобразования N на N DCT.
T = dctmtx(8); dct = @(block_struct) T * block_struct.data * T'; B = blockproc(I,[8 8],dct);
Отменить все коэффициенты, кроме 10 из 64 коэффициентов DCT в каждом блоке.
mask = [1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; B2 = blockproc(B,[8 8],@(block_struct) mask .* block_struct.data);
Восстановите изображение с помощью двумерного обратного DCT каждого блока.
invdct = @(block_struct) T' * block_struct.data * T; I2 = blockproc(B2,[8 8],invdct);
Отобразите оригинальное изображение и восстановленное изображение один за другим. Несмотря на некоторую потерю качества в восстановленном изображении, она четко распознаваема, хотя почти 85% коэффициентов DCT были отброшены.
imshow(I)
figure imshow(I2)