If A Picture Paints A Thousand Words

And so begins the words of the a song by the Bread. The complexity we see in the world is a product of the interactions of simple building blocks. Everything we see is just a combination of a few elements in the periodic table. In turn every element is a combination of electrons, protons and neutrons.

A picture paints a thousands words but what paints a thousand pictures? Just like a Lego truck that is composed of a few Lego shapes, a “black and white” picture is also composed of a few levels of gray. The levels is just a set of 256 numbers starting from 0 up to 255. The number 0 represents black and the number 255 represents white. The numbers in between represent colors between extreme black and extreme white. The diagram below shows the levels of gray in a 16 by 16 matrix. The gradient goes from left to right, top to bottom.



Using just these 256 numbers, we can already draw interesting figures. Take for example this 8 by 8 matrix of numbers:

197   4  46  18 155 186 144 190 
111  30   6 131 235  99 112 227  
10   26 141 147 120  28  92 187 
241 100 118 149 178   5 158 213 
105  43 104  63 172 222  64 174 
130 194 243  56  59 166 134 133 
247 145  36  82 238 251  53 129 
171  29  51 163 199 214 113 195

When you plot this on an 8×8 grid, you get the following pattern:



Not all pictures need to be boring. Here’s an example of a picture that is not that boring:

17 23 26 20 13 20 20 22 21 17 17 25 20 11 15 15 9 10 18 13 14 12 13 39 61 63 71 72 69 71 74 72 74 75 72 76 75 75 75 80 77 78 79 79 80 80 80 80 81 81 82 82 83 83 83 83 84 84 84 84 85 86 86 86 87 87 87 88 88 88 89 89 89 89 90 90 90 90 90 91 90 90 91 91 92 92 92 92 94 94 95 95 95 95 95 95 96 96 96 96 97 97 97 97 98 98 98 99 99 99 100 100 101 101 101 101 102 102 103 103 104 104 104 105 105 105 105 105 106 106 106 107 107 108 108 108 110 110 110 110 111 111 112 112 113 113 113 114 114 115 115 115 116 116 117 117 117 118 118 119 119 119 120 120 121 121 122 122 123 124 124 125 125 125 126 127 127 127 128 128 129 129 129 129 131 131 132 132 133 134 ...

That is just the start of a 310×204 matrix saved in the file “clifton.txt”. If you plot that using the R command

clifton = read.table("clifton.txt")

#convert this data frame to a vector
vclifton = as.numeric(clifton) 

#create the 310x204 matrix
mclifton = matrix(vclifton,nrow=310,ncol=204)

#plot the image
image(mclifton[,ncol(mclifton):1],col=gray((0:255)/255))

you’ll get the following image



Histogram

If you look at the file “clifton.txt” and count the occurrence of each number, you will see that there are 9 occurrences of zero and 4 occurrences of 240. If you do this for all other numbers, you will get the following counts:

Level Frequency
0     9
1     16
2     31
3     34
4     49
:
:
237   115
238   113
239   18
240   4
:
:
254   0
255   0

If you plot this data as a bar chart, you will get what is known as the histogram of the picture:



The histogram above was obtained using the following R command:

hist(vclifton,breaks=256)

The histogram tells us the how much of each gray level contribute to the actual image.

Here’s another example of a picture that is relatively dark. In photography, the image below is called a “Low Key” image because it is mostly dark.



Low Key images tend to have the bulk of the colors at the right side of the scale. The next image is a “High Key” image because it is mostly white:

Histograms of High Key images tend to have the bulk of the colors at the right side of the scale. The histogram of the “clifton.txt” image tends to have a much better balance in that it contains most of the colors at the middle of the range.

It’s surprising how we can come up with complex images using just 256 levels of gray. We haven’t even considered colors yet! We also learned how histograms can be constructed by counting the frequency of each level and what histograms of High Key, Low Key and Optimum exposure look like.

Advertisements

Mathematically Romancing Mt Mayon

The name Mayon is short for Daragang Magayon, or “Beautiful Lady”, which is the legend associated with Mt Mayon. No wonder, I still find myself captivated by its charms after visiting it three weeks ago.

While playing with google maps this sunday, I decided to take a look at Mt Mayon and I was hoping I could get a three dimensional view of the beauty. I was disappointed. Although there is a 3D view, but it was not beautiful at all. Luckily, google map provides a topographical information of Mt Mayon. Suddenly, I was inspired to recreate the view of Mt Mayon using that information and using the tool called R.

First thing I did was to capture the image from the google maps and saved it as JPEG. Using the ReadImages library of R, I loaded the image and plotted it.

# load the library
library("ReadImages")

# read the file and plot
x=read.jpeg("mount_mayon_topography2.jpg")
plot(x)

# add grid lines
grid(nx=20,ny=20,col="red")

The result of the code above is a plot of the image with red grid lines, as shown below.


You will notice that the image contains contour lines with a height information associated with it. I used the grid lines to manually interpolate the height of Mt Mayon at each intersection. I started at the bottom line and worked myself upward from left to right. However, I got lazy interpolating from point to point so I just stopped when I reached the middle line. I decided that the upper half of the image is just a mirror image of the bottom so I might as well use the same numbers. Here’s a dump of the interpolated height from the bottom half of the image:

0,        0,    0,     0,     0,    0,400,400,400,450,450,420,400,350,300,280,250,220,200,
0,     100,200,300,400,420,450,500,550,570,550,500,480,420,400,380,350,250,200,
200,300,350,400,420,500,550,580,600,650,600,600,580,550,500,400,350,300,320,
280,350,380,400,500,580,610,650,780,800,750,730,650,600,500,450,380,310,300,
300,400,430,500,580,650,780,800,950,990,970,900,800,700,580,500,520,350,300,
310,400,480,580,610,750,840,1000,1100,1200,1150,1100,1000,800,650,550,450,380,350,
320,450,500,600,700,800,1000,1200,1350,1500,1500,1380,1180,900,800,650,510,400,350,
350,450,500,600,750,900,1100,1350,1600,1800,1800,1600,1350,1100,900,700,550,450,350,
370,450,500,600,780,900,1200,1500,1800,2100,2000,1800,1500,1180,900,700,550,500,350,
380,450,500,620,780,970,1200,1500,1900,2250,2200,1800,1400,1150,900,700,550,520,400,

Reflecting this information about the middle line and inputting this to R, we get

z=c(0,        0,    0,     0,     0,    0,400,400,400,450,450,420,400,350,300,280,250,220,200,
0,     100,200,300,400,420,450,500,550,570,550,500,480,420,400,380,350,250,200,
200,300,350,400,420,500,550,580,600,650,600,600,580,550,500,400,350,300,320,
280,350,380,400,500,580,610,650,780,800,750,730,650,600,500,450,380,310,300,
300,400,430,500,580,650,780,800,950,990,970,900,800,700,580,500,520,350,300,
310,400,480,580,610,750,840,1000,1100,1200,1150,1100,1000,800,650,550,450,380,350,
320,450,500,600,700,800,1000,1200,1350,1500,1500,1380,1180,900,800,650,510,400,350,
350,450,500,600,750,900,1100,1350,1600,1800,1800,1600,1350,1100,900,700,550,450,350,
370,450,500,600,780,900,1200,1500,1800,2100,2000,1800,1500,1180,900,700,550,500,350,
380,450,500,620,780,970,1200,1500,1900,2250,2200,1800,1400,1150,900,700,550,520,400,
370,450,500,600,780,900,1200,1500,1800,2100,2000,1800,1500,1180,900,700,550,500,350,
350,450,500,600,750,900,1100,1350,1600,1800,1800,1600,1350,1100,900,700,550,450,350,
320,450,500,600,700,800,1000,1200,1350,1500,1500,1380,1180,900,800,650,510,400,350,
310,400,480,580,610,750,840,1000,1100,1200,1150,1100,1000,800,650,550,450,380,350,
300,400,430,500,580,650,780,800,950,990,970,900,800,700,580,500,520,350,300,
280,350,380,400,500,580,610,650,780,800,750,730,650,600,500,450,380,310,300,
200,300,350,400,420,500,550,580,600,650,600,600,580,550,500,400,350,300,320,
0,     100,200,300,400,420,450,500,550,570,550,500,480,420,400,380,350,250,200,
0,        0,    0,     0,     0,    0,400,400,400,450,450,420,400,350,300,280,250,220,200)

Next, I generated the coordinates of the x and y plane:

myx=seq(-9,9,1)
myy=seq(-9,9,1)

To generate the 3D view, I used the persp3d function of the rgl library and animated the 3D plot so that we can see the plot 360 degrees.

library(rgl)
persp3d(myx,myy,z,col="darkseagreen", aspect=c(4,4,1))
play3d(spin3d(axis=c(0,0,1), rpm=8), duration=20)

The result of the above code is an animated plot of Mt Mayon using partial topographical information. Shown below is the animation:

This is indeed a great waste of time. But I guess, that’s what you do when you fall in love…mathematically!