Python 需要提高图像创建的速度
我正在尝试用每种可能的颜色创建一个图像。它将从种子像素开始,然后在其周围放置随机生成的RGB像素。未来的放置将基于任意一个开放点,其周围像素的平均值最接近要放置的新颜色Python 需要提高图像创建的速度,python,image,numpy,colors,Python,Image,Numpy,Colors,我正在尝试用每种可能的颜色创建一个图像。它将从种子像素开始,然后在其周围放置随机生成的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
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()
从PIL导入图像
将numpy作为np导入
从随机导入randint
导入系统
随机输入
进口itertools
系统设置检查间隔(10000)
def moddistance3(x1、y1、z1、x2、y2、z2):#获取两个3D点之间的相对距离
x=abs(x1-x2)
y=abs(y1-y2)
z=abs(z1-z2)
返回(x+y+z)
def genColor(未使用):#生成随机颜色(不再使用)
测试=0
当test==0时:
红色=randint(0255)
绿色=兰迪特(0255)
蓝色=兰迪特(0255)
如果未使用[红、绿、蓝]==1:
测试=1
返回(红色、绿色、蓝色)
def周围平均值(点,未填充):
周围={}
计数=长度(点数)
对于X范围内的inc(计数):
邻居=已填充的邻居(点数[inc][0],点数[inc][1],未填充)
nearcount=len(邻居)
pixred=0
pixgreen=0
像素蓝=0
对于xrange中的num(nearcount):
(淡红色、淡绿色、淡蓝色)=像素[邻居[num][0],邻居[num][1]]
pixred=pixred+温度
像素绿色=像素绿色+温度绿色
像素蓝=像素蓝+温度蓝
pixred=pixred/nearcount
像素绿色=像素绿色/近计数
像素蓝=像素蓝/近计数
周围[(点数[inc][0],点数[inc][1])]=(像素红色、像素绿色、像素蓝色)
返回环境
def genPoint(边缘、未填充、平均值、红色、绿色、蓝色):
num_test=len(perim)
测试=0
最小差值=9999
附近=[]
对于X范围内的点(数值测试):
i=perim[点][0]
j=周长[点][1]
pixred=平均值[(i,j)][0]
pixgreen=平均值[(i,j)][1]
pixblue=平均值[(i,j)][2]
差异=abs(红色-像素红色)+abs(绿色-像素绿色)+abs(蓝色-像素蓝色)
如果差异4095或i>4095或未填充[(i,j)]==0或j<0或i<0:
删除。追加((i,j))
映射(邻居。删除,删除)
回乡
def FILLED邻域(x、y、未填充):
产品=itertools.product
toremove=[]
邻居=列表(产品(范围(x-1,x+2),范围(y-1,y+2)))
#邻居=过滤器(λi,j:j<4096和i<4096,未填充[i,j]==0和j>-1和i>-1,所有邻居)
对于xrange中的num(len(邻居)):
i、 j=邻居[num]
如果j>4095或i>4095或未填充[(i,j)]==1或j<0或i<0:
删除。追加((i,j))
映射(邻居。删除,删除)
回乡
img=Image.new('RGB',(40964096))#创建一个新的黑色图像
像素=img.load()#创建像素贴图
颜色列表=范围(16777216)
colorCube=cubegen()
打印(“已成功创建彩色立方体”)
未填充={}
对于x范围内的x(4096):
对于X范围内的y(4096):
未填充[(x,y)]=1
startx=2048
starty=2048
随机。洗牌(颜色列表)
打印(“颜色列表洗牌成功”)
颜色=颜色列表[0]
(红、绿、蓝)=彩色立方体[颜色]
像素[startx,starty]=(红、绿、蓝)
未填充[(星形,星形)]=0
perim_empty=GetNeights(startx、starty、未填充)
边缘=[]
#追加边((startx,starty))
平均值=周围平均值(周围为空,未填充)
打印(“成功放置第一个点”)
#appendEdge=edge.append
#removedge=edge.remove
appendPerim=perim\u empty.append
removePerim=perim\u空。移除
updateAvg=avg.update
对于xrange(116777216)中的迭代:
温度={}
颜色=颜色列表[迭代]
(红、绿、蓝)=彩色立方体[颜色]
(i,j)=genPoint(perim_空、未填充、平均、红色、绿色、蓝色)
未填充[(i,j)]=0
像素[i,j]=(红、绿、蓝)
新邻居=获取邻居(i,j,未填充)
地图(附件、新邻居)
温度=周围平均值(新邻居,未填充)
updateAvg(临时)
移除perim((i,j))
#附录边((i,j))
#如果迭代%20==0:
#toremove=[]
#appendToRemove=toremove.append
#对于xrange中的num(len(edge)):
#附近=获取邻居(边[num][0],边[num][1],未填充)
#如果len(附近)==0:
#appendToRemove(边[num])
#对于xrange中的num(len(toremove)):
#删除边缘(删除[num])
#映射(删除边缘,删除)
如果迭代%500==0:
打印(“迭代%d已完成”%Iteration)
如果迭代==100000或迭代==500000或迭代==1000000或迭代==5000000或迭代==10000000或迭代==15000000:
保存(“周长平均--%d次迭代.bmp”%iteration)
保存(“周长平均最终.bmp”)
img.show()
问题是,当我尝试运行这个程序时,它甚至需要几天的时间来处理1000000种颜色,并且随着时间的推移,速度会大大减慢。我不知道如何使它花费更少的时间,我知道一定有一种方法可以做到这一点,不需要几个月。我对代码还不熟悉,正在自学,所以请原谅我完全忽略的任何明显的修复。好的,我花了一些时间研究这个问题,并做了一些更改以加快速度。我真的很喜欢你在这个项目中实施的想法,而且结果非常好
from PIL import Image
import sys
import random
import itertools
import datetime as dt
#sys.setcheckinterval(10000)
def surroundAvg(points):
surrounding = {}
for inc in points:
neighbors = filledNeighbors(inc[0],inc[1])
nearcount = len(neighbors)
pixred = 0
pixgreen = 0
pixblue = 0
for n in neighbors:
(temp_red,temp_green,temp_blue) = pixels[n[0],n[1]]
pixred += temp_red
pixgreen += temp_green
pixblue += temp_blue
pixred = pixred / nearcount
pixgreen = pixgreen / nearcount
pixblue = pixblue / nearcount
surrounding[(inc[0],inc[1])] = (pixred,pixgreen,pixblue)
return surrounding
def genPoint(perim,averages,red,green,blue):
test = 0
least_diff = 9999
threshold = 35
for point in perim:
i = point[0]
j = point[1]
if pixels[i,j] == (0,0,0):
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
if least_diff < threshold:
return newx,newy,perim
else:
perim.pop(perim.index(point))
return newx,newy,perim
def cubegen(): #create the cube of colors with each color having its own number
cube = []
num = 0
for red in xrange(0,256):
for green in xrange(0,256):
for blue in xrange(0,256):
cube.append((red,green,blue))
num += 1
return tuple(cube)
def getNeighbors(x,y):
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 pixels[i,j] != (0,0,0) or j < 0 or i < 0:
toremove.append((i,j))
map(neighbors.remove,toremove)
return neighbors
def filledNeighbors(x,y):
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 pixels[i,j] == (0,0,0) 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
print("Making list")
colorList = range(16777216)
random.shuffle(colorList)
print("Color list shuffled successfully")
print("Making cube")
colorCube = cubegen()
print("Color cube created successfully")
startx = 2048
starty = 2048
color = colorList[0]
(red,green,blue) = colorCube[color]
#start with a random color
pixels[startx,starty] = (red,green,blue)
#get it's neighboring pixels
perim_empty = getNeighbors(startx,starty)
#calc avg values (original pixel)
avg = surroundAvg(perim_empty)
print("First point placed successfully.")
appendPerim = perim_empty.append
removePerim = perim_empty.remove
updateAvg = avg.update
start = dt.datetime.now()
for iteration in xrange(1,16777216):
temp = {}
color = colorList[iteration]
(red,green,blue) = colorCube[color]
i,j,perim_empty = genPoint(perim_empty,avg,red,green,blue)
pixels[i,j] = (red,green,blue)
new_neighbors = getNeighbors(i,j)
map(appendPerim,new_neighbors)
temp = surroundAvg(new_neighbors)
updateAvg(temp)
removePerim((i,j))
for p in perim_empty:
if p[0] == i and p[1] == j:
perim_empty.remove(p)
if iteration % 1000 == 0:
end = dt.datetime.now()
print("Iteration %d complete: %f" %(iteration,(end-start).total_seconds()))
print("Perimeter size: %d"%len(perim_empty))
print("Averages size: %d"%sys.getsizeof(avg))
start = dt.datetime.now()
img.save("%06d.png" % (iteration/1000))
img.save("Perimeter Averaging Final.bmp")
img.show()