我试图将以下实验复制为我在python中的第一个项目:
http://www.petercollingridge.co.uk/evolving-images
我要做的是在游戏中在屏幕上生成200个随机灰度圆圈,然后在屏幕上改变随机选择的圆圈的参数,然后通过比较圆形图像的像素值来计算适应度函数到目标图像的像素值。根据适合度值,父母或孩子将被传递给下一代。
我运行了10,000代代码,但我的健身值没有提高,我基本上没有得到我想要的结果。我在下面发布我的代码(只有main.py而不是导入的函数)。我认为我的突变方法是错误的,需要改变,但我不确定如何解决它。我很感激您的反馈。
import pygame
import random
import numpy
import time
from PIL import Image
from Fitness import fit
from MutateOrder import mutation
from GenerateCircles import generate
from MutatePosition import position
from MutateRadius import rad
from MutateColor import ccolor
from MutateAlpha import trans
import pygame.locals
start_time = time.time()
width = 512
height = 512
thickness = 0
d = (height)*1/6
white = (255,255,255)
genome = []
bestFit = []
bestMutation = []
DISPLAY = (1, 1)
DEPTH = 32
FLAGS = 0
count = 0
num = 200
iter = 10000
fitness = numpy.zeros((1,iter+1))
pygame.init()
def circle_drawing(surf):
for i in range(1,num+1):
r = random.randint(5,d)
x = random.randint(0,width)
y = random.randint(0,height)
alfa = random.randint(0,255)
color1 = random.randint(0,255)
color2 = random.randint(0,255)
color3 = random.randint(0,255)
# calculating the gray-scale value
color4 = 0.299*color1 + 0.587*color2 + 0.114*color3
color5 = int(color4)
color = (color5,color5,color5)
# the genome vector
genome[((i-1)+(i-1)*5):((i+4)+(i-1)*5)] = [x,y,i,r,color5,alfa]
surf2 = pygame.Surface((r*2,r*2))
surf2.fill(white)
surf2.set_colorkey(white)
pygame.draw.circle(surf2, color, (r,r), r, thickness)
surf2.set_alpha(alfa)
surf.blit(surf2, (x,y))
pygame.display.flip()
return surf
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
work_surface = pygame.Surface((width,height))
work_surface.fill(white)
work_surface.set_colorkey(white)
ws = circle_drawing(work_surface.copy())
pygame.image.save(ws, "circles_" + str(count)+".png")
# the original genome gets saved as a numpy array, then reshaped into a 2-D 50x6 array
genomeArr = numpy.asarray(genome)
genomeArr.shape = (num,6)
print "\n first genome array: \n\n", genomeArr
# saving the first array of randomly generated circles in originalGenomeArr
originalGenomeArr = genomeArr
# the image of the circles (the original genome)gets converted into a numpy array
# this is done so we can subtract its pixel values from the target image and calculate fitness
circles = Image.open("circles_" + str(count)+".png").convert('L')
print "\n circles format: \n", circles.format, circles.size, circles.mode
circlesArr = numpy.asarray(circles)
print "\n the pixel values of the first Circles image\n\n", circlesArr
# The target image converted into a numpy array
im = Image.open("lena.png")
print "\n\n target format: \n\n", im.format, im.size, im.mode
arr = numpy.asarray(im)
print "\n\n the pixel values of the target image: \n\n", arr
# subtracting the original genome array from the target image array
# then calculating the fitness
fitness[0,0] = fit(arr,circlesArr)
print "\n\n fitness of the first generation: \n\n", fitness[0,0]
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
for j in range(0,iter):
# mutating the order in which the circles are drawn
mutated = mutation(genomeArr)
print "\n\nThis is the mutation number ", j+1, "\n\n"
# mutating the position
mposition = position(mutated,width,height)
# mutating the radius
mrad = rad(mposition,height)
# mutating the color
mcolor = ccolor(mrad)
# mutating the transparency
mtrans = trans(mcolor)
# regenerating the circle image
mutatedCircles = generate(mtrans,work_surface.copy())
print "\n\n The mutated Circles number ", j+1
fitness[0,j+1] = fit(arr,mutatedCircles)
# saving the best fitness values and the corresponding arrays
if fitness[0,j+1] < 100:
bestFit.append(fitness[0,j+1])
bestMutation.append(mtrans)
if fitness[0,j+1] < fitness[0,j]:
genomeArr = mtrans
print "\n"
print "fitness array is:\n", fitness
fitnessSorted = numpy.sort(fitness)
print "\n"
print "The fitness sorted. The first element is the best fitness\n", fitnessSorted
print("\n --- %s seconds ---" % round(time.time() - start_time,2))
pygame.quit()
这是健身功能:
import numpy
def fit(array1,array2):
sub = numpy.subtract(array1,array2)
subAdd = 0.00
for i in range(0,512):
for j in range(0,512):
subAdd = (subAdd + float((sub[i,j])**2))
subAdd = subAdd/1000000.00
return subAdd