【问题标题】:How to iterate through all pixels in a image and compare their RGB values with another RGB value without using for loop?如何在不使用 for 循环的情况下遍历图像中的所有像素并将它们的 RGB 值与另一个 RGB 值进行比较?
【发布时间】:2019-06-03 14:32:38
【问题描述】:

所以,基本上我有一个包含 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 函数可以帮我优化这个?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

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

    如果您的图像具有 (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 中的特殊功能。不幸的是,这可能有点难以理解。

    【讨论】:

    • 好吧,它起作用了,顺便说一下快了很多。感谢分享,现在将尝试了解到底发生了什么。
    • @MarceloYuriBenesciutti 如何将图像形状设置为 (x,y,3) 并将调色板形状设置为 (n,3)?
    • RGB 图像通常具有 (y,x,3) 形状。例如,如果您从 PIL 获得它,那么它将具有的形状。如果不是 (y,x,3),那么它可能不是 RGB,您可能需要先进行色彩空间转换。 (注意顺序:先是 Y,然后是 X。)
    【解决方案2】:

    未经测试,但您可以尝试矢量化您的函数:

    # 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 )
    

    【讨论】:

    • 请阅读 np.vectorize 免责声明 - 它不会提高速度。最好自己做一些计时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多