我試圖用每種可能的顏色創建圖像。它將從種子像素開始,然後在其周圍放置隨機生成的RGB像素。未來的展示位置將基於哪個開放位置的周圍像素的平均值最接近要放置的新顏色。需要增加圖像創建的速度
from PIL import Image
import numpy as np
from random import randint
import sys
import random
import itertools
sys.setcheckinterval(10000)
def moddistance3(x1,y1,z1,x2,y2,z2): #get relative distance between two 3D points
x = abs(x1 - x2)
y = abs(y1 - y2)
z = abs(z1 - z2)
return (x + y + z)
def genColor(unused): #generate random color (not used anymore)
test = 0
while test == 0:
red = randint(0,255)
green = randint(0,255)
blue = randint(0,255)
if unused[red,green,blue] == 1:
test = 1
return (red,green,blue)
def surroundAvg(points,unfilled):
surrounding = {}
count = len(points)
for inc in xrange(count):
neighbors = filledNeighbors(points[inc][0],points[inc][1],unfilled)
nearcount = len(neighbors)
pixred = 0
pixgreen = 0
pixblue = 0
for num in xrange(nearcount):
(temp_red,temp_green,temp_blue) = pixels[neighbors[num][0],neighbors[num][1]]
pixred = pixred + temp_red
pixgreen = pixgreen + temp_green
pixblue = pixblue + temp_blue
pixred = pixred/nearcount
pixgreen = pixgreen/nearcount
pixblue = pixblue/nearcount
surrounding[(points[inc][0],points[inc][1])] = (pixred,pixgreen,pixblue)
return surrounding
def genPoint(perim,unfilled,averages,red,green,blue):
num_test = len(perim)
test = 0
least_diff = 9999
nearby = []
for point in xrange(num_test):
i = perim[point][0]
j = perim[point][1]
pixred = averages[(i,j)][0]
pixgreen = averages[(i,j)][1]
pixblue = averages[(i,j)][2]
diff = abs(red - pixred) + abs(green - pixgreen) + abs(blue - pixblue)
if diff < least_diff or test == 0:
least_diff = diff
newx = i
newy = j
test = 1
return newx,newy
def cubegen(): #create the cube of colors with each color having its own number
cube = np.zeros(16777216,dtype=np.object)
num = 0
for red in xrange(0,256):
for green in xrange(0,256):
for blue in xrange(0,256):
cube[num] = [red,green,blue]
num += 1
return cube
def getNeighbors(x,y,unfilled):
Prod = itertools.product
toremove = []
neighbors = list(Prod(range(x-1,x+2),range(y-1,y+2)))
for num in xrange(len(neighbors)):
i,j = neighbors[num]
if j > 4095 or i > 4095 or unfilled[(i,j)] == 0 or j < 0 or i < 0:
toremove.append((i,j))
map(neighbors.remove,toremove)
return neighbors
def filledNeighbors(x,y,unfilled):
Prod = itertools.product
toremove = []
neighbors = list(Prod(range(x-1,x+2),range(y-1,y+2)))
#neighbors = filter(lambda i,j: j < 4096 and i < 4096 and unfilled[i,j] == 0 and j > -1 and i > -1,allneighbors)
for num in xrange(len(neighbors)):
i,j = neighbors[num]
if j > 4095 or i > 4095 or unfilled[(i,j)] == 1 or j < 0 or i < 0:
toremove.append((i,j))
map(neighbors.remove,toremove)
return neighbors
img = Image.new('RGB', (4096,4096)) # create a new black image
pixels = img.load() # create the pixel map
colorList = range(16777216)
colorCube = cubegen()
print("Color cube created successfully")
unfilled = {}
for x in xrange(4096):
for y in xrange(4096):
unfilled[(x,y)] = 1
startx = 2048
starty = 2048
random.shuffle(colorList)
print("Color list shuffled successfully")
color = colorList[0]
(red,green,blue) = colorCube[color]
pixels[startx,starty] = (red,green,blue)
unfilled[(startx,starty)] = 0
perim_empty = getNeighbors(startx,starty,unfilled)
edge = []
#edge.append((startx,starty))
avg = surroundAvg(perim_empty,unfilled)
print("First point placed successfully.")
#appendEdge = edge.append
#removeEdge = edge.remove
appendPerim = perim_empty.append
removePerim = perim_empty.remove
updateAvg = avg.update
for iteration in xrange(1,16777216):
temp = {}
color = colorList[iteration]
(red,green,blue) = colorCube[color]
(i,j) = genPoint(perim_empty,unfilled,avg,red,green,blue)
unfilled[(i,j)] = 0
pixels[i,j] = (red,green,blue)
new_neighbors = getNeighbors(i,j,unfilled)
map(appendPerim,new_neighbors)
temp = surroundAvg(new_neighbors,unfilled)
updateAvg(temp)
removePerim((i,j))
#appendEdge((i,j))
#if iteration % 20 == 0:
# toremove = []
# appendToRemove = toremove.append
# for num in xrange(len(edge)):
# nearby = getNeighbors(edge[num][0],edge[num][1],unfilled)
# if len(nearby) == 0:
# appendToRemove(edge[num])
#for num in xrange(len(toremove)):
# edge.remove(toremove[num])
# map(removeEdge,toremove)
if iteration % 500 == 0:
print("Iteration %d complete" %iteration)
if iteration == 100000 or iteration == 500000 or iteration ==1000000 or iteration == 5000000 or iteration == 10000000 or iteration == 15000000:
img.save("Perimeter Averaging -- %d iterations.bmp" %iteration)
img.save("Perimeter Averaging Final.bmp")
img.show()
的問題是,當我嘗試運行此,它需要花費數天甚至經過顏色的1,000,000,減慢顯着,因爲它去。我無法弄清楚如何讓它花費更少的時間,而且我知道必須有一種方法可以做到這一點,但這不會花費數月時間。我是新來的代碼,並且在自學,所以請原諒我完全忽略的任何明顯的修復。
,而不必專門看了到你的代碼中,你有沒有考慮'cython',定義它還是使用像'numba'這樣的JIT編譯器? – salient
你說得對,這樣可以更快運行。我猜想從函數到函數的龐大字典都可能是一個很大的瓶頸。這個程序在進入迭代部分之前會消耗大量內存。肯定有一些地方你可以更有效地處理。如果我有時間的話,我今天晚上會列出一張名單。 – BHawk
無論何時試圖加快代碼速度,最好將其分析以確定其花費的大部分時間在哪裏......因此您在此知道要花費大部分時間來優化它。請參閱[** _如何配置python腳本?_ **](https://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script)這就是說,通常答案是完全使用不同的算法並避免瓶頸,無論它是什麼。 – martineau