如何计算没有 NaN 的图像中 3D 矩阵的平均值?

How to calculate the mean of 3D matrices in an image without NaN?

我需要计算 3D 矩阵的平均值(代码中的最后一步)。但是,(diff_dataframe./dataframe_vor)计算中有很多NaN。所以当我使用这段代码时,一些结果将是 NaN。我如何通过忽略 NaN 来计算该矩阵的平均值?我附上代码如下。

S.amplitude = 1:20;%:20;
S.blocksize = [1 2 3 4 5 6 8 10 12 15 20];
S.frameWidth = 1920;
S.frameHeight = 1080;
S.quality=0:10:100;
image = 127*ones(S.frameHeight,S.frameWidth,3);
S.yuv2rgb = [1 0 1.28033; 1 -0.21482 -0.38059; 1 2.12798 0];
i_bs = 0;
for BS = S.blocksize
i_bs = i_bs + 1;

hblocks = S.frameWidth / BS;
vblocks = S.frameHeight / BS;
i_a = 0;
dataU = randi([0 1],vblocks,hblocks);
dataV = randi([0 1],vblocks,hblocks);
dataframe_yuv = zeros(S.frameHeight, S.frameWidth, 3);
for x = 1 : hblocks
    for y = 1 : vblocks
        dataframe_yuv((y-1)*BS+1:y*BS, ...
            (x-1)*BS+1:x*BS, 2) = dataU(y,x) * 2 - 1;
        dataframe_yuv((y-1)*BS+1:y*BS, ...
            (x-1)*BS+1:x*BS, 3) = dataV(y,x) * 2 - 1;
    end
end

dataframe_rgb(:,:,1) = S.yuv2rgb(1,1) * dataframe_yuv(:,:,1) + ...
    S.yuv2rgb(1,2) * dataframe_yuv(:,:,2) + ...
    S.yuv2rgb(1,3) * dataframe_yuv(:,:,3);
dataframe_rgb(:,:,2) = S.yuv2rgb(2,1) * dataframe_yuv(:,:,1) + ...
    S.yuv2rgb(2,2) * dataframe_yuv(:,:,2) + ...
    S.yuv2rgb(2,3) * dataframe_yuv(:,:,3);
dataframe_rgb(:,:,3) = S.yuv2rgb(3,1) * dataframe_yuv(:,:,1) + ...
    S.yuv2rgb(3,2) * dataframe_yuv(:,:,2) + ...
    S.yuv2rgb(3,3) * dataframe_yuv(:,:,3);
for A = S.amplitude
    i_a = i_a + 1;
    i_q = 0;
image1p = round(image + dataframe_rgb * A);
image1n = round(image - dataframe_rgb * A);
dataframe_vor = ((image1p-image1n)/2)/255;
for Q = S.quality
        i_q = i_q + 1;
namestrp = ['greyjpegs/Img_BS' num2str(BS) '_A' num2str(A) '_Q'     num2str(Q) '_1p.jpg'];
namestrn = ['greyjpegs/Img_BS' num2str(BS) '_A' num2str(A) '_Q' num2str(Q) '_1n.jpg'];
imwrite(image1p/255,namestrp,'jpg', 'Quality', Q);
imwrite(image1n/255,namestrn,'jpg', 'Quality', Q);
error_mean(i_bs, i_a, i_q) = mean2((abs(diff_dataframe./dataframe_vor)));
end
end
end

mean2 是一个快捷函数,它是图像处理工具箱的一部分,用于查找不包括处理 NaN 的 2D 区域的整个平均值。在这种情况下,只需删除所有 NaN 的值并找到生成的平均值。请注意,删除 NaN 会将 2D 区域展开为 1D 向量,因此在这种情况下我们可以简单地使用 mean。作为附加检查,让我们确保没有除以 0 的错误,因此还要检查 Inf

因此,替换此行:

error_mean(i_bs, i_a, i_q) = mean2((abs(diff_dataframe./dataframe_vor)));

...与:

tmp = abs(diff_dataframe ./ dataframe_vor);
mask = ~isnan(tmp) | ~isinf(tmp);
tmp = tmp(mask);

if isempty(tmp)
    error_mean(i_bs, i_a, i_q) = 0;
else
    error_mean(i_bs, i_a, i_q) = mean(tmp);

我们首先将所需的操作分配给一个临时变量,使用 isnan and isinf 删除有问题的值,然后求其余值的平均值。一个复杂的问题是,如果您的 整个区域 NaNInf,那么删除该区域中的所有这些条目会导致空向量,并找到这个未定义的意思。有一个单独的检查以确保如果它是空的,只需分配 0 的值即可。