При декодировании jpeg, как мне отменить понижение частоты дискретизации цветности в Matlab?

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

resampler = vision.ChromaResampler;
[Cb, Cr] = resampler(Cb_channel, Cr_channel);

эта функция является частью набора инструментов компьютерного зрения для Matlab.

например перед понижением частоты дискретизации:

Размеры Y = 3024 на 4032; Размеры Cb и Cr = 3024 на 4032

после понижения дискретизации:

Размеры Y = 3024 на 4032; Размеры Cb и Cr = 3024 к 2016 г.

чтобы отобразить исходное изображение RGB после распаковки, размеры всех трех компонентов Y, Cb и Cr должны быть одинаковыми, чтобы я мог объединить каналы и преобразовать изображение обратно в RGB. Я использую следующий код для достижения этой цели:

Cb_resized = imresize(Cb, [(size(Cb, 1)) (2*size(Cb, 2))]);
Cr_resized = imresize(Cr, [(size(Cr, 1)) (2*size(Cr, 2))]);

Когда я затем объединяю 3 канала и использую imshow(), чтобы увидеть изображение, оно выглядит нормально. Так является ли вышеописанный метод правильным способом обращения цветности с пониженной частотой дискретизации при декодировании jpeg?


person Community    schedule 27.04.2021    source источник


Ответы (1)


Использование imresize для повышения частоты дискретизации почти правильно.

Вместо использования imresize вам лучше использовать vision.ChromaResampler для повышения частоты дискретизации:

up_resampler = vision.ChromaResampler();
up_resampler.Resampling = '4:2:2 to 4:4:4';

[Cb_resized, Cr_resized] = up_resampler(Cb, Cr);

Модуль разработан таким образом, что Resampling = '4:2:2 to 4:4:4' обращает результат Resampling = '4:4:4 to 4:2:2'.


'4:4:4 to 4:2:2' ChromaResampler использует соглашение, которое смещает результат на 0,5 пикселя вправо.
(Я думаю, что сдвиг на 0,5 пикселя предполагает соответствие стандарту кодека MPEG-1).

Смещение 0,5 не очень хорошо задокументировано - мне пришлось построить короткий тест, чтобы выяснить это.

Насколько я помню, соглашение о перемещении на 0,5 пикселя используется кодеком MPEG-1, но не используется MPEG-2 и более новыми кодеками.
Я не думаю, что оно используется JPEG, но я не уверена...

Примечание.
Поскольку зрительная система человека не очень чувствительна к разрешению Chroma, вы, вероятно, не увидите различий, если используется смещение 0,5 или нет.


Для получения того же результата, что и ChromaResampler, вы можете использовать imwarp с смещение на 1 пиксель по горизонтальной оси.

Понять imwarp немного сложно.
Я собираюсь использовать imwarp для демонстрации того, что смещение в 1 пиксель дает тот же результат, что и ChromaResampler:

В следующем примере кода показана эквивалентность:

close all

I = imread('peppers.png'); % Read sample image
YUV = rgb2ycbcr(I); % Convert RGB to Y:Cb:Cr
U = YUV(:, :, 2); % Get U color channel
V = YUV(:, :, 3); % Get V color channel

down_resampler = vision.ChromaResampler(); % 4:4:4 to 4:2:2
down_resampler.Resampling = '4:4:4 to 4:2:2';

up_resampler = vision.ChromaResampler(); % 4:2:2 to 4:4:4
up_resampler.Resampling = '4:2:2 to 4:4:4';

% Down-sample U and V using ChromaResampler
[downU, downV] = down_resampler(U, V);

%downU2 = imresize(U, [size(U, 1), size(U, 2)/2]); % Not the same as using imresize
%figure;imshow(downU);figure;imshow(downU2);

% Up-sample downU and downV using ChromaResampler
[upU, upV] = up_resampler(downU, downV);

% Result is not the same as using imresize
%resizedU = imresize(downU, [size(downU, 1), size(downU, 2)*2], 'bilinear');
%resizedV = imresize(downV, [size(downV, 1), size(downV, 2)*2], 'bilinear');

% Use transformation matrix that resize horizontally by x2 and include single pixel horizontal displacement.
tform = affine2d([ 2   0   0
                   0   1   0
                  -1   0   1]);

% Use imwarp instead of imresize (the warp includes horizontal displacement of 1 pixel)
warpU = imwarp(downU, tform, 'bilinear', 'OutputView', imref2d([size(downU, 1), size(downU, 2)*2]));
warpU(:, end) = warpU(:, end-1); % Fill the last column by duplication

%figure;imagesc(double(upU) - double(resizedU));impixelinfo
%figure;imshow(upU);figure;imshow(resizedU);
%figure;imshow(upU);figure;imshow(warpU);

% Show the differences:
figure;imagesc(double(upU) - double(warpU));title('Diff');impixelinfo
max_abs_diff = max(imabsdiff(warpU(:), upU(:)));
disp(['max_abs_diff = ', num2str(max_abs_diff)]); % Maximum absolute differenced is 1 (due to rounding).

Примечание. Использование imresize сохраняется в комментариях.


Примечание.
Метод интерполяции по умолчанию для imresize — это кубическая интерполяция, а метод интерполяции по умолчанию для ChromaResampler — линейная интерполяция.
Кубическая интерполяция считается лучшей, но обычно используется линейная интерполяция (видимая разница незначительна). .

person Rotem    schedule 27.04.2021
comment
Спасибо, очень обширный ответ с 2 решениями. Я полностью упустил из виду тот факт, что vision.ChromaResampler предназначен не только для понижения частоты дискретизации. - person ; 28.04.2021