使用numpy,python和open cv2.4迭代多维数组

最近我发布了一个关于此的问题,但最后我以非优雅的方式解决了它 .

我有2个图像是numpy数组,我想创建一个迭代2个图像的新数组 . 我有3个案例,我做了以下事情:

delta= np.empty((h, w, 3),int)
    for z in range (0,3):
      for i in range(0, (h-1)):
        for j in range(0, (w-1)):
         delta[i][j][z]=np.sqrt(((imgLlab[i][j][0]-imgRlab[i][j-disp[i][j]][0])**2) + ((imgLlab[i][j][1]-imgRlab[i][j-disp[i][j]][1])**2) + ((imgLlab[i][j][2]-imgRlab[i][j-disp[i][j]][2])**2) )


delta= np.empty((h, w, 3),int)
    for z in range (0,3):
     for i in range(0, (h-1)):
    for j in range(0, (w-1)):
       delta[i][j][z]=np.sqrt(((imgLlab[i][j][0]-imgRlab[i][j-disp[i][j]][0])**2)  )


for z in range (0,3):
 for i in range(0, (h-1)):
  for j in range(0, (w-1)):
    delta[i][j][z]=np.sqrt(((imgLlab[i][j][1]-imgRlab[i][j-disp[i][j]][1])**2) + ((imgLlab[i][j][2]-imgRlab[i][j-disp[i][j]][2])**2) )

我想不要每次都重复迭代,尽快做到 .

还有另一种方法可以用numpy做到这一点吗?

在Jaime帮助之后编辑,我改变了我的代码:

disp= np.hstack([disp, disp, disp]).reshape(h,w,3).astype(np.int)
rows = np.arange(h).reshape(h, 1, 1)
cols = np.arange(w).reshape(1, w, 1)
planes = np.arange(3).reshape(1, 1, 3)
print rows.shape, cols.shape, planes.shape, disp.shape, h
data = imgLlab[rows, cols, planes] - imgRlab[rows ,cols - disp[rows, cols, planes], planes]
data = data**2
data = np.sum(data, axis=-1)
data = np.sqrt(data)

我不得不重塑dist,因为它没有imglLab和imgRLab的相同形状,我的意思是imglLab是(288,384,3)和disp是(288,384) . 另外,如果我打印disp(288,384,1)我得到相同的错误,它就像那里没有值,但维度与其他维度相同 . 但是现在3个数组得到了相同的维度,我得到一个indexError:index(384)超出范围(0 <= = 1中的索引(383) .

回答(1)

2 years ago

您可以在代码中改进一些内容 .

  • 不要将数组索引为 arr[a][b][c] . 这样做时,你实际上是在创建一个python对象 arr[a] ,然后用它来创建一个新的python对象 arr[a][b] ,从中构造你想要的对象 arr[a][b][c] . 如果你使用numpy的元组索引作为 arr[a, b, c] ,那么所有中间构造和破坏都将被消除 .

  • 不需要时使用循环!代替

for j in xrange(len(a)) :
    a[j] = b[j]

你可以做

a[:] = b[:]

这实际上就是让numpy很棒的东西,所以要用它!

至于加速你的代码...你应该检查 imgLlab.shapeimgRlab.shapedisp.shape 都是一样的, (h, w, 3) . 您的索引错误表明其中一个较小 . 无论如何,在我们需要利用broadcastingfancy indexing后得到你的东西 . 阅读并消化这些链接,或者以下内容没有多大意义:

rows = np.arange(h).reshape(h, 1, 1)
cols = np.arange(w).reshape(1, w, 1)
planes = np.arange(3).reshape(1, 1, 3)
data = imgLlab[rows, cols, planes] - \ 
       imgRlab[planes, rows - disp[rows, cols, planes], planes]
# data is of shape (h, w, 3)
data = data**2
# data is of shape (h, w, 3)
data = np.sum(data, axis=-1)
# data is of shape (h, w)
data = np.sqrt(data)
# data is of shape (h, w)

如果你真的想将完全相同的数组复制到 delta 数组的三个平面,你可以这样做:

delta[...] = data.reshape(h, w, 1) # equivalent to data.reshape(-1, 1)

这只是你的第一个案例,但是一旦你了解了正在发生的事情,其他的应该很容易从第一个例子构建 . 如果遇到麻烦,请回来问问!