Dreaming a Deep Dream of the Muybridge's Horse

Posted on Mon 06 July 2015 in fun • Tagged with animation, deep, pythonLeave a comment

So here's a short post. Google recently released their code from that really interesting work entitled Inceptionism: Going Deeper into Neural Networks. Their code is available on github.

What I did here is just that I took all the frames from that horse running gif which I used in one of my previous posts, ran each frame through Google's Deep Dream code and then stitched them back together to create a new gif.

The result is very nice and you can see it below:
Whoa!

Fun, fun, fun!!

I might try to make some more of these in the next couple of days. :)


Playing around with .pdf files

Posted on Mon 26 January 2015 in Code snippetsLeave a comment

Here's a bunch of commands that I found useful when working with .pdf files.

1. How to convert an image into a .pdf file?

Install imagemagick:

sudo apt-get install imagemagick

Convert the image:

convert image.jpg output.pdf

2. How to concatenate multiple .pdf files into one .pdf file?

Install pdftk:

sudo apt-get install pdftk

Run:

pdftk p1.pdf p2.pdf p3.pdf p4.pdf p5.pdf output all_pages.pdf

Or, if you have all the files in one directory, you could do

pdftk *.pdf output all_pages.pdf

3. How to rotate all the pages in a .pdf file 90 degrees counterclockwise?

pdftk input.pdf cat 1-endW output rotatedW.pdf

If you want to rotate clockwise:

pdftk input.pdf cat 1-endE output rotatedE.pdf

4. How to set the size of the .pdf file to A4?

Install ghostscript:

sudo apt-get install ghostscript

Run:

gs -o resized_a4.pdf -sDEVICE=pdfwrite -sPAPERSIZE=a4 -dFIXEDMEDIA \ -dPDFFitPage -dCompatibilityLevel=1.4 input.pdf

5. How to convert a colour .pdf file into a greyscale one?

gs -sDEVICE=pdfwrite -dNOPAUSE -dQUIET \ -dBATCH -sColorConversionStrategy=Gray \ -dProcessColorModel=/DeviceGray \ -sOutputFile="output_greyscale.pdf" "input_coloured.pdf"

That's it for now!


Drawing images consisting of all possible RGB colours!

Posted on Sat 22 November 2014 in fun • Tagged with animation, image, python, videoLeave a comment

This is also an old, but fun project I did 8 months ago, inspired by the video that József Fejes posted on his blog in March: All RGB colors in one image. It was part of the challenge posted here, where people had to write code that makes colorful images. Fun, fun, fun!

The challenge has already finished when I saw it, but anyway, it sounded interesting and I wanted to see what I can come up with.

A bit about colours

There's a lot of colours out there! If you look into one pixel on your screen and concentrate really really hard, you will notice that it can (probably) display $16777216$ different colours! Here we are talking about $24$-bit colours, where each one is represented as a combination of red ($8$ bits), green ($8$ bits) and blue ($8$ bits) colours. $8$ bits can take $256$ different values, so $256 \times 256 \times 256 = 16777216$. And that's a lot! If you wore a different coloured shirt every minute, it would take you almost $32$ years to wear all of the possible $24$-bit RGB colours. I know you wanted to know that.

The result was colorful!

Below you can see what I got in the end.
Colours final!

In this case the image was $640\times480px$, which means it only contained $307200$ different colours, that is, only around $1.831054687\%$ of all possible $24$-bit RGB colours. OHNOES!

Make it bigger!

The next generated image was a bit bigger. It was $1088\times1920px$ big, containing $2088960$ different colours, which is around $12.451171875\%$ of all the colours we wanted to use.

Click to see it bigger!
Colours final!

That's better. Why $1088$ you ask? Because the implementation was a quick hack and required the dimensions to be divisible by $16$. That's what you get when you want to see the results as quickly as possible. But you know what's cool? Each colour in that image is used only once and it would take you almost $4$ years to wear shirts in all of those colours if you wore each one only for a minute!

A video would be even more colorful!

The next obvious thing that needed to be done was a video of how this image was generated. Here are four frames from the first image shown in this post being generated:

Colours 30000! Colours 100000!

Colours 170000! Colours 230000!

Having limited time, I decided that $12.451171875$ is roughly equal to $100$ and that a HD video will be enough to call this project done. So, a frame was saved after generating every so many pixels of the $1088\times1090px$ image, the frames were turned into a video and it was uploaded to YouTube to live there happily ever after.

The end?

Enter savfk!

It wasn't the end! After uploading the video on YouTube, my colleague Saverio messaged me and said:

I did a 2:30 thingy on purpose for your colour stuff!

Turns out he makes music (which I didn't know) and he made real music for the crazy colour snake video!! The music fit perfectly and the result can be seen below.

Now the project was finally complete! Yay!

If you want to see other videos of the images being generated, here's a few (but without music): a small one, the 640x480px version, the 3 and a half hour long version and the

HD version.

But, but, all of the colours??

Yes, it will work with all of the colours if you have the time to generate the frames. That's why I'm providing the code below!

Code

It's written in python and is again not cleaned up because I'm too lazy to do that. If you want to use it to generate an image really using all of the colours, the dimensions of it should be for example $4096\times4096px$. Just set the height and width variables to $256$, and that should work. It could also not work, I don't know, this was written a long time ago. :P

And I forgot to mention how it actually works! For the traversing part, it is just a randomized DFS algorithm. Every time when a pixel get visited, a colour is chosen randomly and it is used if it is less than a certain distance (Euclidean distance in RGB space) from the previously used colour. If it isn't, another colour gets chosen randomly. If after a number of random choices the colour still isn't less than the threshold distance from the previous colour, then the threshold gets increased. And that's it! Magic!

Oh, and BTW, you should have a folder called generated where all the images will get saved to.

colours.py download
import cv2
import numpy as np
import math
import random
from sets import Set
  
dr = [-1, -1, -1, 0, 0, 1, 1, 1]
dc = [-1, 0, 1, -1, 1, -1, 0, 1]
  
height = 68 #1080/16
width = 120 #1920/16
  
field = np.zeros((height * 16, width * 16, 3), dtype = "uint8")
visited = np.zeros((height * 16, width * 16), dtype = "bool")
  
total_colours = 0
colours = []
  
def distance(c1, c2):
    return math.sqrt((c1[0] - c2[0]) * (c1[0] - c2[0]) +
                     (c1[1] - c2[1]) * (c1[1] - c2[1]) +
                     (c1[2] - c2[2]) * (c1[2] - c2[2]))
  
  
def fill(queue, prev_colour):
      
    while (len(queue) > 0):
  
        current_point = queue.pop(0)
  
        rand_it =  list(range(len(dr)))
        random.shuffle(rand_it)
  
        for i in xrange(len(dr)):
            r = current_point[0] + dr[rand_it[i]]
            c = current_point[1] + dc[rand_it[i]]
  
            if (r < 0 or r >= field.shape[0]):
                continue
              
            if (c < 0 or c >= field.shape[1]):
                continue
  
            if (visited[r, c]):
                continue
  
            if ((r,c) in queue):
                continue
  
            queue.insert(0, (r, c))
  
        r = current_point[0]
        c = current_point[1]
  
        field[r, c, 0] = prev_colour[0]
        field[r, c, 1] = prev_colour[1]
        field[r, c, 2] = prev_colour[2]
  
        visited[r, c] = True
  
        print len(colours)
  
        colours.remove(prev_colour)
        if (len(colours) > 0):
            next_colour = colours[random.randint(0, len(colours) - 1)]
              
            tries = 0
  
            min_dist = 30
  
            while (distance(prev_colour, next_colour) > min_dist):
                next_colour = colours[random.randint(0, len(colours) - 1)]
                tries += 1
  
                if (tries > 0.1 * len(colours)):
                    min_dist += 0.1
  
            prev_colour = next_colour
  
        cv2.imwrite("generated/img_" + str((total_colours - len(colours))).zfill(10) + ".png", field)
  
cv2.namedWindow("field", flags = cv2.cv.CV_WINDOW_NORMAL)
  
for r in xrange(16):
    for c in xrange(16):
        for i in xrange(height):
            for j in xrange(width):
                colours.append((int((float(r * 16 + c) / 256) * 255),
                                int((float(i) / height) * 255),
                                int((float(j) / width) * 255)))
      
  
    print r, "/", 16
  
total_colours = len(colours)
  
prev_colour = colours[random.randint(0, len(colours))]
  
current_point = (random.randint(0, field.shape[0]),
                 random.randint(0, field.shape[1]))
  
queue = []
  
queue.append(current_point)
  
fill(queue, prev_colour)
  
cv2.imshow("field", field)
cv2.waitKey(0)

The code is also available on github.

Thanks for scrolling through!