python - 为什么这两个 numpy.divide 运算会给出如此不同的结果?

标签 python numpy numpy-ndarray division array-broadcasting

我想使用 here 中描述的公式修正相机高光谱读数中的值。 ;

the captured data is subtracted by dark reference and divided with white reference subtracted dark reference.

在原始示例中,任务相当简单,白色和黑色引用与主要数据具有相同的形状,因此公式执行为:

corrected_nparr = np.divide(np.subtract(data_nparr, dark_nparr),
np.subtract(white_nparr, dark_nparr))

但是根据我的经验,主要数据要大得多。我的例子中的形状如下;

$ white_nparr.shape, dark_nparr.shape, data_nparr.shape
((100, 640, 224), (100, 640, 224), (4300, 640, 224))

这就是我重复引用数组的原因。

   white_nparr_rep = white_nparr.repeat(43, axis=0)
   dark_nparr_rep = dark_nparr.repeat(43, axis=0)
return np.divide(np.subtract(data_nparr, dark_nparr_rep), np.subtract(white_nparr_rep, dark_nparr_rep))

几乎完美工作,如左图所示。但这种方法需要大量内存,因此我决定遍历大数组并即时用更正后的值替换原始值:

ref_scale = dark_nparr.shape[0]
data_scale = data_nparr.shape[0]

for i in range(int(data_scale / ref_scale)):
    data_nparr[i*ref_scale:(i+1)*ref_scale] = 
        np.divide
        ( 
        np.subtract(data_nparr[i*ref_scale:(i+1)*ref_scale], dark_nparr),
        np.subtract(white_nparr, dark_nparr)
        )

但是这种遍历方法给了我最丑陋的结果,如右图所示。如果有任何可以帮助我解决此问题的想法,我将不胜感激。

注意:我应用了 20 次共同相加(20 次读数的平均值)来获得下面的图像。

编辑:每个数组的dtype如下:

$ white_nparr.dtype, dark_nparr.dtype, data_nparr.dtype
(dtype('float32'), dtype('float32'), dtype('float32'))

left image right image

最佳答案

您的两种方法不一致,因为在第一种方法中您使用了

   white_nparr_rep = white_nparr.repeat(43, axis=0)

但第二种方法对应于使用

   white_nparr_rep = np.tile(white_nparr, (43, 1, 1))

如果第一种方法正确,您必须调整第二种方法以进行相应操作。也许

for i in range(int(data_scale / ref_scale)):
    data_nparr[i*ref_scale:(i+1)*ref_scale] = 
        np.divide
        ( 
        np.subtract(data_nparr[i*ref_scale:(i+1)*ref_scale], dark_nparr[i]),
        np.subtract(white_nparr[i], dark_nparr[i])
        )

一个二维数组的简单示例,显示了 repeattile 之间的区别:

In [146]: z
Out[146]: 
array([[ 1,  2,  3,  4,  5],
       [11, 12, 13, 14, 15]])

In [147]: np.repeat(z, 3, axis=0)
Out[147]: 
array([[ 1,  2,  3,  4,  5],
       [ 1,  2,  3,  4,  5],
       [ 1,  2,  3,  4,  5],
       [11, 12, 13, 14, 15],
       [11, 12, 13, 14, 15],
       [11, 12, 13, 14, 15]])

In [148]: np.tile(z, (3, 1))
Out[148]: 
array([[ 1,  2,  3,  4,  5],
       [11, 12, 13, 14, 15],
       [ 1,  2,  3,  4,  5],
       [11, 12, 13, 14, 15],
       [ 1,  2,  3,  4,  5],
       [11, 12, 13, 14, 15]])

题外话:我不知道为什么您链接到的页面的作者将 NumPy 表达式写为(例如):

corrected_nparr = np.divide(
    np.subtract(data_nparr, dark_nparr),
    np.subtract(white_nparr, dark_nparr))

NumPy 允许您将其写为

corrected_nparr = (data_nparr - dark_nparr) / (white_nparr - dark_nparr)

这对我来说看起来更好。

关于python - 为什么这两个 numpy.divide 运算会给出如此不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71343443/

相关文章:

python - wxPython图像占用大量内存

python - xml ns0 : prefix cant make the previous solutions work

python - 在 python 中的两个对象之间存储和使用信息的最佳方式是什么?

python - 将图像分割成任意数量的框

python - 在成对比较 NxN numpy 数组中找到 N 个最小值?

python - `mode=' c '` do in numpy.ndarray[..., mode=' c'] 有什么作用?

python - Numpy PIL Python : crop image on whitespace or crop text with histogram Thresholds

python - Numpy 不会为点积抛出 FloatingPointError

python - 按位置将函数数组应用于元素数组

python - 比较两个同种格式日期时间字符串是否可靠?