Nail Portrait

I have a thing for stuff made from/using wood. Not that I am an expert, in fact, I have no skills whatsoever. The only time I attempted to put something together was during my sophomore year. Nails were hammered and/or screwed into a piece of wood to write sentences. Since then I wanted to make portraits on wooden blocks using nails. That didn’t happen so far. So just to satisfy my desire, I have written a program in Mathematica that takes an image and converts it to a nail portrait. 🙂

The idea will be to use Mathematica functions only (and no other 3d models) to build the portrait from scratch.


Here’s a test image of myself:

img = Darker[Import["me.png", ImageSize -> 250], 0.5]

First thing would be to find the edges. The image is blurred a bit (with 5 pixel radius) before the edge detection methods are called just so that noise is suppressed.

edge = EdgeDetect[Blur[img, 5], 2, 0.01]

That needs to be cleaned up, so I decided to delete the small components that are less than 25 pixel length.

dedge = DeleteSmallComponents[edge, 25]

The components that are touching the border are deleted next.

dedge = DeleteBorderComponents[dedge]

Finally we do a morphological connected components search to detect the different regions.

cedge = MorphologicalComponents[dedge];

% // Colorize

Making the “nails”

Each component in the connected components matrix is found and the number of elements in the matrix for each component is calculated. The components are then sampled uniformly to create a point set representation of each component. The points are plotted using the ListPlot command. They were also rotated by a [0 1; -1 0] rotation matrix (-90 degrees) for viewing the resulting plot correctly.

cm = ComponentMeasurements[cedge, "Count"];

counts = Table[cm[[i, 2]], {i, 1, Length[cm]}];

rm = {{0, 1}, {-1, 0}}

Table[rm.Position[cedge, 1][[i]], {i, 1, counts[[1]], 10}];

selpt = Table[
 rm.Position[cedge, i][[j]], {i, 1, Length[counts]}, {j, 1,
 counts[[i]], 8}];

ListPlot[Flatten[selpt, 1] -
 Table[{0, Min[Flatten[selpt]]}, {i, 1, Length[Flatten[selpt, 1]]}]]

To create the nails from this image, all the points are converted from 2d to 3d by adding a random amount of elevation to each 2d coordinates. The randomization is mainly to mimic the random heights of nails on the wooden board.

zlength = Max[Flatten[selpt]]/10.0
flselpt3d =
 Table[{flselpt2[[i, 1]], flselpt2[[i, 2]],
 RandomReal[{zlength, zlength + zlength/2}]}, {i, 1,

The resulting 3d coordinates are plotted using the ListPointPlot3D command. The Filling property of this command is set to true (and a dark gray color is assigned to it) to show the height of each point. This will also act as the body of the nail in the final plot!

lst3d = ListPointPlot3D[flselpt3d, Filling -> Bottom,
 PlotStyle -> Directive[Black, PointSize[Large]],
 FillingStyle -> Directive[RGBColor[19/255, 19/255, 19/255], Thick],
 Lighting -> Automatic]

Making the “board”

The “wooden board” is actually just another plot using Mathematica. A wood texture has been applied to a region plot. A cuboid region is generated by using a simple condition: x >0. The limits are defined by the maximum and minimum range of the 3d “nail” points in x, y and z directions.

rgplot = RegionPlot3D[
 x > 0, {x, 0, Max[flselpt2[[;; , 1]]]}, {y, 0,
 Max[flselpt2[[;; , 2]]]}, {z, 0, zlength},
 PlotStyle -> Texture[wood3], BoxRatios -> Automatic, Mesh -> None]

Putting it altogether

The 3d points plot and the region plot are shown together using the Show[] command. The lighting is adjusted, borders and axes are taken out too to give the final image.

Show[lst3d, rgplot, PlotRange -> {0, 1.6*zlength}, Axes -> None,
 Boxed -> False, BoxRatios -> Automatic]

This gives us the final 3d plot.

Here’s another view of the plot.

Some details are lost in this portrait, for example the smile is missing (or can be hardly noticed)! Oh well, this is just a simple scheme. To reconstruct the smile would require a better image (where lighting conditions are suitable to find the correct edges) and more playing around with the blur and edge detection parameters in the preprocessing stage.

Anyway, this gives me a general platform to produce nail portraits of nearly anything.


The idea was to create some sort of visual representation of all negative emotions/facts in a Bangladeshi newspaper, The Daily Star. By negative emotions here I mean news regarding death, accidents, robbery, abduction, rape, bribing, arson and any natural calamity.

Following are images that are in the first installment of the series Abyss. Abyss is one of my efforts to visualize emotions/facts through computational art. The images were programmed and generated using Mathematica.

Each circle represents the crime, disaster and calamity news per district or municipal cities every three months, starting from September 2007 to June 2012. Each bar in a circle represents a city or a district, with its angle and height being proportional to the number of such news reported by Daily Star for that region. A sequence of circles thus represents a timeline of negative emotions going from the present to the past.

Click to view larger versions of these images.

Abyss 1. A timeline of crime news reported for the districts of Bangladesh.

Abyss 2. Timeline of crime news reported for all cities of Bangladesh.

Abyss 3. Timeline of crime news reported for all the municipal cities of Bangladesh.

Method: The data were collected by parsing through the online archive of Daily Star. The online archive data were downloaded using Mathematica for each date and the news were matched against a set of predefined words (along with their inflected forms) to separate the crime/disaster reports, then these selected news were parsed again to look for cities and district names in them. The names of cities and districts were parsed from this website.

A matrix containing the count for each city/district (columns) every three months (rows) was updated at each iteration of this parsing. The data in the matrix is then visualized as described above. All of these operations and visualization were done using Mathematica.