Matlab - 使用四个像素的平均值缩小图像
Matlab - Scale down an image using an average of four pixels
我刚开始学习图像处理和 Matlab,我正在尝试使用平均 4 个像素来缩小图像。这意味着对于每 4 个原始像素,我计算平均值并生成 1 个输出像素。
到目前为止,我有以下代码:
img = imread('bird.jpg');
row_size = size(img, 1);
col_size = size(img, 2);
res = zeros(floor(row_size/2), floor(col_size/2));
figure, imshow(img);
for i = 1:2:row_size
for j = 1:2:col_size
num = mean([img(i, j), img(i, j+1), img(i+1, j), img(i+1, j+1)]);
res(round(i/2), round(j/2)) = num;
end
end
figure, imshow(uint8(res));
此代码设法缩小了图像,但将其转换为灰度。
我知道我可能必须计算输出像素的 RGB 分量的平均值,但我不知道如何访问它们、计算平均值并将它们插入结果矩阵。
您可以使用以下修改后的代码来解决这个问题:
img = imread('bird.jpg');
row_size = size(img, 1);
col_size = size(img, 2);
figure, imshow(img);
res = zeros(floor(row_size/2), floor(col_size/2), 3); %Pre-allocation
for p = 1:2:row_size
for q = 1:2:col_size
num = mean([img(p, q,:), img(p, q+1,:), img(p+1, q,:), img(p+1, q+1,:)]);
res(round(p/2), round(q/2),:) = num;
end
end
figure, imshow(uint8(res));
我拍了一张 1200x1600x3 uint8
的示例图像,上面的代码将其转换为 600x800x3 uint8
这是正确的,因为 (1200*1600)/4 = 480000
和 600*800 = 480000
P.S : 我将变量名 i
和 j
分别更改为 p
和 q
因为 i
和 j
是为 imaginary numbers
保留的。
在 Matlab 中,RGB 图像被视为 3D 数组。您可以通过以下方式查看:
depth_size = size(img, 3)
depth_size =
3
如您所做的那样,循环解决方案在 中进行了说明。但是,在 Matlab 中,建议您在想要提高速度时避免循环。
这是一个将 RGB 图像缩小 n
:
的矢量化解决方案
img = imread('bird.jpg');
n = 2; % n can only be integer
[row_size, col_size] = size(img(:, :, 1));
% getting rid of extra rows and columns that won't be counted in averaging:
I = img(1:n*floor(row_size / n), 1:n*floor(col_size / n), :);
[r, ~] = size(I(:, :, 1));
% separating and re-ordering the three colors of image in a way ...
% that averaging could be done with a single 'mean' command:
R = reshape(permute(reshape(I(:, :, 1), r, n, []), [2, 1, 3]), n*n, [], 1);
G = reshape(permute(reshape(I(:, :, 2), r, n, []), [2, 1, 3]), n*n, [], 1);
B = reshape(permute(reshape(I(:, :, 3), r, n, []), [2, 1, 3]), n*n, [], 1);
% averaging and reshaping the colors back to the image form:
R_avg = reshape(mean(R), r / n, []);
G_avg = reshape(mean(G), r / n, []);
B_avg = reshape(mean(B), r / n, []);
% concatenating the three colors together:
scaled_img = cat(3, R_avg, G_avg, B_avg);
% casting the result to the class of original image
scaled_img = cast(scaled_img, 'like', img);
基准测试:
如果你想知道为什么矢量化解决方案更受欢迎,看看用两种方法处理 RGB 768 x 1024 图像需要多长时间:
------------------- With vectorized solution:
Elapsed time is 0.024690 seconds.
------------------- With nested loop solution:
Elapsed time is 6.127933 seconds.
所以两个解的速度相差超过2个数量级
另一种可能的解决方案是使用 blockproc
中提到的函数 this link。这也将避免 for 循环。
我刚开始学习图像处理和 Matlab,我正在尝试使用平均 4 个像素来缩小图像。这意味着对于每 4 个原始像素,我计算平均值并生成 1 个输出像素。 到目前为止,我有以下代码:
img = imread('bird.jpg');
row_size = size(img, 1);
col_size = size(img, 2);
res = zeros(floor(row_size/2), floor(col_size/2));
figure, imshow(img);
for i = 1:2:row_size
for j = 1:2:col_size
num = mean([img(i, j), img(i, j+1), img(i+1, j), img(i+1, j+1)]);
res(round(i/2), round(j/2)) = num;
end
end
figure, imshow(uint8(res));
此代码设法缩小了图像,但将其转换为灰度。 我知道我可能必须计算输出像素的 RGB 分量的平均值,但我不知道如何访问它们、计算平均值并将它们插入结果矩阵。
您可以使用以下修改后的代码来解决这个问题:
img = imread('bird.jpg');
row_size = size(img, 1);
col_size = size(img, 2);
figure, imshow(img);
res = zeros(floor(row_size/2), floor(col_size/2), 3); %Pre-allocation
for p = 1:2:row_size
for q = 1:2:col_size
num = mean([img(p, q,:), img(p, q+1,:), img(p+1, q,:), img(p+1, q+1,:)]);
res(round(p/2), round(q/2),:) = num;
end
end
figure, imshow(uint8(res));
我拍了一张 1200x1600x3 uint8
的示例图像,上面的代码将其转换为 600x800x3 uint8
这是正确的,因为 (1200*1600)/4 = 480000
和 600*800 = 480000
P.S : 我将变量名 i
和 j
分别更改为 p
和 q
因为 i
和 j
是为 imaginary numbers
保留的。
在 Matlab 中,RGB 图像被视为 3D 数组。您可以通过以下方式查看:
depth_size = size(img, 3)
depth_size =
3
如您所做的那样,循环解决方案在
这是一个将 RGB 图像缩小 n
:
img = imread('bird.jpg');
n = 2; % n can only be integer
[row_size, col_size] = size(img(:, :, 1));
% getting rid of extra rows and columns that won't be counted in averaging:
I = img(1:n*floor(row_size / n), 1:n*floor(col_size / n), :);
[r, ~] = size(I(:, :, 1));
% separating and re-ordering the three colors of image in a way ...
% that averaging could be done with a single 'mean' command:
R = reshape(permute(reshape(I(:, :, 1), r, n, []), [2, 1, 3]), n*n, [], 1);
G = reshape(permute(reshape(I(:, :, 2), r, n, []), [2, 1, 3]), n*n, [], 1);
B = reshape(permute(reshape(I(:, :, 3), r, n, []), [2, 1, 3]), n*n, [], 1);
% averaging and reshaping the colors back to the image form:
R_avg = reshape(mean(R), r / n, []);
G_avg = reshape(mean(G), r / n, []);
B_avg = reshape(mean(B), r / n, []);
% concatenating the three colors together:
scaled_img = cat(3, R_avg, G_avg, B_avg);
% casting the result to the class of original image
scaled_img = cast(scaled_img, 'like', img);
基准测试:
如果你想知道为什么矢量化解决方案更受欢迎,看看用两种方法处理 RGB 768 x 1024 图像需要多长时间:
------------------- With vectorized solution:
Elapsed time is 0.024690 seconds.
------------------- With nested loop solution:
Elapsed time is 6.127933 seconds.
所以两个解的速度相差超过2个数量级
另一种可能的解决方案是使用 blockproc
中提到的函数 this link。这也将避免 for 循环。