Sunday, 19 August 2012

Learning Scala - Photo collage creator

I finally took the time this summer to read a book on Scala. I bought Programming in Scala by Martin Odersky, the father of the language, which I think was a good choice. Regardless whether I'll write a lot of Scala programs in the future I learnt some new general programming techniques and a well needed recap on  programming language fundamentals from school. After reading it and applied it on a couple of hobby projects I must say that I feel excited.

My first project to play around with the language is a photo collage creator where you supply the program a motive and a set of images to create a collage from. The algorithm tries to puzzle the images together to create a collage that best fits the motive.

The motive to create collage from.
The motive is divided in segments and the image catalogue is searched for best fitting images to puzzle together.

The final collage in low-res.
When printing the collage in high resolution, for example 16384 x 10922 pixels the effect becomes quite cool when you approach the collage from a distance to a near closeup.

Let me just show you an arbitrary Scala function in this program that demonstrates a few of the things that I like compared to my daily work horse Java.

  /**
   * Calculate the average brightness of a portion of an image.
   * 
   * @param img Image to analyse for average brightness.
   * @param startx Start x coordinate of image subset to analyze 
   * @param starty Start y coordinate of image subset to analyze
   * @param stopx Stop x coordinate of image subset to analyze
   * @param stopy Stop y coordinate of image subset to analyze
   * @return Average brightness of the subset of the image
   */
  def brightness(img: BufferedImage, startx: Int, starty: Int, stopx: Int, stopy: Int): Int = {

    @tailrec
    def estimateBrightness(x: Int, y: Int, maxx: Int, maxy: Int, aggr: Int): Int = {
      if (y == maxy)
        aggr
      else if (x == maxx)
        estimateBrightness(startx, y + 1, maxx, maxy, aggr)
      else
        estimateBrightness(x + 1, y, maxx, maxy, aggr + rgb2gray(img.getRGB(x, y)))
    }
   
    /*
     * Average the brightness of the number of evaluated pixels with 
     * the aggregate of their calculated values.
     */
    val aggregatedBrightness = estimateBrightness(startx, starty, stopx, stopy, 0)
    aggregatedBrightness / ((stopx - startx) * (stopy - starty))
  }



As you can see, Scala is statically typed, but the compiler tries to infer as much as possible. You can create a constant variable with the val keyword. But it will in this example figure out that the variable aggregatedBrightness must be of the type (or subclass) Int since it is evaluated via the function estimateBrightness(). You will save yourself a lot of boilerplate declarations.

But what about the function estimateBrightness? It is declared inside the scope of the function brightness(). In Scala a function is on par with any plain old objects and can be referenced via variables or passed as arguments to functions and also be declared inside functions as a consequence. Why wouldn't it always be so?

Everything has a value, even a for loop or an if clause will result in something that can be passed to a variable or statement. This makes for concise and beautiful code.

Scala is basically a functional language but with all the imperative concepts around to make it easy for imperative people like me to make the transition to a more functional style in the tempo that suits me. In this example I made my calculations in a functional style using recursion instead of using loop constructs. I tried to write the program without any for or while loops at all but my conclusion is that just because it is nice to make everything recursive and functional it must not inherently be readable and understandable. I'll stick to my imperative guns when I need them for some time more.

An interesting annotation is @tailrec on the local function declaration. It forces the compiler to verify that this recursive function will be tail-call optimized, meaning that you can be sure that this function will not create stack frames for each invocation in the recusive loop. If so you would be running out of stack after some 10 000 invocations depending on your JVM startup flags.

To be able to write efficient and understandable functional programs my impression is that the requirements of the programmer are heightened compared to programming in plain old Java/C/C++. A challenge I'm gladly willing to continue with.

Instead of me trying to convince you that Scala seems like a great contribution to the Java VM family I strongly recommend you to read the book. You'll definitively become a better C# or Java programmer as well afterwards.



If you want to play around with the Photo Collage creator program and generate som collages of your own clone the code from GitHub.

https://github.com/johannoren/PhotoCollage

I have used Eclipse with the Scala plugin which make the program run without any hazzle. To configure it without any code changes, create a directory photos in the module, and put one image in that directory as your motive and name if motive.jpg. Put all your images that will be part of the puzzle in a subdirectory called inputphotos. Run PhotoCollage and monitor the standard out until the program is finished. Run time depends mainly on the number of images in the directory inputphotos.

Saturday, 4 August 2012

Raspberry Pi - how to get ssh and Tomcat running

Finally got my Raspberry Pi! The cheap $25/$35 board with 700Mhz ARM cpu, GPU, 256 mb RAM, dual USB, ethernet and a bunch of general purpose IO pins. Looking awesome in its bare metal and firing it up is no problem. I flashed an SD card with the Raspbian “wheezy” Linux distribution. To write the image to the SD card I used Win32DiskImager from a PC with SD card slot.

After attaching USB keyboard, network cable and HDMI  it comes to life by using a micro USB as power supply. The diods flashes and even X runs quite smooth on this limited hardware.

However, after playing around I soon realised I will be much more comfortable working on a distance from my ordinary desktop machine. So how to enable ssh?
A lot of tutorials talks about something as simple as this to enable ssh daemon on boot.
sudo mv /boot/boot_enable_ssh.rc /boot/boot.rc

Sorry, I have no such files in my /boot directory. Furthermore, when trying to start the ssh daemon with
/etc/init.d/ssh start
it refuses to start. Clues in the startup log are

Could not load host key: /etc/ssh/ssh_host_rsa_key Could not load host key: /etc/ssh/ssh_host_dsa_key

Why these are corrupt I don't know, but it's easy to regenerate them.

ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key

Make ssh daemon start permanent

sudo update-rc.d ssh defaults

sudo reboot and everything seems ok.

Now, my mission for tonight was to get a web server running on the chipset. Here's what you need to do to make Tomcat 7 run.

Tomcat obviously need Java:
sudo apt-get install openjdk-6-jdk

And you obviously need a potent editor
sudo apt-get install vim

Clean up your installs to save some space on the SD card
sudo apt-get clean

Now, download, unpack and install Tomcat
wget http://mirrors.axint.net/apache/tomcat/tomcat-7/v7.0.28/bin/apache-tomcat-7.0.28.tar.gz
tar xzf apache-tomcat-7.0.28.tar.gz
cd apache-tomcat-7.0.28/conf
vim tomcat-users.xml

Add a user to the authorization file, directly below <tomcat-users> add
<user username="system" password="raspberry" roles="manager-gui"/>

Now start Tomcat
cd ../bin
sudo sh startup.sh

Nice! From your PC (or via a browser on the Pi) surf against the Tomcat console.
http://192.168.1.90:8080/

(Figure out the ip address via for example ifconfig)

It takes a short while to warm up the server but then you can login via Manager App. Now, it's business as usual. Upload a war archive and you have a nifty web server running you web application, for $35!