利用遗传算法的变异特征在python中用圆圈逼近目标图像

时间:2015-03-26 16:28:47

标签: python pygame genetic-algorithm

我试图将以下实验复制为我在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

0 个答案:

没有答案