此代码的前提条件的详细信息很长,因此我将尽力总结一下。 WB/RG/BYColor是基本图像,FIDO是应用到此基本图像的叠加层。 S_wb/rg/by是最终的输出图像。 WB/RG/BYColor与FIDO的尺寸相同。

对于FIDO中的每个唯一元素,我们要计算基本图像中该区域的平均颜色。下面的代码可以做到这一点,但是因为numFIDOs非常大(最多40,000个),因此需要长时间

计算三个独立的RGB channel 的平均值。

sX=200
sY=200
S_wb = np.zeros((sX, sY))
S_rg = np.zeros((sX, sY))
S_by = np.zeros((sX, sY))
uniqueFIDOs, unique_counts = np.unique(FIDO, return_counts=True)
numFIDOs = uniqueFIDOs.shape
for i in np.arange(0,numFIDOs[0]):
    Lookup = FIDO==uniqueFIDOs[i]
    # Get average of color signals for this FIDO
    S_wb[Lookup] = np.sum(WBColor[Lookup])/unique_counts[i]
    S_rg[Lookup] = np.sum(RGColor[Lookup])/unique_counts[i]
    S_by[Lookup] = np.sum(BYColor[Lookup])/unique_counts[i]

运行大约需要7.89秒,时间不长,但是它将包含在另一个循环中,因此它会累积起来!

我已经尝试过向量化(如下所示),但是我做不到
FIDOsize = unique_counts[0:numFIDOs[0]:1]
Lookup = FIDO ==uniqueFIDOs[0:numFIDOs[0]:1]
S_wb[Lookup] = np.sum(WBColor[Lookup])/FIDOsize
S_rg[Lookup] = np.sum(RGColor[Lookup])/FIDOsize
S_by[Lookup] = np.sum(BYColor[Lookup])/FIDOsize

数组大小匹配错误

最佳答案

这已在Scipy中实现,因此您可以执行以下操作:

from scipy.ndimage.measurements import mean as labeled_mean

labels = np.arange(FIDO.max()+1, dtype=int)
S_wb = labeled_mean(WBColor, FIDO, labels)[FIDO]
S_rg = labeled_mean(RGColor, FIDO, labels)[FIDO]
S_by = labeled_mean(BYColor, FIDO, labels)[FIDO]

假设FIDO包含相对较小的整数。如果不是这种情况,则可以通过np.unique(FIDO, return_inverse=True)对其进行转换。

对于200x200的图像和FIDO,该简单代码比原始速度快1000倍,其中ojit_code包含从零到40,000的随机整数。

10-08 10:59