解码 jpeg 时如何在 matlab 中反转色度下采样?
When decoding a jpeg how would I reverse chrominance downsampling in matlab?
你好,我正在尝试制作一个简单的 jpeg 压缩器,它也可以解压缩图像。我使用以下代码对 jpeg 压缩的第一步图像的色度进行下采样。
resampler = vision.ChromaResampler;
[Cb, Cr] = resampler(Cb_channel, Cr_channel);
该函数是 matlab 计算机视觉工具箱的一部分。
例如在下采样之前:
Y 维度 = 3024 x 4032;
Cb 和 Cr 尺寸 = 3024 x 4032
下采样后:
Y 维度 = 3024 x 4032;
到 2016 年,Cb 和 Cr 尺寸 = 3024
为了显示解压缩后的原始 RGB 图像,所有 3 个 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时,上述方法是否是反转下采样色度的正确方法?
使用 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 位移没有很好的记录 - 我不得不建立一个简短的测试来弄清楚它。
据我所知,MPEG-1 编解码器使用移动 0.5 个像素的约定,但 MPEG-2 和更新的编解码器不使用。
我不认为它被 JPEG 使用,但我不确定...
注:
由于人类视觉系统对色度分辨率不是很敏感,所以无论是否使用 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默认的插值方式是线性插值。
三次插值被认为是优越的,但通常使用线性插值(可见差异可以忽略不计)。
你好,我正在尝试制作一个简单的 jpeg 压缩器,它也可以解压缩图像。我使用以下代码对 jpeg 压缩的第一步图像的色度进行下采样。
resampler = vision.ChromaResampler;
[Cb, Cr] = resampler(Cb_channel, Cr_channel);
该函数是 matlab 计算机视觉工具箱的一部分。
例如在下采样之前:
Y 维度 = 3024 x 4032; Cb 和 Cr 尺寸 = 3024 x 4032
下采样后:
Y 维度 = 3024 x 4032; 到 2016 年,Cb 和 Cr 尺寸 = 3024
为了显示解压缩后的原始 RGB 图像,所有 3 个 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时,上述方法是否是反转下采样色度的正确方法?
使用 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 位移没有很好的记录 - 我不得不建立一个简短的测试来弄清楚它。
据我所知,MPEG-1 编解码器使用移动 0.5 个像素的约定,但 MPEG-2 和更新的编解码器不使用。
我不认为它被 JPEG 使用,但我不确定...
注:
由于人类视觉系统对色度分辨率不是很敏感,所以无论是否使用 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默认的插值方式是线性插值。
三次插值被认为是优越的,但通常使用线性插值(可见差异可以忽略不计)。