Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
Задание на экзамен – создание формы, позволяющей выполнять архивацию полутонового изображения с использованием алгоритма JPEG
В первоначальный вариант экзаменационного задания были внесены изменения из-за ошибок и неточностей, содержавшихся в приведенных функциях. Приведем сначала интерфейс формы в режиме макета:

Рис.1. Форма в режиме макета
Теперь приведем форму в режиме выполнения и просмотр основных характеристик сжатия – отношения сигнал/шум и времени кодирования.

Рис.2. Результат выполнения алгоритма сжатия
В командном окне среды, кроме того, отображается время кодирования сообщения, что позволяет провести эксперименты над различными изображениями:
Elapsed time is 8.102382 seconds.
Щелкнув на кнопке «Показать в отдельном окне» (под исходным изображением), мы сможем просмотреть исходное изображение в новом окне:

Рис.3. Исходное изображение в новом окне
Щелкнув на вторую кнопку «Показать в отдельном окне», мы сможем просмотреть результат сжатия:

Рис.4. Результат сжатия с заданными параметрами
При нажатии на кнопку «Рассчитать и показать коэффициенты ДКП» появится окно с изображением базисных функций дискретного косинусного преобразования:

Рис.5. Базисные функции ДКП
Нажав на кнопку «Загрузить и показать коэффициенты квантования», пользователь сможет просмотреть заданные с помощью слайдера и размерности блока коэффициенты квантования:

Рис.6. Диаграмма коэффициентов квантования
При нажатии на кнопку «Выполнить кодирование» осуществляется сжатие полутонового изображения по алгоритму JPEG.
При нажатии на исходное изображение (первая область вывода) правой кнопкой мыши мы получим изображения и численные значения коэффициентов ДКП для выбранного участка изображения:

Рис.7. Просмотр результатов кодирования
Также в текстовом поле отображается соотношение сигнал/шум, характеризующее степень сжатия изображения.
По результатам работы должен быть написан отчет, который содержит:
· Титульный лист
· Введение
· Описание алгоритма сжатия данных JPEG (изложение материала должно быть у каждого индивидуальное)
· Иллюстрации, содержащие:
§ Интерфейс формы
§ Результаты выполнения обработчиков на форме
§ Результаты проведенных экспериментов и выводы (самостоятельно изучить смысл соотношения сигнал/шум). Эксперименты провести не менее чем с тремя изображениями (на вход - .bmp, на выходе – сжатое изображение).
· Список модулей и краткое описание (код приводить не надо)
· Трудности, возникшие в процессе проектирования формы
· Выводы
Должна быть подготовлена презентация на 10 минут с докладом по тексту отчета.
Оценивание будет производиться следующим образом:
· 100 баллов – наличие формы с рабочими функциями
· 90 баллов – нет возможности просматривать блоки ДКП, все остальные функции работают
· 80 баллов – не реализованы функции просмотра коэффициентов ДКП и квантования
· 70 баллов – не реализована возможность задания параметров кодирования
· 60 баллов – реализован только вывод исходного и закодированного изображения с использованием постоянных параметров
· 50 баллов – формы нет, кодирование изображения происходит только с использованием командного окна
· 40 баллов – функции, использующиеся для кодирования, работают только в командном окне, форма реализована частично (выбор исходного изображения)
· 30 баллов – реализованы отдельные фрагменты кода
· 20 баллов – имеются доклад и презентация
· 10 баллов – имеется только текст доклада
· 0 баллов – за списанную работу
Далее приведем коды функций и обработчиков для объектов формы:
Функции:
function basisMatrix (имеет вспомогательное назначение – использовалась для проверки демонстрации базовых блоков ДКП, есть смысл ее включить в набор функций)
global Params % для наглядности вводим коэффициент "растяжения" поверхности
% (масштабирования по горизонтали)
resolution = 10; % считать с формы параметры кодирования
figure; % открываем новое окно
N = Params. BlockSize;
for k = 1:N
for l = 1:N
subplot( N, N,(k-1)*N+l );
% выбираем часть окна для вывода графика
% формируем матрицу для получения формы базисной функции
in = zeros(N*resolution);
in(k, l) = 1; % "тестовый сигнал" для оценки отклика
% выполнить прямое ДКП
out = dct2(in);
mesh(out); % вывести в заданной части окна
axis off; % отключить вывод числовых осей на графике
end
end
end
function [cut_linear_coefs, num_coefs] = CutCoefs(linear_coefs)
global Params % выделяем память под массивы "обрезанных" коэффициентов
cut_linear_coefs = zeros(Params. NumBlocks(1)*Params. NumBlocks(2), ...
Params. BlockSize*Params. BlockSize);
% и под массив количества коэффициентов в каждом блоке
num_coefs = zeros(Params. NumBlocks(1)*Params. NumBlocks(2),1);
% вспомогательные временные переменные – для краткости
d = uint16(Params. BlockSize);
t = d*d; % в зависимости от установленного способа кодирования коэффициентов ДКП
switch Params. CodeNonZero
case 0 % кодировать заданное число коэффициентов
% строим маску, одинаковую для всех блоков
mask = ones(1, Params. NumFirstDCTCoefs);
if Params. NumFirstDCTCoefs < t
add_mask = zeros(1, t-Params. NumFirstDCTCoefs);
mask = [mask add_mask];
end
% проходим по всем блокам заданного размера
for m = 1:Params. NumBlocks(1)*Params. NumBlocks(2)
% количество линейных блоков
cut_linear_coefs(m, :) = linear_coefs(m, :) .* mask;
% обнуляем лишние коэффициенты
num_coefs(m+1) = Params. NumFirstDCTCoefs; % количество коэффициентов!=0
end
case 1 % кодировать все ненулевые коэффициенты
% проходим по всем блокам заданного размера
for m = 1:Params. NumBlocks(1)*Params. NumBlocks(2)
% количество линейных блоков % находим индекс последнего коэффициента, неравного 0
last_non_zero_ind = find(linear_coefs(m, :), 1, 'last');
% строим маску с необходимым числом единиц и нулей
if (last_non_zero_ind == t) % чтобы в цикле избежать изменения размера
mask = ones(1, last_non_zero_ind);
elseif isempty(last_non_zero_ind) % хотя бы один коэффициент должен быть
last_non_zero_ind = 1; mask = [ones(1, last_non_zero_ind) zeros(1, t-last_non_zero_ind)];
else mask = [ones(1, last_non_zero_ind) zeros(1, t-last_non_zero_ind)];
end
cut_linear_coefs(m, :) = linear_coefs(m, :) .* mask; % обнуляем лишние коэффициенты
num_coefs(m+1) = last_non_zero_ind; % количество коэффициентов !=0
end
end
function [out_image] = DCT2Im(in_image)
global Params
out_image = zeros(Params. ImageSize);
% создаем матрицу для хранения восст. изображения
% проходим по всем блокам заданного размера
d = uint16(Params. BlockSize);
% d – размер блока по каждой оси % в цикле используем векторизацию – за один раз рассчитываем
% сразу целый блок благодаря использованию конструкций [1:d]
for m = 0:Params. NumBlocks(1)-1 % количество блоков по вертикали
for n = 0:Params. NumBlocks(2)-1 % количество блоков по горизонтали
out_image(m*d+[1:d], n*d+[1:d]) = idct2(in_image(m*d+[1:d], n*d+[1:d]));
end
end
function [out_image] = DCT2Scale(in_image)
global Params
out_image = zeros(Params. ImageSize);
coef_scales = generate_Scales(Params. BlockSize, Params. Quality);
d = uint16(Params. BlockSize);
for m=0:Params. NumBlocks(1)-1
for n=0:Params. NumBlocks(2)-1
out_image(m*d+[1:d], n*d+[1:d]) = round(in_image(m*d+[1:d], n*d+[1:d]) ...
./ coef_scales);
end
end
function [c_ratio] = EstimateBitRate(cut_linear_coefs)
global Params
c_ratio = 0; % сформировать примерные длины кодов Хаффмана
table_code_len = Generate_Scales(Params. BlockSize*Params. BlockSize, 0);
% проходим по всем блокам заданного размера
pDC = 0; % последний DC-коэф. сначала = 0
for m = 1:Params. NumBlocks(1)*Params. NumBlocks(2) % количество линейных блоков
% рассчитать размер каждого блока
s = EstimateBlockBitRate(cut_linear_coefs(m, :), pDC, table_code_len);
pDC = cut_linear_coefs(m, 1); % запомнить последний DC
c_ratio = c_ratio + s; % суммируем по всему изображению
end
function [block_bitrate] = EstimateBlockBitRate(linear_block, prev_DC, table_len)
% Оценка размера блока в битах в соответствии с кодированием квантованныx
% коэффициентов ДКП в алгоритме JPEG
% Входные параметры:
% linear_block - массив целочисленных значений Nx1
% prev_DC - значение первого коэффициента предыдущего % блока
% table_len - условная таблица длин кодов Хаффмана % (Nxn) элементов
% Выходные параметры: % block_bitrate - размер блока в битах
% Алгоритм: % Кодирование первого значения (DC) и остальных значений (AC)
% выполняется по отдельности. % Для кодирования DC вычисляется разность между DC и prev_DC,
% которая кодируется унарным кодом + само число. Для оценки
% длины кода достаточно использовать двойную длину унарного % кода
% При кодировании AC каждое число заменяется на пару % <число_нулей, значение>. Для этой пары берется код из
% таблицы Хаффмана. Для оценки кода достаточно знать длину
% этого кода
%-------
N = size(linear_block, 1); % определяем размер массива
% рассчитываем размер кода для DC-коэффициента
diff = linear_block(1) - prev_DC;
block_bitrate = 2*(size(abs(diff),2)+1);
% унарный код + само число.
% рассчитываем размер кода для всех AC-коэффициентов
nz_ind = find(linear_block); % получаем список всех ненулевых коэффициентов
snd = size(nz_ind,2);
%число ненулевых коэффициентов
%--
% Вариант 1 - с поэлементной обработкой % начинаем обход всех ненулевых со
% второго ненулевого элемента
%for i=2:snd % Z = nz_ind(i) - nz_ind(i-1);
% число нулей между ними + 1 (для доступа к таблице)
% x = linear_block(nz_ind(i)); % само значение % R = ceil(log2(abs(x))) + 1;
% длина унарного кода значения - № строки в таблице % C = R; % длина номера столбца в таблице %
% лишняя (можно вместо C использовать R) % block_bitrate = block_bitrate + table_len(R, Z+1) + C;
%end % добавляем 4 бита на символ конца блока %block_bitrate = block_bitrate + 4;
%--
% Вариант 2 - с векторной обработкой % сначала находим смещение каждого ненулевого коэффициента от
% предыдущего. Для этого просто сдвигаем вектор индексов на 1 и поэлементно % вычитаем из исходного
nz_ind_shift = nz_ind(1:(snd-1)); % берем только первые SND-1 ненулевых коэффициентов
Z = nz_ind(2:snd) - nz_ind_shift; % вычитаем их из первого (кроме первого эл-нта) вектора
x = linear_block(nz_ind(2:size(nz_ind,2))); % берем вектор самих значений
R = ceil(log2(abs(x))) + 1; % рассчитываем количество битов
C = R; % запомнить (лишняя, можно вместо C исп-ть R)
ind = (Z-1)*N+R; % находим линейные индексы для таблицы
block_bitrate = sum(table_len(ind) + C) + 4; % суммируем длины кодовых слов и C + 4 бита (EOB)
%
function [coefs_scale] = Generate_Scales(N, Quality)
% Генерация коэффициентов квантования для масштабирования коэф. ДКП
% Входные параметры: % N - количество элементов в квадратной матрице
% Quality - условное значение параметра качества >0 % Выходные параметры:
% coefs_scale - матрица коэффициентов квантования размером NxN (double)
% Алгоритм: % Формирование матрицы с монотонно увеличивающимися коэффициентами
%
coefs_scale = zeros(N); % заранее генерируем квадратную матрицу
%--
% Вариант 1 - с поэлементной обработкой
%for m=1:N
% for n=1:N
% coefs_scale(m, n) = 1 + (m+n)*Quality;
% end
%end
%--
% Вариант 2 - ориентированный на векторную обработку
% выполняется быстрее в 3-5 раз (в зависимости от N)
coefs_scale(1,:) = (1+(1+1)*Quality):Quality:(1+(1+N)*Quality);
% генерируем первую строку
for m=2:N
coefs_scale(m,:) = coefs_scale(m-1,:) + Quality;
% ост. строки увеличиваем на Quality
end %-----
function [Indices, Indices_l] = Generate_Zigzag(N)
% Генерация индексов для обхода матрицы по зигзагу
% Входные параметры:
% N - количество элементов в квадратной матрице
% Выходные параметры: % Indices - массив (N^2,2), содержащий номера строк
% и столбцов элементов квадратной матрица в порядке
% обхода. Первый столбец соответствует номеру строки,
% второй столбец - номера столбца % Indices_l - массив (N^2,1), содержащий ту же самую
% информацию, что и Indices, но номера
% приведены в виде одномерного смещения от начала
% массива. При этом учитывается, что матрица в MATLAB
% хранится по столбцам!
%
Indices = zeros(N*N, 2); % заранее выделяем место под матрицу (N^2 x 2)
% Первую диагонально проходим вручную (один элемент)
Indices(1, :) = [1 1];
a = 2; % сдвигаем индекс в таблице индексов % обрабатываем диагонали длиной больше 1 (все, кроме первой и последней)
for t=2:1:(2*N-2) % В матрице NxN строк есть 2N-1 диагоналей. Одну уже прошли
% сначала отрабатываем переход на первый элемент диагонали
% и устаналиваем необходимые параметры движения по ней
if (rem(t,2)~=0) % если диагональ нечетная (rem – остаток от деления)
dr = 1; dc = -1; % приращения для перехода к следующему элементу диагонали
if (t <= N) % длина диагонали растет или уменьшается?
P = t; % если растет - то число элементов равно номеру диагонали
Indices(a, 1) = Indices(a-1, 1);
Indices(a, 2) = Indices(a-1, 2)+1;
else
P = 2*N-t; % иначе: (2N - номер диагонали)
Indices(a, 1) = Indices(a-1, 1)+1;
Indices(a, 2) = Indices(a-1, 2);
end
else % если диагональ четная
dr = -1;
dc = 1;
if (t <= N) % длина диагонали растет или уменьшается?
P = t; % если растет - то число элементов равно номеру диагонали
Indices(a, 1) = Indices(a-1, 1) + 1;
Indices(a, 2) = Indices(a-1, 2);
else
P = 2*N-t; % иначе: (2N - номер диагонали)
Indices(a, 1) = Indices(a-1, 1);
Indices(a, 2) = Indices(a-1, 2)+1;
end
end
a = a + 1; % первый элемент диагонали обработали
% теперь проходим по оставшимся элементам диагонали
for i=2:1:P
Indices(a, 1) = Indices(a-1, 1) + dr;
Indices(a, 2) = Indices(a-1, 2) + dc;
a = a + 1;
end
end % Последнюю диагонально проходим вручную (один элемент)
Indices(N*N, :) = [N N]; % Дополнительно расчитывает линейные индексы элементов
% Для преобразования (row, col) => ind может использоваться
% функция sub2ind вида % ix = sub2ind([n n], ind(:,1), ind(:,2));
% Но поскольку она очень "медленная", то вместо нее
% лучше рассчитывать смещение от начала матрицы "вручную". При этом
% следует помнить, что в MATLAB двумерный массив хранится по столбцам.
Indices_l = (Indices(:,2)-1)*N + Indices(:,1);
%
function [out_image] = Im2DCT(in_image)
global Params
out_image = zeros(Params. ImageSize);
% создаем матрицу для хранения ДКП
% проходим по всем блокам заданного размера
d = uint16(Params. BlockSize);
% d – размер блока по каждой оси
% в цикле используем векторизацию – за один раз рассчитываем
% сразу целый блок благодаря использованию конструкций [1:d]
for m = 0:Params. NumBlocks(1)-1 % количество блоков по вертикали
for n = 0:Params. NumBlocks(2)-1 % количество блоков по горизонтали
out_image(m*d+[1:d], n*d+[1:d]) = dct2(in_image(m*d+[1:d], n*d+[1:d]));
end
end
function read_params(hObject, eventdata, handles)
global Params % взять выбранный размер блока
% Params. BlockSize = 8;
sfd = get(handles. menu, 'String'); %выбор размера блока из меню.
Params. BlockSize = str2num(strtok(sfd{get(handles. menu, 'Value')}));
Params. Quality = round(get(handles. slider_Quality, 'Value'));
% режим кодирования коэффициентов ДКП
Params. CodeNonZero = get(handles. radiobutton_CodeNonZero, 'Value');
% количество оставляемых ДКП коэффициентов Params. NumFirstDCTCoefs = 0;
if (Params. CodeNonZero == 0) % если надо кодировать только первые коэффициенты
Params. NumFirstDCTCoefs = uint16(str2num(get(handles. edit_NumFirstDCTCoefs, 'String')));
% проверить, чтобы число оставляемых коэффициентов было не больше
% числа коэффциентов в блоке. Если что – скорректировать
if (Params. NumFirstDCTCoefs > Params. BlockSize*Params. BlockSize )
Params. NumFirstDCTCoefs = Params. BlockSize*Params. BlockSize;
set(handles. edit_NumFirstDCTCoefs, 'String', num2str(Params. NumFirstDCTCoefs));
end
end
function [out_matrix] = RollMatrix(in_linear, ind, ind_l)
% Сворачивание вектора в квадратную матрицу в вектор путем обхода по зигзагу
% Входные параметры: % in_linear - исходный вектор
% ind - массив индексов (NxN,2) % ind_l - массив индексов (NxN,1)- индексы представлены
% в виде смещений от начала массива (т. е. одним % числом) % Выходные параметры:
% out_matrix - матрица, содержащая элементы вектора, % упорядоченные в соответствии с таблицей индексов
%
n = sqrt(size(in_linear, 2));
% из размера вектора определить размер матрицы
out_matrix = zeros(n);
% заранее выделяем место под квадратную матрицу
%--
% Вариант 1 - с поэлементной обработкой %for i=1:n*n % out_matrix(ind(i,1), ind(i,2)) = in_linear(i); %end
%--
% Вариант 2 - с векторной обработкой % для чтения сразу нескольких элементов матрицы необходимо, чтобы
% индексы ее элементов были перечислены в необходимом порядке % виде скалярных значений.
out_matrix(ind_l) = in_linear;
%
function out_image = Scale2DCT(in_image)
global Params
out_image = zeros(Params. ImageSize);
% создаем матрицу для хранения восст. коэффициентов
% сгенерировать коэффициенты масштабирования
coef_descales = Generate_Scales(Params. BlockSize, Params. Quality);
d = uint16(Params. BlockSize); % d – размер блока по каждой оси
% проходим по всем блокам заданного размера
for m = 0:Params. NumBlocks(1)-1 % количество блоков по вертикали
for n = 0:Params. NumBlocks(2)-1 % количество блоков по горизонтали
out_image(m*d+[1:d], n*d+[1:d]) = in_image(m*d+[1:d], n*d+[1:d]).* coef_descales;
end
end
function linear_coefs = Scale2Zigzag(in_image)
global Params
% заранее выделить место под линейное хранение коэффициентов
% двумерный массив. Число строк – полное число блоков, число столбцов –
% количество элементов в блоке
linear_coefs = zeros(Params. NumBlocks(1)*Params. NumBlocks(2), ...
Params. BlockSize*Params. BlockSize);
% сформировать последовательность индексов для обхода зигзагом
% формируются индексы и в матричной форме и в линейной (для самопроверки)
% после тестирования достаточно оставить только линейную форму
[zigzag_ind, zigzag_ind_l] = Generate_Zigzag(Params. BlockSize);
% проходим по всем блокам заданного размера
d = uint16(Params. BlockSize); % d – размер блока по каждой оси
t = d*d; % t – число элементов в блоке
p = 1; % храним в новом массиве
for m = 0:Params. NumBlocks(1)-1
% количество блоков по вертикали
for n = 0:Params. NumBlocks(2)-1
% количество блоков по горизонтали
ttt = UnrollMatrix(in_image(m*d+[1:d], n*d+[1:d]), zigzag_ind, zigzag_ind_l);
linear_coefs(p, :) = ttt;
% запомнить результат
p = p+1;
% перейти к следующему блоку
end
end
function [res] = SNR(im_x, im_y)
% Вычисление отношения сигнал-шум % Входные параметры:
% im_x - исходное изображение % im_y - восстановленное изображение %
% Изображения должны быть одинакового размера
% Выходные параметры:
% res - отношение сигнал-шум
%
N = size(im_x,1) * size(im_x,2);
% количество пикселов в изображении
% находим мощность исходного изображения
imx_sq = im_x.* im_x; % Src*Src – каждый элемент – в квадрат
P_x = sum(sum(imx_sq))/N; % Power(Src) – разделить сумму всех элементов % матрицы на число элементов
% находим ошибку кодирования
e = im_x-im_y; % одной командой – сразу всю матрицу обрабатываем % расчет мощности ошибки
e_sq = e.*e; P_e = sum(sum(e_sq))/N; % отношение сигнал-шум
res = 10*log10(P_x/P_e); % присваиваем значение выходному параметру
%
function [out_linear] = UnrollMatrix(in_matrix, ind, ind_l)
% Разворачивание матрицы в вектор путем обхода в заданном порядке
% Входные параметры: % in_matrix - исходная матрица
% ind - массив индексов (NxN,2) % ind_l - массив индексов (NxN,1)- индексы представлены
% в виде смещений от начала массива (т. е. одним
% числом)
% Выходные параметры: % out_linear - вектор, содержащий элементы матрицы, %
% упорядоченные в соответствии таблицей индексов
%
n = size(in_matrix, 1); % взять размер полученной квадратной матрицы
out_linear = zeros(1, n*n); % заранее выделяем место под массив-вектор 1xN^2
%--
% Вариант 1 - с поэлементной обработкой
% в цикле формируем вектор, выбирая в него элементы матрицы
% в порядке, который определен таблице индексов ind
%for i=1:n*n % out_linear(i) = in_matrix(ind(i,1), ind(i,2)); %end
%--
% Вариант 2 - с векторной обработкой
% для чтения сразу нескольких элементов матрицы необходимо, чтобы
% индексы ее элементов были перечислены в необходимом порядке
% виде скалярных значений.
out_linear = in_matrix(ind_l);
function out_image = Zigzag2Scale(linear_coefs)
global Params % заранее выделить место под матрицу
out_image = zeros(Params. ImageSize(1),Params. ImageSize(2));
% сформировать последовательность индексов для обхода зигзагом
% формируются индексы и в матричной форме и в линейной (для самопроверки)
% после тестирования достаточно оставить только линейную форму
[zigzag_ind, zigzag_ind_l] = Generate_Zigzag(Params. BlockSize);
% проходим по всем блокам заданного размера
d = uint16(Params. BlockSize); % d – размер блока по каждой оси
t = d*d; % t – число элементов в блоке
p = 1; % храним в новом массиве
for m = 0:Params. NumBlocks(1)-1 % количество блоков по вертикали
for n = 0:Params. NumBlocks(2)-1 % количество блоков по горизонтали
out_image(m*d+[1:d], n*d+[1:d]) = RollMatrix(linear_coefs(p, :), ...
zigzag_ind, zigzag_ind_l);
p = p+1;
end
end
%--
Система MATLAB чувствительна к неправильным названиям объектов. Каждый объект имеет свой идентификатор (handle). Можно выделить две команды: set (устанавливает определенные свойства для объекта) и get(можно сохранить введенные значения). Подобно другим системам визуального программирования и проектирования MATLAB предоставляет возможность назначать имена (Tag) для каждого объекта и изменять его свойства. Это возможно в окне, называемом «инспектор свойств». Вызывается следующим образом: щелкните правой кнопкой мыши на объекте и выберите пункт Property Inspector.

Рис.8. Инспектор свойств
Особый интерес для нас представляют пункты String, Tag. Для слайдера можно в полях Max и Min задать максимальные и минимальные значения (от 0.0 до 100.0).
Для компонента popupmenu редактирование свойств происходит в пункте String:

Рис.10. Ввод значений для компонента popupmenu
Обработчик (call-back – возвращаемая процедура) пишется внутри объекта, и сделать это можно следующим образом:
Для компонента:

Рис.11. Пункт меню, позволяющий редактировать функции-обработчики объектов
В результате появится окно редактора. Писать обработчики можно и для самой формы (выполняющегося в результате щелчка мыши или другого заданного действия).

Рис.12.Типы обработчиков, которые можно назначить форме
У нас будет обработчик, который позволяет просмотреть результат преобразований, щелкнув кнопкой мыши на изображении. Поэтому очень внимательно необходимо обращаться с объектами – соблюдать однозначность в названиях на форме и в коде.
Приведем имена (Tag) объектов и их назначение.
1. Load_Image – кнопка выбора изображения
2. SrcImage – поле вывода исходного изображения
3. text2 – текстовое поле для вывода служебной информации
4. pushbutton5 – показать исходное изображение в отдельном окне
5. menu – меню выбора размера блока ДКП
6. radiobutton_CodeNonZero – кодирование введенного количества ДКП (радиокнопка)
7. Params_Code_NonZero1 – кодирование всех коэффициентов ДКП (радиокнопка)
8. edit_NumFirstDCTCoefs – сколько коэффициентов ДКП кодировать (поле ввода)
9. text_Quality – отображение качества кодирования (текстовое поле)
10. slider_Quality – слайдер, задающий качество квантования (min=0.0, max = 100.0)
11. ShowDCTCoefs – показать коэффициенты ДКП (в виде базисных функций)
12. ShowQuantCoefs – показать коэффициенты квантования
13. text_SNR – отображение соотношения сигнал/шум
14. RunCoding – выполнить кодирование изображения
15. axes_DstImage – вывод сжатого изображения
16. text_CodingProgress – сообщение о начале и завершении процесса кодирования
17. pushbutton6 – вывод изображения в отдельное окно
18. axes_DstBlock – область вывода, где можно просмотреть изображение блока коэффициентов ДКП исходного изображения
19. uitable_TableSrcBlock – таблица, в которой отображается массив коэффициентов ДКП
20. uitable_TableDstBlock – таблица, в которой отображается массив коэффициентов ДКП после обработки
21. axes_SrcBlock – вывод декодированного блока коэффициентов ДКП
Таким образом, на форме должны быть четыре группы компонентов:
· Выбор и просмотр исходного изображения
· Выбор параметров кодирования
· Кодирование изображения в соответствии с заданными параметрами
· Просмотр коэффициентов ДКП до и после обработки
Теперь приведем код главного модуля (важно не механически копировать коды, а продуманно задавать программы для каждого обработчика).
function varargout = JPEG_Analysis(varargin)
% JPEG_ANALYSIS M-file for JPEG_Analysis. fig
% JPEG_ANALYSIS, by itself, creates a new JPEG_ANALYSIS or raises the existing
% singleton*.
%
% H = JPEG_ANALYSIS returns the handle to a new JPEG_ANALYSIS or the handle to
% the existing singleton*.
%
% JPEG_ANALYSIS('CALLBACK',hObject, eventData, handles,...) calls the local
% function named CALLBACK in JPEG_ANALYSIS. M with the given input arguments.
%
% JPEG_ANALYSIS('Property','Value',...) creates a new JPEG_ANALYSIS or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before JPEG_Analysis_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to JPEG_Analysis_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help JPEG_Analysis
% Last Modified by GUIDE vNov-2010 13:42:40
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @JPEG_Analysis_OpeningFcn, ...
'gui_OutputFcn', @JPEG_Analysis_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State. gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before JPEG_Analysis is made visible.
function JPEG_Analysis_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to JPEG_Analysis (see VARARGIN)
% Choose default command line output for JPEG_Analysis
handles. output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes JPEG_Analysis wait for user response (see UIRESUME)
% uiwait(handles. figure1);
% --- Outputs from this function are returned to the command line.
function varargout = JPEG_Analysis_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles. output;
% --- Executes on button press in Load_Image.
function Load_Image_Callback(hObject, eventdata, handles)
% hObject handle to Load_Image (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global SrcImage
global Params
% Вызов стандартного диалогового окна для выбора файла.
% Назначаем фильтр "*.bmp".
% Возвращаемые параметры - имя файла и путь к файлу
[fname, pname] = uigetfile( {'*.bmp', 'bmp-файл'}, ...
'Выберите файл изображения'); % фильтр и его отображение
% заголовок диалога
if fname~=0 % если файл выбран
si = imread(fullfile(pname, fname));
% si = imread(fname,'BMP');
% загрузить из файла и преобразовать в double
% проверить, что изображение содержит только одну компоненту
if ndims(si)>2 % если цветное - то преобразовать в серое
SrcImage = double(rgb2gray(si));
else
SrcImage = double(si);
end % показать исходное изображение
axes(handles. SrcImage);
% активируем нужный элемент управления
imshow(SrcImage, [0 255]); % выводим в него изображение
end
% --- Executes on selection change in menu.
function menu_Callback(hObject, eventdata, handles)
% hObject handle to menu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = get(hObject,'String') returns menu contents as cell array
% contents{get(hObject,'Value')} returns selected item from menu
% --- Executes during object creation, after setting all properties.
function menu_CreateFcn(hObject, eventdata, handles)
% hObject handle to menu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: popupmenu controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in RunCoding.
function RunCoding_Callback(hObject, eventdata, handles)
% hObject handle to RunCoding (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params
global SrcImage
global DstImage
global DCT_Image
global DeScaleDCT_Image
Params. ImageSize = size(SrcImage);
% взять остальные параметры кодирования
read_params(hObject, eventdata, handles);
Если закомментировать этот блок, то будет выполняться кодирование любых изображений. Иначе происходит проверка на кратность размера изображения и кратность размера блока ДКП
if (any(rem(Params. ImageSize, Params. BlockSize)))
errordlg('Параметры заданы не верно','Ошибка в выборе параметров');
return
end
Params. NumBlocks = uint16(Params. ImageSize / Params. BlockSize);% количество блоков
% показать сообщение о начале кодирования
set(handles. text_CodingProgress, 'String', 'Выполняется кодирование...'); drawnow;
% принудительно вывести на экран
%----- КОДЕР -------
% выполнить кодирование
tic;
DCT_Image = Im2DCT(SrcImage); % прямое ДКП
Scale_Image = DCT2Scale(DCT_Image); % квантование коэффициентов ДКП
% выстроить коэффициенты в вектор
Linear_Coefs = Scale2Zigzag(Scale_Image); % обойти матрицу зигзагом
% обрезать коэффициенты (обнулить лишние)
[Cut_Coefs, NumC] = CutCoefs(Linear_Coefs);
DCT_Image = Im2DCT(SrcImage); % прямое ДКП
Scale_Image = DCT2Scale(DCT_Image); % квантование коэффициентов ДКП
% выстроить коэффициенты в вектор
Linear_Coefs = Scale2Zigzag(Scale_Image); % обойти матрицу зигзагом
toc;
%ДЕКОДЕР----
DeScale_Image = Zigzag2Scale(Cut_Coefs); % сворачивание матрицы из вектора коэффициентов
DeScaleDCT_Image = Scale2DCT(DeScale_Image); % деквантование коэффициентов ДКП
DstImage = DCT2Im(DeScaleDCT_Image); % обратное ДКП
%оценить качество кодирования (сигнал-шум)
Params. SN_ratio = SNR(SrcImage, DstImage);
set(handles. text_SNR, 'String', strcat('Отношение сигнал/шум (дБ) = ', ...
num2str(Params. SN_ratio)));
% показать восстановленное изображение
axes(handles. axes_DstImage); % активируем нужный элемент управления
imshow(DstImage, [0 255]); % выводим в него изображение
set(handles. text_CodingProgress, 'String', 'Кодирование завершено');
msgbox('Процесс завершен');
% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global SrcImage;
figure;
imshow(SrcImage, [0 255]);
% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton6 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DstImage
figure; % новое окно
imshow(DstImage, [0 255]); % принудительно установить диапазон амплитуд для double
% --- Executes on slider movement.
function slider_Quality_Callback(hObject, eventdata, handles)
% hObject handle to slider_Quality (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
st = round(get(hObject,'Value'));
set(handles. text_Quality,'String',num2str(100-st+1));
% --- Executes during object creation, after setting all properties.
function slider_Quality_CreateFcn(hObject, eventdata, handles)
% hObject handle to slider_Quality (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor',[.9 .9 .9]);
end
% --- Executes on button press in ShowDCTCoefs.
function ShowDCTCoefs_Callback(hObject, eventdata, handles)
% hObject handle to ShowDCTCoefs (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params
% для наглядности вводим коэффициент
%"растяжения" поверхности
% (масштабирования по горизонтали)
resolution = 10; % считать с формы параметры кодирования
read_params(hObject, eventdata, handles);
figure; % открываем новое окно
N = Params. BlockSize;
for k = 1:N
for l = 1:N subplot( N, N,(k-1)*N+l );
% выбираем часть окна для вывода графика
% формируем матрицу для получения формы базисной функции
in = zeros(N*resolution);
in(k, l) = 1; % "тестовый сигнал" для оценки отклика % выполнить прямое ДКП
out = dct2(in);
mesh(out); % вывести в заданной части окна
axis off; % отключить вывод числовых осей на графике
end
end
% --- Executes on button press in ShowQuantCoefs.
function ShowQuantCoefs_Callback(hObject, eventdata, handles)
% hObject handle to ShowQuantCoefs (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params % считать с формы параметры кодирования
read_params(hObject, eventdata, handles); % рассчитать и показать коэффициенты квантования на отдельной форме
figure;
bar3(Generate_Scales(Params. BlockSize, Params. Quality));
% --- Executes on button press in radiobutton_CodeNonZero.
function radiobutton_CodeNonZero_Callback(hObject, eventdata, handles)
% hObject handle to radiobutton_CodeNonZero (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of radiobutton_CodeNonZero
function edit_NumFirstDCTCoefs_Callback(hObject, eventdata, handles)
% hObject handle to edit_NumFirstDCTCoefs (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit_NumFirstDCTCoefs as text
% str2double(get(hObject,'String')) returns contents of edit_NumFirstDCTCoefs as a double
% --- Executes during object creation, after setting all properties.
function edit_NumFirstDCTCoefs_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit_NumFirstDCTCoefs (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in Params_Code_NonZero1.
function Params_Code_NonZero1_Callback(hObject, eventdata, handles)
% hObject handle to Params_Code_NonZero1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of Params_Code_NonZero1
% p = get(hObject,'Value');
global Params
read_params(hObject, eventdata, handles);
set(handles. edit_NumFirstDCTCoefs, 'String',Params. BlockSize*Params. BlockSize);
% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonDownFcn(hObject, eventdata, handles)
% hObject handle to figure1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params
global SrcImage
global DstImage
global DCT_Image
global DeScaleDCT_Image
% определяем попадание координат в область исходного изображения
pt = get(handles. SrcImage, 'currentpoint');
cp(1,1) = pt(1, 2);
cp(1,2) = pt(1, 1); % по смещению от начала области изображения определяем номер блока
num_block = floor(cp./ Params. BlockSize);
% показать исходный блок
SrcBlockImage = SrcImage(num_block(1)*(Params. BlockSize) + [1:Params. BlockSize], ...
num_block(2)*(Params. BlockSize) + [1:Params. BlockSize]);
axes(handles. axes_SrcBlock);
% активируем нужный элемент управления
imshow(SrcBlockImage, [0 255]);
% выводим в него изображение
% показать восстановленный блок
DstBlockImage = DstImage(num_block(1)*(Params. BlockSize) + [1:Params. BlockSize], ...
num_block(2)*(Params. BlockSize) + [1:Params. BlockSize]);
axes(handles. axes_DstBlock);
% активируем нужный элемент управления
imshow(DstBlockImage, [0 255]); % выводим в него изображение
% показать таблицу исходных коэффициентов ДКП
d = uint16(Params. BlockSize);
% % количество элементов в стороне блока
hdr_c = cell(1, Params. BlockSize);
% место под заголовки столбцов
width_c = cell(1, Params. BlockSize);
% место под ширины столбцов
hdr_r = cell(Params. BlockSize, 1); % место под заголовки строк
for i=1:Params. BlockSize
hdr_c{1, i} = num2str(i); % заголовки – просто номера строк и столбцов
width_c{1, i} = 'auto'; % ширина – "автоподбор"
hdr_r{i, 1} = num2str(i);
end
set(handles. uitable_TableSrcBlock, 'ColumnName', hdr_c);
set(handles. uitable_TableSrcBlock, 'ColumnWidth', width_c);
set(handles. uitable_TableSrcBlock, 'RowName', hdr_r);
set(handles. uitable_TableSrcBlock, 'Data',DCT_Image(num_block(1)*d+[1:d], ...
num_block(2)*d+[1:d]));
%после преобразования
set(handles. uitable_TableDstBlock, 'ColumnName', hdr_c);
set(handles. uitable_TableDstBlock, 'ColumnWidth', width_c);
set(handles. uitable_TableDstBlock, 'RowName', hdr_r);
set(handles. uitable_TableDstBlock, 'Data', DeScaleDCT_Image(num_block(1)*d+[1:d], ...
num_block(2)*d+[1:d]));
В заключение приведем коды обработчиков для основных элементов управления:

1)
function Load_Image_Callback(hObject, eventdata, handles)
% hObject handle to Load_Image (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global SrcImage
global Params
% Вызов стандартного диалогового окна для выбора файла.
% Назначаем фильтр "*.bmp".
% Возвращаемые параметры - имя файла и путь к файлу
[fname, pname] = uigetfile( {'*.bmp', 'bmp-файл'}, ...
'Выберите файл изображения'); % фильтр и его отображение
% заголовок диалога
if fname~=0 % если файл выбран
si = imread(fullfile(pname, fname));
% si = imread(fname,'BMP');
% загрузить из файла и преобразовать в double
% проверить, что изображение содержит только одну компоненту
if ndims(si)>2 % если цветное - то преобразовать в серое
SrcImage = double(rgb2gray(si));
else
SrcImage = double(si);
end % показать исходное изображение
axes(handles. SrcImage);
% активируем нужный элемент управления
imshow(SrcImage, [0 255]); % выводим в него изображение
end
![]()
2)
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global SrcImage;
figure;
imshow(SrcImage, [0 255]);

3)
function RunCoding_Callback(hObject, eventdata, handles)
% hObject handle to RunCoding (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params
global SrcImage
global DstImage
global DCT_Image
global DeScaleDCT_Image
Params. ImageSize = size(SrcImage);
% взять остальные параметры кодирования
read_params(hObject, eventdata, handles);
if (any(rem(Params. ImageSize, Params. BlockSize)))
errordlg('Параметры заданы не верно','Ошибка в выборе параметров');
return
end
Params. NumBlocks = uint16(Params. ImageSize / Params. BlockSize);% количество блоков
% показать сообщение о начале кодирования
set(handles. text_CodingProgress, 'String', 'Выполняется кодирование...'); drawnow;
% принудительно вывести на экран
%----- КОДЕР -------
% выполнить кодирование
tic;
DCT_Image = Im2DCT(SrcImage); % прямое ДКП
Scale_Image = DCT2Scale(DCT_Image); % квантование коэффициентов ДКП
% выстроить коэффициенты в вектор
Linear_Coefs = Scale2Zigzag(Scale_Image); % обойти матрицу зигзагом
% обрезать коэффициенты (обнулить лишние)
[Cut_Coefs, NumC] = CutCoefs(Linear_Coefs);
DCT_Image = Im2DCT(SrcImage); % прямое ДКП
Scale_Image = DCT2Scale(DCT_Image); % квантование коэффициентов ДКП
% выстроить коэффициенты в вектор
Linear_Coefs = Scale2Zigzag(Scale_Image); % обойти матрицу зигзагом
toc;
%ДЕКОДЕР----
DeScale_Image = Zigzag2Scale(Cut_Coefs); % сворачивание матрицы из вектора коэффициентов
DeScaleDCT_Image = Scale2DCT(DeScale_Image); % деквантование коэффициентов ДКП
DstImage = DCT2Im(DeScaleDCT_Image); % обратное ДКП
%оценить качество кодирования (сигнал-шум)
Params. SN_ratio = SNR(SrcImage, DstImage);
set(handles. text_SNR, 'String', strcat('Отношение сигнал/шум (дБ) = ', ...
num2str(Params. SN_ratio)));
% показать восстановленное изображение
axes(handles. axes_DstImage); % активируем нужный элемент управления
imshow(DstImage, [0 255]); % выводим в него изображение
set(handles. text_CodingProgress, 'String', 'Кодирование завершено');
msgbox('Процесс завершен');
4) ![]()
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton6 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global DstImage
figure; % новое окно
imshow(DstImage, [0 255]); % принудительно установить диапазон амплитуд для double
5) ![]()
function ShowDCTCoefs_Callback(hObject, eventdata, handles)
% hObject handle to ShowDCTCoefs (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params
% для наглядности вводим коэффициент
%"растяжения" поверхности
% (масштабирования по горизонтали)
resolution = 10; % считать с формы параметры кодирования
read_params(hObject, eventdata, handles);
figure; % открываем новое окно
N = Params. BlockSize;
for k = 1:N
for l = 1:N subplot( N, N,(k-1)*N+l );
% выбираем часть окна для вывода графика
% формируем матрицу для получения формы базисной функции
in = zeros(N*resolution);
in(k, l) = 1; % "тестовый сигнал" для оценки отклика % выполнить прямое ДКП
out = dct2(in);
mesh(out); % вывести в заданной части окна
axis off; % отключить вывод числовых осей на графике
end
end
6) 
function ShowQuantCoefs_Callback(hObject, eventdata, handles)
% hObject handle to ShowQuantCoefs (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params % считать с формы параметры кодирования
read_params(hObject, eventdata, handles); % рассчитать и показать коэффициенты квантования на отдельной форме
figure;
bar3(Generate_Scales(Params. BlockSize, Params. Quality))
7) 
function slider_Quality_Callback(hObject, eventdata, handles)
% hObject handle to slider_Quality (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
st = round(get(hObject,'Value'));
set(handles. text_Quality,'String',num2str(100-st+1));
![]()
8)
function Params_Code_NonZero1_Callback(hObject, eventdata, handles)
% hObject handle to Params_Code_NonZero1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: get(hObject,'Value') returns toggle state of Params_Code_NonZero1
% p = get(hObject,'Value');
global Params
read_params(hObject, eventdata, handles);
set(handles. edit_NumFirstDCTCoefs, 'String',Params. BlockSize*Params. BlockSize);
9) Обработчик, выполняющийся при нажатии кнопки мыши на изображение, расположенное на форме (для вывода блоков исходных и преобразованных коэффициентов ДКП)
function figure1_WindowButtonDownFcn(hObject, eventdata, handles)
% hObject handle to figure1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global Params
global SrcImage
global DstImage
global DCT_Image
global DeScaleDCT_Image
% определяем попадание координат в область исходного изображения
pt = get(handles. SrcImage, 'currentpoint');
cp(1,1) = pt(1, 2);
cp(1,2) = pt(1, 1); % по смещению от начала области изображения определяем номер блока
num_block = floor(cp./ Params. BlockSize);
% показать исходный блок
SrcBlockImage = SrcImage(num_block(1)*(Params. BlockSize) + [1:Params. BlockSize], ...
num_block(2)*(Params. BlockSize) + [1:Params. BlockSize]);
axes(handles. axes_SrcBlock);
% активируем нужный элемент управления
imshow(SrcBlockImage, [0 255]);
% выводим в него изображение
% показать восстановленный блок
DstBlockImage = DstImage(num_block(1)*(Params. BlockSize) + [1:Params. BlockSize], ...
num_block(2)*(Params. BlockSize) + [1:Params. BlockSize]);
axes(handles. axes_DstBlock);
% активируем нужный элемент управления
imshow(DstBlockImage, [0 255]); % выводим в него изображение
% показать таблицу исходных коэффициентов ДКП
d = uint16(Params. BlockSize);
% % количество элементов в стороне блока
hdr_c = cell(1, Params. BlockSize);
% место под заголовки столбцов
width_c = cell(1, Params. BlockSize);
% место под ширины столбцов
hdr_r = cell(Params. BlockSize, 1); % место под заголовки строк
for i=1:Params. BlockSize
hdr_c{1, i} = num2str(i); % заголовки – просто номера строк и столбцов
width_c{1, i} = 'auto'; % ширина – "автоподбор"
hdr_r{i, 1} = num2str(i);
end
set(handles. uitable_TableSrcBlock, 'ColumnName', hdr_c);
set(handles. uitable_TableSrcBlock, 'ColumnWidth', width_c);
set(handles. uitable_TableSrcBlock, 'RowName', hdr_r);
set(handles. uitable_TableSrcBlock, 'Data',DCT_Image(num_block(1)*d+[1:d], ...
num_block(2)*d+[1:d]));
%после преобразования
set(handles. uitable_TableDstBlock, 'ColumnName', hdr_c);
set(handles. uitable_TableDstBlock, 'ColumnWidth', width_c);
set(handles. uitable_TableDstBlock, 'RowName', hdr_r);
set(handles. uitable_TableDstBlock, 'Data', DeScaleDCT_Image(num_block(1)*d+[1:d], ...
num_block(2)*d+[1:d]));
Таким образом, при правильном написании кодов программы, при выполнении условий корректного расположения элементов формы и учета всех параметров, мы получим следующий результат:

Рис.13. Результат выполнения кодирования изображения
В командном окне появится сообщение, выдающее информацию о времени кодирования сообщения:
Elapsed time is 7.604185 seconds.
Если параметры установлены правильно, то выполнится кодирование изображения и появится сообщение о завершении процесса. Иначе появится сообщение об ошибке и обработка изображения не произойдет.
Можно осуществлять моделирование, задавая коэффициенты квантования и количество кодируемых коэффициентов ДКП. Проведите эксперименты:
1) Над разными изображениями с одинаковыми параметрами
2) Над одним и тем же изображением с разными параметрами (в том числе и разным числом блоков ДКП).
3) Оцените соотношение сигнал/шум и время компрессии.


