gpt4 book ai didi

python - 如何对 python 图像(使用 numpy、opencv 或 PIL)的每个 PIXEL(不是每个 rgb 组件!)应用操作?

转载 作者:行者123 更新时间:2023-12-05 08:22:06 25 4
gpt4 key购买 nike

我试图以一种有效的方式对图像的所有像素应用一个函数(在我的特定情况下,我想对每个像素进行一些颜色近似,但我认为这与问题无关)。问题是我找到了不同的方法来做到这一点,但它们都对像素的每个组件应用一个函数,而我想要做的是应用一个函数,接收一个像素(不是像素分量),这是 3 个 rgb 分量(我猜是一个元组,但我不关心格式,只要我将 3 个分量作为函数中的参数).

如果您对我所拥有的感兴趣,这是对我的问题的非有效解决方案(工作正常但速度太慢):

def closest_colour(pixel, colours):
closest_colours = sorted(colours, key=lambda colour: colours_distance(colour, pixel))
return closest_colours[0]

# reduces the colours of the image based on the results of KMean
# img is image open with opencv.imread()
# colours is an array of colours
def image_color_reduction(img, colours):
start = time.time()
print("Color reduction...")
reduced_img = img.copy()[...,::-1]
width = reduced_img.shape[0]
height = reduced_img.shape[1]

for x in range(width):
for y in range(height):
reduced_img[x,y] = closest_colour(reduced_img[x,y], colours)

end = time.time()
print(f"Successfully reduced in {end-start} seconds")
return reduced_img

我关注了这篇文章:PIL - apply the same operation to every pixel这似乎很清楚并且与我的问题一致。我尝试过使用任何类型的图像格式,我尝试过多线程(都使用 pool.map 和 pool.imap),我尝试过 numpy.apply_along_axis,最后我尝试了 PIL.point(),我认为是与我正在寻找的最相似的解决方案。事实上,如果你看一下他们的官方文档:.point() ,它确切地说:为每个可能的像素值调用一次该函数。我发现这确实具有误导性,因为在尝试之后我意识到在此上下文中的像素值 不是指 rgb 元组,而是指 3 个 rgb 组件中的每一个(说真的,在什么世界?)。

如果有人可以分享一些他们的经验并让我对这个问题有所了解,我将不胜感激。提前致谢!!

(更新)

根据您的要求,我添加了有关我正在处理的具体问题的更多信息:

Given

  • an image M of size 1022*1080
  • an array of colours N with size 1 < |N| < 16

Reduce the colours of M by replacing each pixel's colour by the mostsimilar one in N (thanks to your answers I know this is defined asNearest Neighbor Color Quantization)

这是 colours_distance 的缺失实现:

def colours_distance(c1, c2):
(r1,g1,b1) = c1
(r2,g2,b2) = c2
return math.sqrt((r1 - r2)**2 + (g1 - g2) ** 2 + (b1 - b2) **2)

这是运行此代码所需的导入:

import cv2
import time
import math

我的问题中显示的解决方案平均在不到 40 秒的时间内解决了描述的问题。

最佳答案

假设您的图像是一个 (M, N, 3) numpy 数组,您的颜色表是 (K, 3),并且您将颜色距离测量为一些理智的向量范数,你可以使用 scipy 的 cKDTree (或只是 KDTree )为您优化和矢量化查找。

首先用你的颜色表做一棵树:

colors = ... # K, 3 array
color_tree = cKDTree(colors)

现在您可以 query树直接得到输出图像:

_, output = color_tree.query(img)

output 将是 (M, N) 索引数组到 color_table 中。重要的是 KD 树被优化为每个像素执行 O(log K) 查找,而不是 O(K)O(K log K) 与您当前的实现一样。由于循环是用 C 语言实现的,因此您也会从中得到很大的提升。

关于python - 如何对 python 图像(使用 numpy、opencv 或 PIL)的每个 PIXEL(不是每个 rgb 组件!)应用操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65494994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com