Last active
March 5, 2023 20:54
-
-
Save heaversm/f5b168b0932c25ac3f2588f004b77dc7 to your computer and use it in GitHub Desktop.
Create animated transitions between StyleGAN images with P5.js and Runway ML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<script src="js/lib/p5.js"></script> | |
<script src="js/lib/p5.dom.js"></script> | |
<script src="js/lib/toxiclibs.js"></script> | |
<script src="data/landscape.js"></script> | |
<script src="js/stylegan-transition.js"></script> | |
</head> | |
<body> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// CODE ADAPTED FROM https://editor.p5js.org/codingtrain/sketches/K6l0JbS6u | |
// and https://editor.p5js.org/codingtrain/sketches/KVXguIFNg | |
// by the coding train / Daniel Shiffman (https://www.youtube.com/watch?v=QzRW0xzm10c&t=6622s) | |
let outputImage; | |
const n = []; | |
const imgSize = 512; //our image will be 512x512 pixels, which is what StyleGAN requires | |
//let amt = 0.0; //unused? | |
let angle = 0; | |
let count = 0; | |
function setup() { | |
createCanvas(imgSize, imgSize); | |
for (let i = 0; i < imgSize; i++) { | |
n[i] = new NoiseLoop(20, -1, 1); //diameter, min, max | |
} | |
generateImage(); | |
} | |
function generateImage() { | |
const path = "http://localhost:8000/query"; //the default path used by Runway / StyleGAN for receiving post requests | |
//a is loaded via the data js array and represents our initial starting vector / latent space image representation from which we sample to get random new images. | |
for (let i = 0; i < imgSize; i++) { //loop through all pixels, and select the corresponding value for the vector with the randomness generated from our Noise Loop function | |
a[i] = n[i].value(angle); | |
} | |
//amt += 0.05; //unused? | |
let da = TWO_PI / (24*60); //MH - not sure why these values are used (1440 = 360*4) | |
angle += da; | |
const data = { | |
z: a, //generated latent space vector | |
truncation: 0.5, //variation in image generations - higher is more random, lower is more similar | |
}; | |
httpPost(path, 'json', data, gotImage, gotError); | |
} | |
function gotError(error) { //if the generate image post request fails | |
console.error(error); | |
} | |
function gotImage(result) { //called once generate image has received a response | |
outputImage = createImg(result.image, imageReady); | |
outputImage.hide(); | |
} | |
function imageReady() { //saves the image | |
image(outputImage, 0, 0); | |
//save(`outputImage${nf(count, 4)}`); //nf formats numbers to strings //if you don't want to output to Runway, you can save the images straight from processing by uncommenting this line. | |
count++; | |
if (angle <= TWO_PI) { //once we have traversed all pixels, generated a new image | |
setTimeout(generateImage, 100); | |
} | |
} | |
class NoiseLoop { //introduces the randomness we need to generate images from the latent space | |
constructor(diameter, min, max) { | |
this.diameter = diameter; | |
this.min = min; | |
this.max = max; | |
this.cx = random(1000); | |
this.cy = random(1000); | |
} | |
value(a) { | |
let xoff = map(cos(a), -1, 1, this.cx, this.cx + this.diameter); | |
let yoff = map(sin(a), -1, 1, this.cy, this.cy + this.diameter); | |
let r = toxi.math.noise.simplexNoise.noise(xoff,yoff); //requires toxic libs library | |
return map(r, -1, 1, this.min, this.max); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment