Creating a Globe of Data (revisited for Programming Historian Second Edition)

Module Goals

After seeing the basics of Python and how it could help us in our daily work, we will introduce one of the many options for visualization of data. In this case, we will combine a data source in CSV format that will be processed to transform them into JSON notation. Finally we will represent all the information in a world globe, designed for modern browsers using the WebGL technology. During the process, we will need to get the spatial coordinates for countries across the world. And before starting, you can see the final result of this unit on World Poverty, so don’t be afraid about all the new names mentioned above, we will explain them below.

The Globe of Data

Since the ending of 2009, some browsers started to implement an incipient specification for rendering 3D content on the Web. Although it is not yet a part of W3C‘s specifications –the W3C is the organization that proposes, defines and approves almost all Internet standards–, WebGL, that it is how is called, is being supported by all major browsers and the industry.

WebGL is the most recent way for 3D representations on the Web. So, with WebGL, a new form of data representation is made available. In fact, there are artists, scientists, game designers, statisticians and so on, creating amazing visualizations from their data.

Google WebGL Globe

Google WebGL Globe

One of these new ways of representations was made by Google. It is called WebGL Globe and allows to show statistical geo-located data.

JSON & World Coordinates

JSON, acronym for JavaScript Object Notation, is not only a format to represent data in Javascript, the language of the browsers. It is also the data type that WebGL Globe needs to work. In this format, a list is inclosed between brackets, “[" for start and "]” to end. Therefore, the data series for WebGL Globe is a list of lists. Every one of these lists have two elements. The first one is the name of the serie and the second one is another list containing the data. Although is good to know how JSON lists are encoded, there are libraries for Python to do that conversion for you, so you only have to handle pure Python objects.

>>> import json

>>> json.dumps([1, 2, 3])
    '[1, 2, 3]'

>>> json.dumps({"key1": "val1", "key2": "val2"})
    '{"key2": "val2", "key1": "val1"}'

The data for WebGL Globe is written comma separated, so you must indicate your information in a set of three elements: the first is the geographical coordinate for latitude, the second one is the same for longitude, and the third one is the value of the magnitude you would like to represent, but normalized between 0 and 1. This means if we have the values 10, 50, 100 for magnitudes, these will have to be translated into 0.1, 0.5 and 1.

Birefly, “A geographic coordinate system is a coordinate system that enables every location on the Earth to be specified by a set of numbers.” These numbers are often chosen to represent the vertical position and horizontal position of a point in the globe (more precisely is even possible add the elevation). They are commonly referred to angles from equatorioal plane, but as far as we are concerned those angles can be transform into a couple of single numbers with several decimals places

Latitude and Longitude of the Earth (Source: Wikipedia.org)

Latitude and Longitude of the Earth (Source: Wikipedia.org)

The only thing you now need is to split up your data into several series of latitude, longitude and magnitude in JSON format, as the next example illustrates:

var data = [
  [
    'seriesA', [ latitude, longitude, magnitude, latitude, longitude, magnitude, ... ]
  ],
  [
    'seriesB', [ latitude, longitude, magnitude, latitude, longitude, magnitude, ... ]
  ]
];

This said, we can write the data for our globe in pure Python and then apply a conversion into JSON.

>>> data = [
 ...: "seriesA", [34.56, -5.23, 0.89, 27.78, 10.56, 0.12, ...],
 ...: "seriesB", [34.56, -5.23, 0.89, 27.78, 10.56, 0.12, ...],
 ...: ...
 ...: ]

>>> json.dumps(data)
'["seriesA", [34.56, -5.23, 0.89, 27.78, 10.56, 0.12, ...], "seriesB", [34.56, -5.23, 0.89, 27.78, 10.56, 0.12, ...]] ...'

The Data Set

Let’s say we want to represent information from the Human Poverty Index. The first we need is to download the data in the format provided by United Nations’ site for the Multidimensional Poverty Index, that has replaced the old Human Poverty Index. Now we got a spreadsheet document, it’s time to open it and collect just the data we need, thus, go to the page 5 of the book, and copy and paste the cells into a clean spreadsheet. We clean all the date we don’t need like titles, captions, extra columns, etc and we leave just country names, the second “Value” column under the cell “Multidimensional Poverty Index”, the population under poverty in thousands, and the “Intensity of deprivation” column. The next step is to remove the rows with no data for that indicators, marked as “..”. After doing this, we should have a document with 4 columns and 109 rows.

Spreadsheet before getting coordinates for countries

Spreadsheet before getting coordinates for countries

But, although we have the name of the countries, we need the geographical coordinates for them. There are several services that provide the latitude and longitude for a given address. In the case of having just the name of a country, the main coordinates for the capital is provided. We will use geopy, which is a Python library able to connect to different providers and get several kinds of information. To use geopy, a terminal or console is needed in order to get installed, that is very easy with just a command.

$ easy_install geopy

After that, we can open a terminal or interfactive console like iPython and just get the latitude and longitude of, for instance, “Spain”, with next commands:

>>> from geopy import geocoders

>>> g = geocoders.Google()

>>> g.geocode("Spain")
(u'Spain', (40.463667000000001, -3.7492200000000002))

In this way, we can build a list of our countries and pass it to the next script:

>>> from geopy import geocoders

>>> g = geocoders.Google()

>>> countries = ["Slovenia", "Czech Republic", ...]
>>> for country in countries:
try:
    placemark = g.geocode(country)
    print placemark[0] +","+ placemark[1][0] +","+ placemark[1][1]
except:
    print country
....:
....:
Slovenia,46.151241,14.995463
Czech Republic,49.817492,15.472962
United Arab Emirates,23.424076,53.847818
...

Now, we can select all the results corresponding to the latitudes and longitudes of every country and copy them with Ctrl-C or mouse right-click and copy. Go to our spreadsheet, in the first row of a new column, and then paste all. We should see a dialogue for paste the data, and on it, check the right option in order to get the values separated by commas.

Paste the result comma separated

Paste the result comma separated

Done this, we have almost all the coordinates for all the countries. Anyway, there could be some locations for which the script didn’t get the right coordinates, like “Moldova (Republic of)” or “Georgia”. For these countries, and after a carefull supervision, the better thing to do is to run several tries fixing the names (trying “Moldova” instead of “Moldova (Republic of)”) or just looking the location in Wikipedia –for example for Georgia, Wikipedia provides a link in the information box at the right side with the exact coordinates. When the process is over, we remove the columns with the names and sort the columns in order to get first the latitude, second the longitude, and the rest of the columns after that. We almost have the data prepared. After this, we need to save the spreadsheet as CSV file in order to be processed by a Python script that converts it into the JSON format that WebGL Globe is able to handle.

Reading CSV Files

A CSV file is a data format for printing tables intoto plain-text data. There are a plenty of dialects for CSV, but the most common is to print onw row per line and every field comma separated. For example, the next table will have the output shown in below.

Field 1 Field 2
Row 1 Value Cell 1 Row 1 Value Field 2
Row 2 Value Cell 1 Row 2 Value Field 2

And the output will be:

Field 1,Field 2
Row 1 Value Cell 1,Row 1 Value Cell 2
Row 2 Value Cell 1,Row 2 Value Cell 2

And depending on the case, you can choose what character will be used as a separator insted of the “,”, or just leave the header out. But what happens if I need to print commas? Well, you can escape then or just use a double quote for the entire value.

"Row 1, Value Cell 1","Row 1, Value Cell 2"
"Row 2, Value Cell 1","Row 2, Value Cell 2"

And again you can think what is next if I need to print double quotes. In that case can change the character for quoting or just escape with a slash. This is the origin of all the dialects for CSV. However we are not covering this that deep and we will focus on CSV reading through Python. To achieve it we use the standard  ”csv”  library and invoke the “reader” method with a file object after opening it from disk. This done, we can just iterate for every line as a list and store every value in a variable for the iteration.

 

In our case every line has, in this order, latitude, longitude, value for multidimensional poverty index, value for thousands of people in a poverty situation, and finally value for the intensity of deprivation. Note that our CSV file has no header, so we do not have to ignore de first line then. We will use three lists to store the different vales of our series and finally, using the

json

library we could print a JSON output to a file. The script that processes the CSV file and produces the JSON output is the detailed the next:

import csv
lines = csv.reader(open("poverty.csv", "rb"))
mpis = []  # Multidimensional Poverty Index
thousands = []  # People, in thousands, in a poverty situation
deprivations = []  # Intensity of Deprivation
for lat, lon, mpi, thousand, deprivation in lines:
    mpis = mpi + (lat, lon, mpi)
    thousands = thousands + (lat, lon, thousand)
    deprivations = deprivation + (lat, lon, deprivation)
output = [
    ["Multidimensional Poverty Index", mpis],
    ["People affected (in thousands)", thousands],
    ["Intensity of Deprivation", deprivations]
]
print json.dumps(output)

And the output must look like:

[
["Multidimensional Poverty Index", ["46.151241", "14.995463", "0", ... ]
...

Putting it all together

Now, if we copy that output into a file called poverty.json we will have our input data for WebGL Globe. So, the last step is setup the Globe and and the data input file all toghether. We need to download the webgl-globe.zip file and extract the directory named as “globe”  into a directory with the same name. In it, we copy our poverty.json file and now edit the index.html in order to replace the apparitions of “population909500.json” with “poverty.json”, and do some other additions like the name of the series. Finally, to see the result, you can put all the files in a static web server and browse the URL. Another option, just for local debugging, is run the next command under the directory itself:

$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

And then, go to http://localhost:8000 to see the result.

Globe before normalization

Globe before normalization

It seems like there is something wrong with two of the series: the population in poverty conditions, and the intensity of the poverty. This is because we need to normalize the values in order to get values in the range o to 1. To do that, we open again our CSV file as a spreadsheet, calculate the sum of the columns that we want to normalize, and then, we create a new column in which every single cell is the result of the division of the old value of cell by the total sum of all the values in the old column, We repeat the proccess with the another column and replace the old ones with just the values in the new ones. Now, we can run the steps of generate the JSON file and try again.

Now, you can click on World Poverty to see everything properly woriking.

Suggested Readings

The Python Standard Library Documentation

Lutz, Learning Python

  • Ch. 9: Tuples, Files, and Everything Else

Leave a Comment

Filed under Topics

Final Post: Gamex and Faces in Baroque Paintings

Face recognition algorithms (used in digital cameras) allowed us to detect faces in paintings. This has gave us the possibility of having a collection of faces of a particular epoch (in this case, the baroque). However, the results of the algorithms are not perfect when applied in paintings instead of pictures. Gamex gives the chance to clean this collection. This is very important since these paintings are the only historical visual inheritance we have from the period. A period that started after the meet of two worlds.

1. Description

Gamex was born from the merging of different ideas we had at the very beginning of the Interactive Exhibit Design course. It basically combines motion detection, face recognition and games to produce an interactive exhibit of Baroque paintings. The user is going to interact with the game by touching, or more properly poking, faces, eyes, ears, noses, mouths and throats of the characters of the painting. We will be scoring him if there is or there is not a face already recognized on those points. Previously, the database has a repository with all the information the faces recognition algorithms have detected. With this idea, we will be able to clean mistakes that the automatic face recognition has introduced.

The Gamex Set

The Gamex Set

2. The Architecture

A Tentative Architecture for Gamex explains the general architecture in more detail. Basically we have four physical components:

  • A screen. Built with a wood frame and elastic-stretch fabric where the images are going to be projected from the back and where the user is going to interact poking them.
  • The projector. Just to project the image from the back to the screen (rear screen projetion).
  • Microsoft Kinect. It is going to capture the deformations on the fabric and send them to the computer.
  • Computer. Captures the deformations send by the Kinect device and translates them to touch events (similar to mouse clicks). These events are used in a game to mark on different parts of the face of people from baroque paintings. All the information is stored in a database and we are going to use it to refine a previously calculated set of faces obtained through face recognition algorithms.

3. The Technology

There were several important pieces of technology that were involved in this project.

Face Recognition

Recent technologies offers us the possibility of recognizing objects in digital images. In this case, we were interested in recognizing faces. To achieve that, we used the libraries OpenCV and SimpleCV. The second one just allowed us to use OpenCV with Python, the glue of our project. There are several posts in which we explain a bit more the details of this technology and how we used.

Multi Touch Screen

One of the biggest part of our work involved working with multi-touch screens. Probably because it is still a very new technology where things haven’t set down that much we have several problems but fortunately we managed to solved them all. The idea is to have a rear screen projection using the Microsoft Kinect. Initially though for video-game system Microsoft Xbox 360, there is a lot of people creating hacks (such as Simple Kinect Touch) to take advantage of the abilities of this artifact to capture deepness. Using two infrared lights and arithmetic, this device is able to capture the distance from the Kinect to the objects in front of it. It basically returns an image, in which each pixel is the deepness of the object to the Kinect. All sorts of magic tricks could be performed, from recognizing gestures of faces to deformations in a piece of sheet. This last idea is the hearth of our project. Again, some of the posts explaining how and how do not use this technology.

Calibrating the multi-touch screen

Calibrating the multi-touch screen

Games

Last but not least, Kivy. Kivy is an open source framework for the development of applications that make use of innovative user interfaces, such as multi-touch applications. So, it fits to our purposes. As programmers, we have developed interfaces in many different types of platforms, such as Java, Microsoft Visual, Python, C++ and HTML. We discovered Kivy being very different from anything we knew before. After struggling for two or three weeks we came with our interface. The real thing about Kivy is that they use a very different approach which, apart from having their own language, the developers claim to be very efficient. At the very end, we started to liked and to be fair it has just one year out there so it will probably improve a lot. Finally, it has the advantage that it is straightforward to have a version for Android and iOS devices.

4. Learning

There has been a lot of personal learning in this project. We never used before the three main technologies used for this project. Also we included a relatively new NoSQL database system called MongoDB. So that makes four different technologies. However, Javier and me agree that one of the most difficult part was building up the frame. We tried several approaches: from using my loft bed as a frame to a monster big frame (with massive pieces of wood carried from downtown to the university in my bike) that the psyco duck would bring down with the movement of the wings.

It is also interesting how ideas changes over the time, some of them we probably forgot. Others, we tried and didn’t work as expected. Most of them changed a little bit but the spirit of our initial concept is in our project. I guess creative process is a long way between a driven idea and the hacks to get to it.

5. The Exhibition

Technology fails on the big day and the day of the presentation we couldn’t get our video but there is the ThatCamp coming soon. A new opportunity to see users in action. So the video of the final result, although not puclib yet, is attached here. It will come more soon!

6. Future Work

This has been a long post but there is still a few more things to say. And probably much more in the future. We liked the idea so much that we are continuing working on this and we liked to mention some ideas that need to be polished and some pending work:

  • Score of the game. We want to build a better system for scores. Our main problem is that the data that we have to score is incomplete and imperfect (who has always the right answers anyway). We want to give a fair solution to this. Our idea is to work with fuzzy logic to lessen the damage in case the computer is not right.
  • Graphics. We need to improve our icons. We consider some of them very cheesy and needs to be refined. Also, we would like to adapt the size of the icon to the size of the face the computer already recognized, so the image would be adjusted almost perfectly.
  • Sounds.  A nice improvement but also a lot of work to have a good collection of midi or MP3 files if we don’t find any publicly available.
  • Mobile versions. Since Kivy offers this possibility, it would be silly not to take advantage of this. At the end, we know addictive games are the key to entertain people on buses. This will convert the application in a real crowd sourcing project. Even if this implies to build a better system for storing the information fllowing the REST principles with OAuth and API keys.
  • Cleaning the collection. Finally, after having enough data it would be the right time to collect the faces and have the first repository of “The Baroque Face”. This will give us an spectrum of how does the people of the XVI to XVIII looked like. Exciting, ¿isn’t it?
  • Visualizations. Also we will be able to do some interesting visualizations, like heat maps where the people did touch for being a mouth, or an ear, or a head.

6. Conclusions

In conclusion we can say that the experience has been awesome. Even better than that was to see the really high level of our classmates’ projects. In the honour of the truth, we must say that we have a background in Computer Science and we played somehow with a little bit more of adventage. Anyway, it was an amazing experience the presentation of all the projects. We really liked the course and we recommend to future students. Let’s see what future has prepared for Gamex!

Some of the very interesting projects

Some of the projects

This post was written and edited together to my classmate Roberto. So you can also find the post on his blog.

3 Comments

Filed under Analysis, Tasks

Building the proper screen

The last step in the project, after we were able to overcome all the technical difficulties like Kivy language, was the building of the a suitable screen for our purposes, this is a poke-able rear screen. Doing this we avoid the problem of calibrating the Kinect device each time and for each user, and foremost we could do the setup just once.

The first attempt of a rear screen

The first attempt of a rear screen

Our first attempt was building a very big frame and using a table cover or bed sheet as the screen. But we found several serious problems:

  1. The frame was too big for moving.
  2. The frame wasn’t rigif enough and with the interaction of the users it got deformation.
  3. The screen, after an user interaction, never got back to normal and keept deformed forever.

Among all the problems (and others just not commented here), the last one was totally frustrating, because all the platform depends on the stability of the screen. If the screen is not just plain, Kinect will detect that, and it will translate points to the Kivy application when there is no one actually. Everything was wrong.

Choosing the most beautiful tissue

Choosing the most beautiful tissue

The alternative was to use a stretch fabric with the capacity to recover the initial shape after any, virtually, number of interactions. Even with hard punchs. But we didn’t know where to buy that or if it was even cheap enough for our students’ pockets. Fortunatelly, Prof. William Turkel recommend us Fabric Land, with three locations in the city and a lot of options for fabrics. I must say that the place was a bit weird for me, with a bunch of middle age ladies looking for good materials. I felt like Mrs. Doubtfire there. Finally one girl, very gentile, young and nice, helped us to find what we wanted, and she sold us at the price of $5 per meter!

Colours pins! That's the most decorative we can be

Colours pins! That's the most decorative we can be

And with all the raw material ready, we got down to work and we built, after several tries, the proper rear and stretch screen. Just in the first test we discovered that accuracy was amazing. And the most interesting thing: somehow, the fact that the screen is elastic, demands interaction from the users and keeps the people playing. So, we can say mission accomplished!

2 Comments

Filed under Tasks

A Tentative Architecture for Gamex

The other day, during the weekly class, I just realized there is no document explaining the architecture of our project. Roberto and I have been talking a lot about it, but never wrote anything detailed from a technical point of view. In past entries I talked about the idea behind the project, called Gamex, and how it is going to work. Because we are really excited with the project, sometimes we get lost our selves in the universe of coding (and fighting with Kivy) and we forget to document technical issues. So I hope to fix that with the current blog post.

General Architecture of Gamex

General Architecture of Gamex

The architecture of the project, as depicted in the image above, has different parts that I’m going to describe illustrating a complete application cycle:

  1. In a previous phase, and in order to save some time and increase performance, we pre-process a set of baroque paintings applying different techniques to recognize faces in pictures. All the data is stored using JSON files for medatadata and JPEG for images format.
  2. Then, the user, I mean, the audience of the exhibition, walk in front of the screen.
  3. The screen, thanks to a projector, shows a slideshow of baroque paintings and calls for the action, it demands interactivity. Maybe some fancy text with blinking effect or similar. Every phrase it correspond to a different game and different process to collect data. These ones are the current games we are developing (it is very easy to extend to collect data to, for example, just the virgins, or the saints, or the children, etc):
    • “Hey! Punch these people in the face,” to collect information from the position of the heads in the painting.
    • “Dude, better if you get this people’s eyes out,” to collect the pair of points related to the position of the eyes.
  4. When the user punch or touch the screen, a change in the deepness of the screen is produced. This alteration is observed by a Microsoft Kinect device.
  5. The signal is encoded as a point or set of points using STK and sent to a TUIO server.
  6. Tha main application written in Kivy is listening to that server. When a point is received into the TUIO server, the Kivy application translate it into a mouse click in the application frontend.
  7. In that moment, the information about the point is stored in a MongoDBNoSQL database, actually a key-value store. We create something similar to a table for every image with two different lists:
    1. The first one store a list of points and a timestamp for the face punch game.
    2. The second one is intended for the get the eyes out game and store a couple of points.
  8. If the point provided by the user is inside an area previously calculated in our metadata, we assign high points to provide some feedback to the user. If the point is new, we mark that information and show different score.
  9. When the number of points the user gives is similar to the number of faces we get in the preprocessing stage, the slideshow browse to another image and it starts again.

The second game is a way to tune the information we are collecting. For that game, Gamex is going to show paintings with information about where the faces are supposed to be. With the information about the position of the faces in the painting and the position of the eyes, we can calculate the size of the head and, even, create a probability heat map of where the faces are. Finally we will be able to enhance the algorithms used to detect faces.

Of course, this project is senseless if we are not able to get a lot of users and if we require only a minimum effort in the users side to interact. Let’s see what we are able to do.

4 Comments

Filed under Tasks

Faces in Baroque Paintings

As a part of our project, we have to provide a way by which the user can point out the faces in a serie of Baroque paintings. Theses faces are previously calculated using face recognition algorithms and SimpleCV, a simplified API for OpenCV thar, of course, doesn’t work on my 64bits machine. In fact, there are differente methods, with advantages and drawbacks, used at the same time. But algorithms are not perfect, and in general they miss some “obvious” faces as long as they wrongly tag things likes dresses as faces.

Intro screen

Intro screen

Above these lines you can see the initial screen before starting to play. In the future we are thinking about including more than one game. The first one is focused on identifying faces through the input of the users. The second one could be, for example, a game in order to filter that previous selection, something like, once we hace faces selected and extracted, a Invaders-like game in which users has to shot just to faces of certain kind. Very useful to filter and provide even more information for our algortihms.

However, we need to ask for the user the minimal interaction ever, so we expect from the user just one single touch on the screen. And this raises a problem: how to, with a single point in the screen, get the face the user is trying to point. To resolve this we are exploring two approaches.

The first one is to wish the users are going to make a circle around the heads or faces of the characters on the painting. But this is against our main goal to request as minimal interactions as possible. Our idea is the users can punch the screen where they think faces are, not draw a circles around. We need to think in another approach.

How the algorithms work so far.

How the algorithms work so far.

So the next step is to provide a way to make even more usefull the input from the users. And we decided the creation of a second game. In one hand, we previously did a detection of some faces, so we can calculate how near are the single touchs to the already recognized faces. But we don’t know this information for new faces that our algorithms missed out. If this happens, all we have is a point in the painting and no way to figure out if it is relative to a face. In this scenario, we mark these points for second stage in our process. Thus a second game in which we show to the users these images properly cropped and we pretend they just poke eyes out. Then, we have information about almost the center of the face (the previous single points), the current position of the eyes, and information about the medium size of the rest of the heads our algorithms did detect before: we can now triangulate the shape of the face/head. So in this way we filter a lot of information just making the users play a different game. The common feature in both games? The violence: Punch and poke eyes out!

2 Comments

Filed under Tasks

First Proof of Concept: Multi-touchable Surface with Kinect, SKT and Kivy

Slowly but surely. That’s our mantra in this project since it implies a lot of coding and to handle very different techonolgies, some of them –I really mean all of them– in the very stages of development. Anyway, we finally decided to implement our multi-touchable surface using a projector, a Kinect device and the libraries SKT and Kivy. As the next video shows, we are getting some advances, but we develop slower than we expect.

And finally, our first proof of concept of everything working together. It’s about a very basic project that is able to handle several interactions at the same time. At the moment, it only allows to draw lines and identify how many different contact points are there using one color for each one.

Behind scenes, what it happens is described below:

  1. The Simple Kinect Touching allow us to define the boundaries of the projected screen.
  2. We adjust a bunch of parameters related with deepness in order to focus only in the coordinates that mean something is touching the screen.
  3. Then, that information is transformed and sent according the TUIO protocol to a local server. Now we have service streaming of data relative to the touchs and movements on the screen.
  4. In this point, we run our Kivy client application, that we call gamex, by setting the input interface as a TUIO server instead of the mouse.
  5. Black magic.
  6. Profits!

And that’s it. We really hope to have time to focus in the development of the machine learning application once the most difficult technical issues seem almost solved. However, to do the projection on a bed sheet or table cover is going to be kind of traumatic for setting the paramereters in the Kinect recognition layer. We will need a very rigid wood frame or something for making the surface as smooth as we can.

Leave a Comment

Filed under Tasks

Thinking about an exhibit project

This week has been, again, very funny. I was participating in the building of a MakerBot 3D printer. I have to say that is easier than I thought and all you need is inside the box. I couldn’t be all the days needed to finish the printer because I had classes to attend. But anyway, the days I did do I enjoyed a lot.

Finishing the MakerBot 3D Printer

Finishing the MakerBot 3D Printer

Moving on to something else, Roberto and I were talking to Prof. William Turkel about some ideas for our final project. And after listening a lot of very good ideas and proposals, and given the fact that our time is finite, we’ve almost defined our project. It has three different parts that I am going to detail:

  1. We are going to build a multi-touchable big screen using a table cover. Yes, using a table cover. To do that we’ll use a Microsoft Kinect device. The Kinect, as much of you already know, is able to get the deepness of the scene what the device is focusing to. So, we also have a projector that it will be connected to one of our computers. Thanks to the Simple Kinect Touch library that we found, we can define the area of the projected screen as a delimited plain surface. Done this, any change in the surface is properly detected by the deepness camera of the Kinect. There are many ways to transform that information into a single point to emulate a mouse click. Maybe we’ll calculate the middle point according the distorted surface by pressing the screen. But what screen? The table cover on which the projector will be used.
  2. In the step above we explained briefly a way to have an arbitrary surface as a touchable screen. After this, we are going to show images in the screen. But not random images. In a parallel process, and using maybe OpenCV and some improvements to the face recognition algorithms, we extract the position of the bounding box for the faces from certain baroque paintings. However, this process is not always as good as we expect. And that’s the reason of the step three.
  3. In the final step, we use the bounding boxes extracted for each image. With that information, we project a image in the big screen and now,  using Kivy or Processing, we ask for users to touch the devil, angel, saints, virgins or Jesus faces. One of every type at the same time. So we can use that information as features to enhance a machine learning algorithm with scikit-learn. We can even propose different methods to touch the faces: pray for angels, punch for devils, etc. In this way, we give feedback (formally training) to recognise different kinds of faces, because our first algorithm is only able to detect faces and it doesn’t very well for faces in pictures.

And that is. The idea is to have this in some museum or public place, pretending that people play with the screen selecting the type of “touch” to give. And, in the background, providing very useful information for face recognition patterns in artworks.

But, due to the difficulty of having the tings working in 64 bits Linux OS, we are moving to 32 bits. It’s really better to focus on the task to do instead of the installation of requirements.

We also have already some materials to build the screen, I hope during this week to have a very first version of the code, that will be hosted ad GitHub. The name, in a lack of a better one, is Gamex: Game Exhibis for Machine Learning.

2 Comments

Filed under Tasks

The pain of having a 64 bit Linux laptop and OpenCV

This is the story of a very big frustration. I’ve been an evangelist of Open Source from almost 8 years now. One of the first thing I always defend is the the freedom of a free operative system. Of course, with great power comes great responsibility, but that didn’t really worry me because actually I’ve always been enjoying of dealing with the system. There is something special in the satisfaction of getting things working in Linux. Even, and secretly, it is one on the reaseons because we like Linux, because when something gets wrong, we have the power to fix it. And we love this.

But this mantra could have been a mess. Actually I thought I wasn’t able to get the things done. In this case, I was trying to install the open library for computer vision, called OpenCV, in order to use it from Processing. But my laptop has a 64 bits processor, and there started the problem. The most of the libraries are compiled and have binaries for 32 bits systems, so it’s supposed to could be enough if I compiled the libraries by myself. But that’s not alwasy as easy as it looks like. After try, nor one, two, three, four, but six different methods, I got OpenCV libraries working on my machine with Python bindings, and also the OpenNI and NITE PrimerSensor enabled, what it’s supposed to be good in you want to connect a Kinect (in the future I would like to use Point Cloud Library, aka PCL). And not the same luck for CUDA. Once the OpenCV was working, of course, I discovered the fantastic OpenCV PPA with 64 bits libraries packaged for Ubuntu 11.10.

After OpenCV, I needed to bind the library with Java first, and with Processing then. But this step hasn’t been likely at all. I tried the common OpenCV for Processing, I also tried the recommendations made by my classmate Roberto (whose laptop is 32 bits processor based) and generating again the libOpenCV.so following several instrucionts. Even with another different library called JavacvPro, but nothing, I always got the the error:

wrong ELF class: ELFCLASS64

So, if I wanted to build a proof of concept of our idea of a green LED blinking when the camera detects a fece, and a red one when it doesn’t, I had to use the almighty Python for what the OpenCV was already working pretty well. Then I took the typical facedect.py example and added a couple of lines for connecting to Arduino, so the new code looks like:

import numpy as np
import cv2
import cv2.cv as cv
import serial
from video import create_capture
from common import clock, draw_str

arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

help_message = '''
USAGE: facedetect.py [--cascade <cascade_fn>] [--nested-cascade <cascade_fn>] [<video_source>]
'''

def detect(img, cascade):
    rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30), flags = cv.CV_HAAR_SCALE_IMAGE)
    if len(rects) == 0:
        arduino.write("N")
        return []
    rects[:,2:] += rects[:,:2]
    arduino.write("F")
    return rects

# The rest of the code is the same

And having the next Arduino program loaded

#define GREEN 8
#define RED 7

int val = 0;
int face = 70; // "F"
int none = 78; // "N"

void setup() {
  pinMode(GREEN, OUTPUT);
  pinMode(RED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    val = Serial.read();
    if (val == face) {
        digitalWrite(GREEN, HIGH);
        digitalWrite(RED, LOW);
    } else if (val == none) {
        digitalWrite(GREEN, LOW);
        digitalWrite(RED, HIGH);
    }
    Serial.println(val);
  }
}

And here we can watch the amazing result of the work :-D

1 Comment

Filed under Tasks

Arduino, twitter & Python

The second week in the fascinating world of Arduino left us very interesting things. The class was about connecting new kinds of periphals, like buzzers or LCD displays. So, the idea of my classmate Roberto and me was to show the last tweet from twitter in a LCD display. After that, and due to the time limitations of the class, we changed our minds and decided analyze the last tweet in a sense of positive or negative message, and then brigth a blue LED for positive or red LED for negative. But sadly, this also was too much for one and a half hour.

So, what we finally did was to communicate the Arduino device with twitter through serial port connecting to a Python program. The workflow is the next. A Python program in a infinite loop gets the last tweet, then analyzes the positive and negative sentiment (using ViralHeat API) of hte text, after that, it sends a signal to the Arduino device, that it is listening in a specific port. Regardless to the singal received, plus the message, Arduino does the right LED to brigth.

The message is not trivial, and it has to be defined. In our case, we first send the signal for blue, red or both (whether the sentiment was unable to get), followed by a special token as separator, all the characters of the text for a future implementation of the LCD display. The separator token should be a not printable character or some you are sure it is nor possible to use in a twitter message.

So here you can find the Python code fofr the program. As you can see, we used the twython library for connecting with Twitter. Also, if you are using Linux, in order to know the right port to connect, go to the Arduino window → Tool → Serial monitor, and see what it is written in the title of the window. It used to be something like

/dev/ttyACM0

.

import serial
import time
import urllib
import requests

from json import loads
from twython import Twython

# Token, we choose not printable values
SEPARATOR_TOKEN = 666
# Sentimen API
url = "http://www.viralheat.com/api/sentiment/review.json?text=%s&api_key=<KEY>"
# Connect to arduino via serial port
arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=1)

# Write to Arduino
def writeToArduino():
    twitter = Twython()
    public_timeline = twitter.getPublicTimeline()
    last_tweet = public_timeline[-1]
    text = last_tweet["text"]
    # We get the numbers of the each character
    codes = [ord(c) for c in text]]
    # Get the sentiment
    response = requests.get(url % urllib.quote(text))
    sentiment_response = loads(response.content)
    if sentiment_response["mood"].lower() == "negative":
        sentiment = 0
    elif sentiment_response["mood"].lower() == "positive":
        sentiment = 1
    else:
        sentimen = 2
    # Add characters codes and sentiment value
    arduino.write(codes + [SEPARATOR_TOKEN, sentiment])

while True:
    writeToArduino()

And finally the Arduino code.

#define GREEN 8
#define RED 12

const int sepToken = 666;
int val = 0;
int lastVal = 0;

void setup() {
  pinMode(GREEN, OUTPUT);
  pinMode(RED, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    val = Serial.read();
    if (lastVal == sepToken) {
      if (val == 0) {
        digitalWrite(GREEN, HIGH);
        digitalWrite(RED, LOW);
      }
      if (val == 0) {
        digitalWrite(GREEN, HIGH);
        digitalWrite(RED, LOW);
      }
      if (val == 0) {
        digitalWrite(GREEN, HIGH);
        digitalWrite(RED, LOW);
      }
    } else {
      // Print "val" to the LCD Display
    }
    Serial.println(val);
    lastVal = val;
  }
}

Leave a Comment

Filed under Tasks

Arduino: First Contact

This week has been, at the end, my first Interactive Exhibit Design class. From the first moment, and working in pairs, we were given an Arduino UNO device, with the corresponding trainer, wires, light-emitting diodes (aka LED), light sensors, one button and the USB cable to connect to the laptop. I cannot say I weren’t excited. I’ve been hearing about Arduino almost 4 years and finally yesterday I could use it.

As a guy with some Computer Sciences Old School background, has been amazing to see the simplicity of Arduino and the magic of the in board microcontroller. I remember the times when I had to pay a lot of attention in order to get my circuit working. If you made a mistake, you should rethink about your wiring, connect the oscilloscope and analyze what the hell was going on. Now, with Arduino, you can layout the components of the circuit and build as much programs on it as you want. For me, it is like magic.

Arduino and its components

Arduino and its components

This first contact was näive. My classmate and I made the tipical first experiment: make a LED to bright. After that, and using the software development kit also provided, and based on Processing, we plug a light sensor, some resistances and build this time a proximity alarm: if you bring your hand closer to the light sensor, this one lose some light, then our code was design to make blink a diode in a inverse way to the light the sensor were receiving. Really funny and didactic.

Our "proximity" detector

Our "proximity" detector

So now, I am exciting again for the next class and to see what Arduino has for us!

2 Comments

Filed under Analysis, Tasks