Ich versuche, ein Bild mit jeder möglichen Farbe zu erstellen. Es würde mit einem Startpixel beginnen und dann zufällig erzeugte RGB-Pixel um es herum platzieren. Zukünftige Placements würden auf dem offenen Punkt basieren, bei dem der Durchschnitt der Pixel, die ihn am nächsten bei der neuen einzufügenden Farbe umgaben.Notwendigkeit, die Geschwindigkeit der Bilderstellung zu erhöhen
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()
Das Problem ist, dass wenn ich versuche, dies zu laufen, es Tage dauert sogar bis 1.000.000 der Farben zu gehen, und verlangsamt sich deutlich, wie es geht. Ich kann mir nicht vorstellen, wie ich dafür sorgen kann, dass es weniger Zeit braucht, und ich weiß, dass es einen Weg geben muss, dies zu tun, der nicht Monate dauert. Ich bin neu im Code und unterrichte mich selbst, also bitte vergib mir alle offensichtlichen Fehler, die ich völlig übersehen habe.
ohne in Ihren Code speziell sah zu haben, haben Sie darüber nachgedacht, 'cython'-izing oder mit einem JIT-Compiler wie 'numba'? – salient
Sie haben Recht, das könnte viel schneller laufen. Ich denke, dass das Werfen des massiven Wörterbuchs von Funktion zu Funktion wahrscheinlich ein ziemlich großer Flaschenhals ist. Dieses Programm verbraucht jede Menge Speicher, bevor es überhaupt in den iterativen Bereich gelangt. Es gibt definitiv einige Bereiche, die Sie effizienter bewältigen könnten. Ich werde versuchen, heute Abend eine Liste zu machen, wenn ich Zeit habe. –
BHawk
Immer wenn Sie versuchen, Ihren Code zu beschleunigen, ist es eine gute Idee, ihn zu profilieren, um festzustellen, wo er die meiste Zeit verbringt ... also wissen Sie, dass er die meisten von Ihnen für die Optimierung ausgeben kann. Siehe [** _ Wie können Sie ein Python-Skript profilieren? _ **] (https://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script) Das heißt, oft ist die Antwort Verwenden Sie einen ganz anderen Algorithmus und vermeiden Sie den Engpass, was auch immer es ist. – martineau