Ваша (исправленная) функция:
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%. Можем ли мы добиться большего успеха с более подходом Pythoni c?
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 пикселей / сек c.
Завершите тестовую программу, используя случайное изображение из предыдущего вопроса (для загрузки используется доступ 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()
и тестовые изображения до и после:
![test image before](https://i.stack.imgur.com/f3MMx.png)
![test image after](https://i.stack.imgur.com/ccD3r.png)
Если вас интересуют только результаты, используйте любой родной метод, который позволяет ваша библиотека изображений. Этот короткий фрагмент, использующий собственные 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 пикселей / сек c - колоссальное * В 1038 * 500 раз быстрее , чем моя нативная (/ naive) реализация.
(Hyper-fancy touple-to-list происходит из { ссылка })