Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality to resolve Issue #19 Image Saver #25

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ e = evolution.Evolution((64, 64), target, genes=256)

e.evolve(max_generation=50000)

helpers.show_image(e.specie.phenotype)
e.specie.show_img()

np.savetxt("Checkpoint.txt", e.specie.genotype)
cv2.imwrite("OuputImage.jpg", e.specie.phenotype)
e.specie.save_img("OutputImage.jpg")
```
# Contributing

Expand All @@ -74,3 +74,6 @@ Ahmed Khalf

Guilherme de Amorim
[guimorg](http://github.com/guimorg)

Tan Nian Wei
[tnwei](http://github.com/tnwei)
9 changes: 6 additions & 3 deletions circle_evolution/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@
e.evolve(max_generation=50000)

# Show evolved phenotype
helpers.show_image(e.specie.phenotype)
e.specie.show_img()

# Saves genotype to checkpoint
np.savetxt("Checkpoint.txt", e.specie.genotype)

# Saves phenotype
cv2.imwrite("OuputImage.jpg", e.specie.phenotype)
e.specie.save_img("OutputImage.jpg")

# Saves phenotype, resized
e.specie.save_img("OutputImage128x128.jpg", (128, 128))
```

Here is how to load and train further from a saved checkpoint.
Expand All @@ -89,7 +92,7 @@
e.evolve(max_generation=50000)

# Show evolved phenotype
helpers.show_image(e.specie.phenotype)
e.specie.show_img()
```

# Contributing
Expand Down
16 changes: 0 additions & 16 deletions circle_evolution/helpers.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
"""Helper Functions"""
import os

import cv2

import matplotlib.pyplot as plt


def load_target_image(image_path, color=True, size=None):
"""Loads images from image path.

Expand Down Expand Up @@ -39,15 +35,3 @@ def load_target_image(image_path, color=True, size=None):
# Only resizes image if it is needed!
target = cv2.resize(src=target, dsize=size, interpolation=cv2.INTER_AREA)
return target


def show_image(img_arr):
"""Displays image on window.

Arguments:
img_arr (numpy.ndarray): image array to be displayed
"""
plt.figure()
plt.axis("off")
plt.imshow(img_arr / 255)
plt.show()
2 changes: 1 addition & 1 deletion circle_evolution/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def main():
evolution.evolve(max_generation=args.max_generations)

evolution.specie.render()
helpers.show_image(evolution.specie.phenotype)
evolution.specie.show_img()

output_path_checkpoint = "checkpoint-{}.txt".format(evolution.generation)
np.savetxt(output_path_checkpoint, evolution.specie.genotype)
Expand Down
36 changes: 35 additions & 1 deletion circle_evolution/species.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

import cv2

from PIL import Image
import numpy as np


Expand Down Expand Up @@ -87,3 +87,37 @@ def load_checkpoint(self, fname, text=False):
self.genotype = np.loadtxt(fname)
else:
self.genotype = np.load(fname)

def show_img(self, resolution=None):
"""
Displays image of phenotype.

Args:
resolution (tuple): (height, width) of target image.
If None, uses target image resolution. Defaults to None.
"""
im = Image.fromarray(self.phenotype.astype("uint8"))

if resolution is None:
im.show()
else:
im_resized = im.resize(resolution)
im_resized.show()

def save_img(self, fname, resolution=None):
"""
Saves image of phenotype.

Args:
fname (string): Filename to save the image to. Includes format postfix, e.g. `jpg` or `png`.
resolution (tuple): (height, width) of target image.
If None, uses target image resolution. Defaults to None.
"""
im = Image.fromarray(self.phenotype.astype("uint8"))

if resolution is None:
im.save(fname)
else:
im_resized = im.resize(resolution)
im_resized.save(fname)

54 changes: 25 additions & 29 deletions docs/evolution.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.8.1" />
<meta name="generator" content="pdoc 0.9.1" />
<title>circle_evolution.evolution API documentation</title>
<meta name="description" content="Responsible for evolving a specie to look like target image." />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
Expand Down Expand Up @@ -43,22 +45,21 @@ <h1 class="title">Module <code>circle_evolution.evolution</code></h1>
a target image.

Attributes:
size (tuple): tuple containing height and width of target image (h, w).
size (tuple): tuple containing np.shape of target image.
target (np.ndarray): target image for evolution.
genes (int): the amount of circle to train the target image on.
generation (int): amount of generations Evolution class has trained.
specie (species.Specie): the Specie that is getting trained.
&#34;&#34;&#34;

def __init__(self, size, target, genes=5):
def __init__(self, target, genes=100):
&#34;&#34;&#34;Initializes Evolution class.

Args:
size (tuple): tuple containing height and width of target image (h, w).
target (np.ndarray): target image for evolution.
genes (int): the amount of circle to train the target image on.
&#34;&#34;&#34;
self.size = size # Tuple (y, x)
self.size = target.shape
self.target = target # Target Image
self.generation = 1
self.genes = genes
Expand All @@ -78,16 +79,16 @@ <h1 class="title">Module <code>circle_evolution.evolution</code></h1>

# Randomization for Evolution
y = random.randint(0, self.genes - 1)
change = random.randint(0, 6)
change = random.randint(0, new_specie.genotype_width + 1)

if change &gt;= 6:
if change &gt;= new_specie.genotype_width + 1:
change -= 1
i, j = y, random.randint(0, self.genes - 1)
i, j, s = (i, j, -1) if i &lt; j else (j, i, 1)
new_specie.genotype[i : j + 1] = np.roll(new_specie.genotype[i : j + 1], shift=s, axis=0)
y = j

selection = np.random.choice(5, size=change, replace=False)
selection = np.random.choice(new_specie.genotype_width, size=change, replace=False)

if random.random() &lt; 0.25:
new_specie.genotype[y, selection] = np.random.rand(len(selection))
Expand Down Expand Up @@ -143,7 +144,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="circle_evolution.evolution.Evolution"><code class="flex name class">
<span>class <span class="ident">Evolution</span></span>
<span>(</span><span>size, target, genes=5)</span>
<span>(</span><span>target, genes=100)</span>
</code></dt>
<dd>
<div class="desc"><p>Logic for a Species Evolution.</p>
Expand All @@ -152,7 +153,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>size</code></strong> :&ensp;<code>tuple</code></dt>
<dd>tuple containing height and width of target image (h, w).</dd>
<dd>tuple containing np.shape of target image.</dd>
<dt><strong><code>target</code></strong> :&ensp;<code>np.ndarray</code></dt>
<dd>target image for evolution.</dd>
<dt><strong><code>genes</code></strong> :&ensp;<code>int</code></dt>
Expand All @@ -165,8 +166,6 @@ <h2 id="attributes">Attributes</h2>
<p>Initializes Evolution class.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>size</code></strong> :&ensp;<code>tuple</code></dt>
<dd>tuple containing height and width of target image (h, w).</dd>
<dt><strong><code>target</code></strong> :&ensp;<code>np.ndarray</code></dt>
<dd>target image for evolution.</dd>
<dt><strong><code>genes</code></strong> :&ensp;<code>int</code></dt>
Expand All @@ -183,22 +182,21 @@ <h2 id="args">Args</h2>
a target image.

Attributes:
size (tuple): tuple containing height and width of target image (h, w).
size (tuple): tuple containing np.shape of target image.
target (np.ndarray): target image for evolution.
genes (int): the amount of circle to train the target image on.
generation (int): amount of generations Evolution class has trained.
specie (species.Specie): the Specie that is getting trained.
&#34;&#34;&#34;

def __init__(self, size, target, genes=5):
def __init__(self, target, genes=100):
&#34;&#34;&#34;Initializes Evolution class.

Args:
size (tuple): tuple containing height and width of target image (h, w).
target (np.ndarray): target image for evolution.
genes (int): the amount of circle to train the target image on.
&#34;&#34;&#34;
self.size = size # Tuple (y, x)
self.size = target.shape
self.target = target # Target Image
self.generation = 1
self.genes = genes
Expand All @@ -218,16 +216,16 @@ <h2 id="args">Args</h2>

# Randomization for Evolution
y = random.randint(0, self.genes - 1)
change = random.randint(0, 6)
change = random.randint(0, new_specie.genotype_width + 1)

if change &gt;= 6:
if change &gt;= new_specie.genotype_width + 1:
change -= 1
i, j = y, random.randint(0, self.genes - 1)
i, j, s = (i, j, -1) if i &lt; j else (j, i, 1)
new_specie.genotype[i : j + 1] = np.roll(new_specie.genotype[i : j + 1], shift=s, axis=0)
y = j

selection = np.random.choice(5, size=change, replace=False)
selection = np.random.choice(new_specie.genotype_width, size=change, replace=False)

if random.random() &lt; 0.25:
new_specie.genotype[y, selection] = np.random.rand(len(selection))
Expand Down Expand Up @@ -346,16 +344,16 @@ <h2 id="returns">Returns</h2>

# Randomization for Evolution
y = random.randint(0, self.genes - 1)
change = random.randint(0, 6)
change = random.randint(0, new_specie.genotype_width + 1)

if change &gt;= 6:
if change &gt;= new_specie.genotype_width + 1:
change -= 1
i, j = y, random.randint(0, self.genes - 1)
i, j, s = (i, j, -1) if i &lt; j else (j, i, 1)
new_specie.genotype[i : j + 1] = np.roll(new_specie.genotype[i : j + 1], shift=s, axis=0)
y = j

selection = np.random.choice(5, size=change, replace=False)
selection = np.random.choice(new_specie.genotype_width, size=change, replace=False)

if random.random() &lt; 0.25:
new_specie.genotype[y, selection] = np.random.rand(len(selection))
Expand Down Expand Up @@ -421,9 +419,7 @@ <h4><code><a title="circle_evolution.evolution.Evolution" href="#circle_evolutio
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.8.1</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.9.1</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>
Loading