查找图像列表的中位数

6

如果我有一个由3D ndarray表示的图像列表,例如 [[x,y,color],...],我可以使用哪些操作来输出其值为所有值的中位数的图像?我正在使用for循环,但发现速度太慢。


请分享您的循环实现,以产生预期的结果? - Divakar
3个回答

7
这是我的使用NumPy进行矢量化实现的方法:
测试中用到了以下五张图片: enter image description here 相关部分:
import numpy as np
import scipy.ndimage

# Load five images:
ims = [scipy.ndimage.imread(str(i + 1) + '.png', flatten=True) for i in range(5)]
# Stack the reshaped images (rows) vertically:
ims = np.vstack([im.reshape(1,im.shape[0] * im.shape[1]) for im in ims])
# Compute the median column by column and reshape to the original shape:
median = np.median(ims, axis=0).reshape(100, 100)

完整的脚本:
import numpy as np
import scipy.ndimage
import matplotlib.pyplot as plt

ims = [scipy.ndimage.imread(str(i + 1) + '.png', flatten=True) for i in range(5)]
print ims[0].shape # (100, 100)

ims = np.vstack([im.reshape(1,im.shape[0] * im.shape[1]) for im in ims])
print ims.shape # (5, 10000)

median = np.median(ims, axis=0).reshape(100, 100)

fig = plt.figure(figsize=(100./109., 100./109.), dpi=109, frameon=False)
ax = fig.add_axes([0, 0, 1, 1])
ax.axis('off')
plt.imshow(median, cmap='Greys_r')
plt.show()

这五张图片的中位数结果如下所示 (numpy.median):

enter image description here

有趣的是,平均值 (numpy.mean) 的结果看起来像这样:

enter image description here

好了,科学与艺术相遇。 :-)


5

您提到了彩色图像,格式为三维ndarrays列表。假设有n张图像:

imgs = [img_1, ..., img_n]

其中,imgs是一个列表,每个img_i都是形状为(nrows, ncols, 3)的ndarray。

将该列表转换为4d ndarray,然后对应于图像的维度取中值:

import numpy as np

# Convert images to 4d ndarray, size(n, nrows, ncols, 3)
imgs = np.asarray(imgs)

# Take the median over the first dim
med = np.median(imgs, axis=0)

这将给出每个像素的中位数。每个像素的每个颜色通道的值是所有图像对应像素/通道的中位数。 asarray() 的文档说:“如果输入已经是一个 ndarray,则不执行任何复制操作”。这表明,如果将原始图像列表存储为4d ndarray而不是列表,则操作速度会更快。在这种情况下,不需要复制内存中的信息(或运行asarray())。

谢谢!我之前尝试过axis=0,但没有成功。再次尝试后,代码np.median(imgs, axis=0)简单易行且有效。 - ferk86

-3
你能提供一下你的数据示例吗?
否则,我认为你可以使用numpy和numpy.mean
这里有文档在这里;)

1
OP明确要求中位数而不是平均数。 - eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接