首先:我是一名编程初学者。 我有一个NumPy数组,每个像素都有RGB数据。
im = np.asarray(Image.open('image.jpg'))
我正在将每个像素传递给我的getNearestColor函数。 Out也是一个numpy数组。
for x in range(len(im)):
for y in range(len(im[x])):
for _ in range(len(im[x][y])):
out[x][y] = getNearestColor(im[x][y])
然后我要在3d RGB系统中计算距离。
def getNearestColor(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)
list.sort(a)
return a[0]
rgbValues是具有22个RGB值的列表,需要与之进行比较。这很慢。这也只是给我距离(d)。它应该还给我rgb值。如何获得最接近的RGB值并使它更快。 我希望一切都是可以理解的:)
答案 0 :(得分:1)
(已更正)您的功能是:
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%。我们可以使用更Python化的方法做得更好吗?
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
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倍。
(超豪华元组到列表来自https://stackoverflow.com/a/3205524)