python - 在 python 中从 (2,MN) 矩阵读取 (M,N) 图像的值

标签 python vectorization

假设我有一个 (M,N) 图像 J(形状为 (M,N,3))。我有一个 (2,MN) 矩阵 K,如下所示:

0 0 0 ... 0 1 1 1 ... 1 ............. M M M ... M

0 1 2 ... N 1 2 3 ... N ............. 1 2 3 ... N

现在我将上面的矩阵乘以 2 x 2 矩阵,得到一个与 K 大小相同的新矩阵 T。

现在我想创建一个新图像,其中新图像中的像素 (r,s) 等于 r*N+ 中旧图像像素的 (R,G,B) 值T 的 M 列。

如果可能的话,我想以矢量化的方式执行此操作。我不想使用 for 循环(我已经知道如何使用 for 循环来做到这一点,但它非常慢)。事实上,我对这个问题的兴趣是因为我想以矢量化的方式应用单应性变换。

感谢任何帮助。这是使我想要清楚的内容的疯狂版本:

for r in range(0,M):
    for s in range(0,N):
        x, y = T[:,r*N+s]
        new_image[r,s] = J[x,y]

最佳答案

由于内部索引的幸运布局,您几乎可以直接使用索引数组:

import numpy as np

# set up dummy input
M,N = 300,400
J = np.random.rand(M, N, 3)
T = np.array([np.random.randint(0, M, M*N), np.random.randint(0, N, M*N)])

# original    
new_image = np.empty_like(J)
for r in range(0,M):
    for s in range(0,N):
        x, y = T[:,r*N+s]
        new_image[r,s] = J[x,y]

# vectorized new
new_image_vect = J[tuple(T)].reshape(J.shape)

检查:

>>> np.array_equal(new_image, new_image_vect)
True

上面的工作方式并不完全是微不足道的,因为 advanced indexing is a fickle thing 。我上面写的相当于

J[(T[0,...], T[1,...])].reshape(J.shape) -> J[T[0,...], T[1,...]].reshape(J.shape)

现在第一部分更清楚了:取出T第一行中的每个元素并将其用作J的第一个索引,然后取出T中的相应元素T 的第二行并将其用作 J 相应的第二个索引。这部分内容涵盖了循环版本中的 J[x,y]

但是,由于我们本质上是使用长度为 M*N 的一维数组来索引数组,因此生成的数组的形状也将具有 M*N 形状它的第一个维度(以及大小为 3 的尾随维度)。因此,我们需要将结果 reshape (M,N,3)

所有这些都只能直接起作用,因为 T 中的索引是根据 C 连续内存顺序存储的。如果不是这种情况,我们就必须来回转置我们的数组,以便生成具有正确布局的结果数组。

关于python - 在 python 中从 (2,MN) 矩阵读取 (M,N) 图像的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53063528/

相关文章:

python - Django:在数据库错误中获取最近插入的特定字段值:需要超过 1 个值才能解包

python - 对 Pandas 中包含字符串的列进行排序

python - 为什么 min({1},{0}) 返回 {1}

matlab - 矩阵的多个常数并将它们转换为matlab中的 block 对角矩阵

python - pandas 数据框中有效值(非空行)的移动平均值

python - 将多个返回语句拆分为不同的函数

python - 将一个数组的每个元素乘以另一个数组的每个元素

matlab:向量化对 N 个二进制矩阵进行 ORing 的单个循环

c++ - 这个编译器消息(矢量化,GCC)是什么意思?

matlab - "kron"产品的多维版本?