如何在不使用for循环的情况下遍历图像中的所有像素并将其RGB值与另一个RGB值进行比较?

时间:2019-06-03 14:32:38

标签: python numpy

因此,基本上我有一个具有16个RGB颜色值的数组,并且我必须计算输入图像中像素的RGB值与所有这16个之间的距离。具有较低距离的RGB值将为输出图像中的RGB值。

问题是:我正在使用嵌套的for循环来执行这些操作,这确实很慢。摘录如下:

for i in range (row):
        for j in range (columns):
            pixel = img[i, j]
            for color in colorsarray:
                dist.append(np.linalg.norm(pixel - color))
            img[i,j] = colorsarray[dist.index(min(dist))]
            dist.clear()

是否有一个numpy函数可以帮助我优化这一点?

2 个答案:

答案 0 :(得分:0)

您可以通过广播数组来计算距离。

如果图像的形状为(x,y,3)并且调色板的形状为(n,3),则可以将每个像素与每种颜色之间的距离计算为形状为(x,y,n)的数组:

# distance[x,y,n] is the distance from pixel (x,y) to
# color n
distance = np.linalg.norm(
    img[:,:,None] - colors[None,None,:], axis=3)

索引:表示“整个轴”,索引None表示“沿该轴广播值”。

然后您可以选择最接近的颜色索引:

# pal_img[x,y] is the index of the color closest to
# pixel (x,y)
pal_img = np.argmin(distance, axis=2)

最后,您可以转换回RGB:

# rgb_img[x,y] is the RGB color closest to pixel (x,y)
rgb_img = colors[pal_img]

这显示了您实际上并不需要NumPy中的特殊功能。不幸的是,这可能有点难以理解。

答案 1 :(得分:0)

未经测试,但是您可以尝试对功能进行向量化

# reshape to have 1D array
dimx = image.shape[0]
image = image.reshape(-1, 3)

def f(pixel):
    # TODO here: logic to return, given the pixel, the closest match in the list

# vectorize the function and apply it to the image
image = np.vectorize(f)(image)

# set the shape back to original
image = image.reshape( dimx, -1, 3 )