在 MATLAB 中减少灰度图像的强度级别数

信息处理 图像处理 matlab 离散化
2022-02-08 17:09:57

我编写了一个 Matlab 脚本,将灰度图像的每个像素的强度级别数量从 256 减少到 2 的某个幂。

img_color = imread('photo.jpg');
img_gray = rgb2gray(img_color);
imshow(img_gray);
[rows, cols] = size(img_gray);
noOfDesiredIntensityLevels = 2; // test data. will check for 4,8,16,32,etc.
bitsNeededToRepresentIntensityLevels = log2(noOfDesiredIntensityLevels);
new_img = img_gray;
for i = 1 : rows
    for j = 1 : cols
        new_img(i,j) = floor(img_gray(i,j)/(2^(8-bitsNeededToRepresentIntensityLevels)));
    end
end
figure
imshow(new_img);

执行时,脚本返回黑色图像。我的期望是图像将变成黑白(每个像素的强度值将是 0 或 1)。

我在这里想念什么?

PS:我是 Matlab 和图像处理的新手。所以,请忽略我理解中的任何错误。

3个回答

我认为通过级别数,您希望将图像全尺寸灰度分段分成给定数量的级别。例如: -

  • 如果级别数 = 2,那么您只需要图像中的两个灰度,即(0 和 128)或(128 和 255),具体取决于您在范围内使用的是 floor 还是 ceil
  • 如果级别数 = 4,那么您需要图像中有 4 个不同级别,即(0、64、124、192)

解决方案 - 此操作可以在一行中完成

new_img = ceil(img_gray./step)*step;

在这里,我将整个范围划分为所需数量的部分(级别),大小为步长,并使用 ceil 函数将结果限制在上限(您可以使用 floor 作为下限)

完整代码 -

img_color = imread('peppers.png');
img_gray = rgb2gray(img_color);
imshow(img_gray);

[rows, cols] = size(img_gray);
noOfDesiredIntensityLevels = 2;
step = ceil(255/(noOfDesiredIntensityLevels - 1));

new_img = ceil(img_gray./step)*step;

figure
imshow(new_img);


% optional code to show the levels
allSteps = 0;
currStep = 0;
while(currStep < 255)
    currStep = currStep + step;
    allSteps = [allSteps currStep];
end

allSteps

编辑 1 - 我添加了几行额外的行,向您展示了数组中的不同级别(步骤)。它只是可选的,但很高兴知道级别的确切值。

这是一种方法

img_color = imread('peppers.png');
img_gray = rgb2gray(img_color);
figure(1); imshow(img_gray);

nLevels = 4; % change this to the desired level 2 or more
maxLevel = 256;
threshGap = maxLevel / nLevels;
thresholds = zeros(1, nLevels);
thresholds(nLevels) = maxLevel-1;
thresholds(1) = floor(threshGap);
for i = 2:nLevels-1
    thresholds(i) = floor(thresholds(i-1) + threshGap);
end

grayGap = maxLevel / (nLevels - 1);
grayLevels = zeros(1, nLevels);
grayLevels(nLevels) = maxLevel - 1;
for i = 2:nLevels-1
    grayLevels(i) = floor(grayLevels(i-1) + grayGap);
end

new_img = img_gray;
[rows, cols] = size(img_gray);


for i = nLevels:-1:1
    %new_img(img_gray < thresholds(i)) = grayLevels(i); % you can use this line of
    % code and remove the next double nested loops

    for x=1:rows
        for y =1:cols
            if img_gray(x, y) < thresholds(i)
                new_img(x, y) = grayLevels(i);
            end
        end
    end
end

figure(2); imshow(new_img);

这是具有 4 个灰度级的结果: 结果

注意:代码非常简单,但如果您不理解某些内容,请发表评论。

使用 Matlab,您不需要循环其他所有像素。基于矩阵(因此称为“MatLab”),您可以直接分割整个图像。然后,imshow在不是 8 位的图像上可能会很棘手。而是imagesc可以缩放图像。

二值化图像

clear all;
noOfDesiredIntensityLevels = 2; 
bitsIntialToRepresentIntensityLevels = 8; 

img_color = (imread('peppers.png'));
img_gray = double(rgb2gray(img_color));

bitsNeededToRepresentIntensityLevels = log2(noOfDesiredIntensityLevels);
if ~isequal(bitsNeededToRepresentIntensityLevels,floor(bitsNeededToRepresentIntensityLevels))
    error('Number of intensity levels is not a power of two')
end
new_img = floor(img_gray/(2^(bitsIntialToRepresentIntensityLevels-bitsNeededToRepresentIntensityLevels)));

figure(1)
subplot(1,2,1)
imagesc(img_gray);
subplot(1,2,2)
imagesc((2^(bitsIntialToRepresentIntensityLevels-bitsNeededToRepresentIntensityLevels))*new_img);