【问题标题】:Iterating over multidimensional arrays(images) with numpy array - python使用 numpy 数组迭代多维数组(图像) - python
【发布时间】:2012-12-14 04:15:47
【问题描述】:

喂! 我有两个图像(相同尺寸)作为 numpy 数组 imgA - imgB 我想迭代每一行和每一列并得到类似的东西:

for i in range(0, h-1):
  for j in range(0, w-1):
    final[i][j]= imgA[i,j] - imgB[i-k[i],j]

其中 h 和 w 是图像的高度和宽度,k 是尺寸为 [h*w] 的数组。

我看过这个话题: Iterating over a numpy array 但它不适用于图像,我收到错误:解包的值太多 有没有办法用 numpy 和 python 2.7 做到这一点?

谢谢

编辑 我试图更好地解释自己。 我在 LAB 颜色空间中有 2 张图像。 这些图像是 (288,384,3)。 现在我想做 deltaE 所以我可以这样做(吐出 2 个数组):

 imgLabL=np.dsplit(imgL,3)
 imgLabR=np.dsplit(imgR,3)
 imgLl=imgLabL[0]
 imgLa=imgLabL[1]
 imgLb=imgLabL[2]
 imgRl=imgLabR[0]
 imgRa=imgLabR[1]
 imgRb=imgLabR[2]
delta=np.sqrt(((imgLl-imgRl)**2) + ((imgLa - imgRa)**2) + ((imgLb - imgRb)**2)   )

到目前为止一切都很好。 但现在我有了这个大小为 k 的数组(288,384)。 所以现在我需要一个新的增量,但 x 轴不同,就像 imgRl(0,0) 中的像素我想在 imgLl(0+k,0) 中添加像素

你有更多我的问题吗?

【问题讨论】:

  • 你不是说 imgA[i][j] - imgB[i-k[i]][j] 吗??
  • 是的,对不起,我写错了,但我是认真的。我的图像是 384x288,但它进入无限循环,我也不能写 final[i][j],但只是 final,因为我得到:valueError:输出操作数需要缩减,但未启用缩减。
  • imgA[i][j] 里面有什么?它是一个元组吗?如果是这样,那可能是你的问题。赋值需要一个值。
  • imgA 是一个 numpy 数组,imgA.shape 是 288,384,1。

标签: numpy python-2.7


【解决方案1】:

我很确定,无论您尝试做什么,都可以进行矢量化并运行而无需任何循环。但是按照你的代码编写方式,它不起作用也就不足为奇了……

如果k 是一个形状为(h, w) 的数组,那么k[i] 是一个形状为(w,) 的数组。当您执行i-k[i] 时,numpy 将发挥其广播魔法,您将获得一个形状数组(w,)。因此,您使用形状为(w,) 的数组和一个整数来索引imgB。因为索引中的一项是数组,所以fancy indexing 起作用。所以假设imgB 也具有形状(h, w, 1)imgB[i-k[i], j] 的返回值将不是形状(1,) 的数组,而是一个形状数组(w, 1)。然后,当您尝试从 imgA[i, j](一个形状为 (1,) 的数组)中减去它时,广播魔术再次起作用,因此您得到一个形状为 (w, 1) 的数组。

我们不知道final 是什么。但如果它是一个形状为(h, w, 1) 的数组,如imgAimgB,那么final[i][j] 是一个形状为(1,) 的数组,而您正试图为其分配一个形状为(w, 1) 的数组,这不适合。因此出现operand requires a reduction,but reduction is not enabled 错误消息。

编辑

您实际上并不需要拆分数组来计算 DeltaE...

def deltaE(a, b) :
    return np.sqrt(((a - b)**2).sum(axis=-1))

delta = deltaE(imgLabL, imgLabR)

我仍然不明白你想在第二种情况下做什么......如果你想比较沿 x 轴位移的两个图像,我建议使用np.roll

deltaE(imgLabL, np.roll(imgLabR, k, axis=0))

imgLabL 的像素(r, c)imgLAbR 的像素(r - k, c) 之间的deltaE 将在位置(r, c)。这就是你想要的吗?

【讨论】:

  • 在这个 k 我有两个图像的差异。我正在处理立体图像,我发现了差异(docs.opencv.org/modules/calib3d/doc/…)所以现在我想用匹配点制作 deltaE,我应该使用这个差异。如果我做对了,imgA(x,y) 中的点在 imgB(x+disp,y) 中有一个匹配点。因此我必须沿 x 轴移动。我要试试这个 np.roll!顺便说一句,deltaE 方法效果很好!谢谢!
  • 使用 np.roll 我得到这个错误:只有长度为 1 的数组可以转换为 python 标量
【解决方案2】:

我通常使用numpy.nditer,其文档为here,并且有很多示例。简要说明:

import numpy as np
a = np.ones([4,4])

it = np.nditer(a)
for elem in a:
    #do stuff

你也可以使用c风格的迭代,即

while not it.finished:
    #do stuff
    it.iternext()

如果您需要访问数组的索引。在您的情况下,我会将您的两个图像压缩在一起以创建一个形状为 [2,h,w] 的数组,然后对其进行迭代,用计算结果填充一个空数组。

【讨论】:

    猜你喜欢
    • 2016-01-28
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    相关资源
    最近更新 更多