您的(更正后的)函数是:
def findNearest(rgb):
a = []
for i in range(len(rgbValues)):
d = ((rgbValues[i][0]-rgb[0])*0.3)**2 + ((rgbValues[i][1]-rgb[1])*0.59)**2 + ((rgbValues[i][2]-rgb[2])*0.11)**2
a.append([d,i])
list.sort(a)
return rgbValues[a[0][1]]
它返回正确的rgbValues
;现在这是可能的,因为它的索引存储在a
以及。这——在一个公认的大致定时框架中——每秒处理大约 27,085 个像素。
一个简单的实现,调整为仅记住最近的索引:
def findNearest(rgb):
dist = ((rgbValues[0][0]-rgb[0])*0.3)**2 + ((rgbValues[0][1]-rgb[1])*0.59)**2 + ((rgbValues[0][2]-rgb[2])*0.11)**2
index = 0
for i in range(1,len(rgbValues)):
d = ((rgbValues[i][0]-rgb[0])*0.3)**2 + ((rgbValues[i][1]-rgb[1])*0.59)**2 + ((rgbValues[i][2]-rgb[2])*0.11)**2
if d < dist:
dist = d
index = i
return rgbValues[index]
性能已经好得多:每秒 37,175 像素,速度提高了 37%。我们可以用更 Pythonic 的方法做得更好吗?
def findNearest(rgb):
dist = [(((rgbValues[i][0]-rgb[0])*0.3)**2 + ((rgbValues[i][1]-rgb[1])*0.59)**2 + ((rgbValues[i][2]-rgb[2])*0.11)**2,i) for i in range(22)]
return rgbValues[min(dist)[1]]
没有。使用相同的图像和相同的计时机制,它会下降到 33,417 像素/秒。
完整的测试程序,使用之前问题中的随机图像(它使用 PIL 来加载、访问像素并显示图像,但这与距离计算无关):
import random
from PIL import Image
from time import time
def findNearest_org(rgb):
a = []
for i in range(len(rgbValues)):
d = ((rgbValues[i][0]-rgb[0])*0.3)**2 + ((rgbValues[i][1]-rgb[1])*0.59)**2 + ((rgbValues[i][2]-rgb[2])*0.11)**2
a.append([d,i])
list.sort(a)
return rgbValues[a[0][1]]
def findNearest_raw(rgb):
dist = ((rgbValues[0][0]-rgb[0])*0.3)**2 + ((rgbValues[0][1]-rgb[1])*0.59)**2 + ((rgbValues[0][2]-rgb[2])*0.11)**2
index = 0
for i in range(1,len(rgbValues)):
d = ((rgbValues[i][0]-rgb[0])*0.3)**2 + ((rgbValues[i][1]-rgb[1])*0.59)**2 + ((rgbValues[i][2]-rgb[2])*0.11)**2
if d < dist:
dist = d
index = i
return rgbValues[index]
def findNearest_list(rgb):
dist = [(((rgbValues[i][0]-rgb[0])*0.3)**2 + ((rgbValues[i][1]-rgb[1])*0.59)**2 + ((rgbValues[i][2]-rgb[2])*0.11)**2,i) for i in range(22)]
return rgbValues[min(dist)[1]]
image = Image.open('output-2.png')
pixels = image.load()
width, height = image.size
rgbValues = [tuple(random.randrange(0,256) for _ in range(3)) for _ in range(22)]
start = time()
for y in range(height):
for x in range(width):
# fetch the rgb value
color = pixels[x,y]
# replace with nearest
pixels[x,y] = findNearest_list (color)
print ('pixels/sec:', (width*height)/(time()-start))
image.show()
并测试之前和之后的图像:
如果您只对结果感兴趣,请使用图像库允许的任何本机方法。这段短文使用了PIL自己的quantize https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.quantize
rgbValues = list(sum(rgbValues, ()))*12
rgbValues = rgbValues[:768]
palimage = Image.new('P', (width, height))
palimage.putpalette(rgbValues)
newimage = image.quantize(palette=palimage)
将计算外包给本机代码,结果好得多:18,443,414 像素/秒 – 一个惊人的数字快 500 倍比我的本机(/naïve)实现。
(超级花哨的元组到列表来自https://stackoverflow.com/a/3205524 https://stackoverflow.com/a/3205524)