Drawing a line:
var myDraw = Draw(200, 200, true);
var x1 = randomInteger(200);
var y1 = randomInteger(200);
var x2 = randomInteger(200);
var y2 = randomInteger(200);
myDraw.line(x1, y1, x2, y2);
Drawing many lines:
var myDraw = Draw(200, 200, true);
var makeLines = function(n, xs){
var x1 = randomInteger(200);
var y1 = randomInteger(200);
var x2 = randomInteger(200);
var y2 = randomInteger(200);
var xs2 = xs.concat([[x1, y1, x2, y2]]);
return (n==0) ? xs : makeLines(n-1, xs2);
}
var drawLines = function(lines){
var line = lines[0];
myDraw.line(line[0], line[1], line[2], line[3]);
if (lines.length > 1) {
drawLines(lines.slice(1));
}
}
var lines = makeLines(20, []);
drawLines(lines);
Loading images:
var myDraw1 = Draw(200, 200, true);
loadImage(myDraw1, "/assets/img/the_scream.jpg");
var myDraw2 = Draw(200, 200, true);
loadImage(myDraw2, "/assets/img/box.png");
Computing the pixel-by-pixel distance between two images:
var myDraw1 = Draw(200, 200, false);
loadImage(myDraw1, "/assets/img/the_scream.jpg");
var myDraw2 = Draw(200, 200, false);
loadImage(myDraw2, "/assets/img/box.png");
myDraw1.distance(myDraw2);
Target image:
var targetImage = Draw(50, 50, true);
loadImage(targetImage, "/assets/img/box.png")
Inferring lines that match the target image:
var targetImage = Draw(50, 50, false);
loadImage(targetImage, "/assets/img/box.png")
var drawLines = function(drawObj, lines){
var line = lines[0];
drawObj.line(line[0], line[1], line[2], line[3]);
if (lines.length > 1) {
drawLines(drawObj, lines.slice(1));
}
}
var makeLines = function(n, lines, prevScore){
// Add a random line to the set of lines
var x1 = randomInteger(50);
var y1 = randomInteger(50);
var x2 = randomInteger(50);
var y2 = randomInteger(50);
var newLines = lines.concat([[x1, y1, x2, y2]]);
// Compute image from set of lines
var generatedImage = Draw(50, 50, false);
drawLines(generatedImage, newLines);
// Factor prefers images that are close to target image
var newScore = -targetImage.distance(generatedImage)/1000; // Increase to 10000 to see more diverse samples
factor(newScore - prevScore);
generatedImage.destroy();
// Generate remaining lines (unless done)
return (n==1) ? newLines : makeLines(n-1, newLines, newScore);
}
Infer({
method: 'SMC',
particles: 100,
model() {
var lines = makeLines(4, [], 0);
var finalGeneratedImage = Draw(50, 50, true);
drawLines(finalGeneratedImage, lines);
}
})
'done'
Inference using MCMC and with a model that can manipulate opacity and stroke width:
///fold:
var targetImage = Draw(50, 50, false);
loadImage(targetImage, "/assets/img/box.png")
var uniformDraw = function(xs){
var i = randomInteger(xs.length);
return xs[i];
}
var drawLines = function(drawObj, lines){
var line = lines[0];
drawObj.line(line[0], line[1], line[2], line[3], line[4], line[5]);
if (lines.length > 1) {
drawLines(drawObj, lines.slice(1));
}
}
var randomStrokeWidth = function(){
var widths = [2, 4, 8, 16];
return uniformDraw(widths);
}
var randomOpacity = function(){
var opacities = [0, .5];
return uniformDraw(opacities);
}
var makeLines = function(n, lines){
var x1 = randomInteger(50);
var y1 = randomInteger(50);
var x2 = randomInteger(50);
var y2 = randomInteger(50);
var strokeWidth = randomStrokeWidth();
var opacity = randomOpacity();
var newLines = lines.concat([[x1, y1, x2, y2, strokeWidth, opacity]]);
return (n==1) ? newLines : makeLines(n-1, newLines);
}
var finalImgSampler = Infer({
method: 'MCMC',
samples: 500,
model() {
var lines = makeLines(4, []);
var finalGeneratedImage = Draw(50, 50, true);
drawLines(finalGeneratedImage, lines);
var newScore = -targetImage.distance(finalGeneratedImage)/1000; // Increase to 10000 to see more diverse samples
factor(newScore);
// print(newScore);
return lines
}
});
///
var finalImage = Draw(100, 100, false);
var finalLines = sample(finalImgSampler);
drawLines(finalImage, finalLines);
A more colorful target image:
var targetImage = Draw(50, 50, true);
loadImage(targetImage, "/assets/img/beach.png")
A richer image prior:
///fold:
var targetImage = Draw(50, 50, false);
loadImage(targetImage, "/assets/img/beach.png")
var uniformDraw = function(xs){
var i = randomInteger(xs.length);
return xs[i];
}
var drawLines = function(drawObj, lines){
var line = lines[0];
drawObj.line(line[0], line[1], line[2], line[3], line[4], line[5], line[6]);
if (lines.length > 1) {
drawLines(drawObj, lines.slice(1));
}
}
var randomStrokeWidth = function(){
var widths = [2, 4, 8, 16];
return uniformDraw(widths);
}
var randomOpacity = function(){
var opacities = [0, 0.2, .5];
return uniformDraw(opacities);
}
var _getRandomColor = function(i) {
if (i == 0){
return "";
} else {
// var letters = '0123456789ABCDEF'.split('');
var color = '#';
return uniformDraw('04AF') + _getRandomColor(i-1);
}
}
var randomColor = function(){
return "#" + _getRandomColor(6);
}
var makeLines = function(n, lines){
var x1 = randomInteger(50);
var y1 = randomInteger(50);
var x2 = randomInteger(50);
var y2 = y1;
var strokeWidth = randomStrokeWidth();
var opacity = randomOpacity();
var color = randomColor();
var newLines = lines.concat([[x1, y1, x2, y2, strokeWidth, opacity, color]]);
return (n==1) ? newLines : makeLines(n-1, newLines);
}
///
var counter = [];
Infer({
method: 'MCMC',
samples: 2500,
model() {
var lines = makeLines(8, []);
var showOutputImage = (counter.length % 100 == 0);
var finalGeneratedImage = Draw(50, 50, showOutputImage);
drawLines(finalGeneratedImage, lines);
var newScore = -targetImage.distance(finalGeneratedImage)/1000; // Increase to 10000 to see more diverse samples
factor(newScore);
if (!showOutputImage) {
finalGeneratedImage.destroy()
}
counter.push(1);
return lines
}
})
// show target image for comparison
loadImage(Draw(50, 50, true), "/assets/img/beach.png")