Apple and design

Check out this post on why Apple is Really Bad at Design. Apple has made some nice products over the years, but its hold on design has kind-of waned recently. What’s cool about the latest iPhones? Not much. At the end of the day, all mobile devices are just that – mobile devices. They haven’t evolved that much in recent years. Cameras get more complex (dual cameras, optical zoom), and the aesthetics of the phones changes – but other than that there are no fancy things. I certainly wouldn’t use an iPhone as my sole travel camera. Have come to the point of design blah in the world of digital products?

 

Image sharpening in colour – how to avoid colour shifts

It is unavoidable – processing colour images using some types of algorithms may cause subtle changes in the colour of an image which affect its aesthetic value. We have seen this in certain forms of the unsharp masking parameters used in ImageJ. How do we avoid this? One way is to create a more complicated algorithm, but the reality is that without knowing exactly what object is at each pixel, this is impossible. Another way, which is way more convenient is to use a separable colour space. RGB is not separable. The red, green and blue components must work together to form an image. Modify one of these components, and it will have an affect on the rest of them. However if we use a colour space such as HSV (Hue-Saturation-Value), HSB (Hue-Saturation-Brightness) or CIELab, we can avoid colour shifts altogether. This is because these colour spaces separate luminance from colour information, therefore image sharpening can be performed on the luminance layer only – something known as luminance sharpening.

Luminance,  brightness, or intensity can be thought of as the “structural” information in the image. For example first we convert an image from RGB to HSB, then process only the brightness layer of the HSB image. Then convert back to RGB.

Here is the original image:

Here is the RGB processed image (UM, radius=10, MW=0.5):

Note the subtle changes in colour in the region surrounding the letters? This sort of colour shift should be avoided. Now below is the HSB processed image using the same parameters applied to only the brightness layer:

Notice that there are acuity improvements in both halves of the image, however it is more apparent in the right half, “rent K”. The black objects in the left half, have had their contrast improved, i.e. the black got blacker against the yellow background, and hence their acuity has been marginally enhanced.

Different types of unsharp masking

There are various types of image sharpening which come under the banner of “unsharp masking”. Some are subtractive, i.e. involve subtracting a blurred copy of an image, whilst others are additive, i.e. they add a high-pass filtered image to the original. Let’s look at a few of them, applying them again to the sub-images taken the coffee image.

First off, let’s look at a simple example of an additive filter. The filter we are going to use is:

The result of this filter is:

Now, if we add this image to the original:

The image has been slightly sharpened, but at the expense of also sharpening any noise in the image.(click on the image to see the detail). Here is another additive filter, one which is more commonly used:

And the corresponding result:

Now consider the use of traditional “subtract the blurred image” unsharp masking. It is actually not as easy as just subtracting a blurred version of the image. The diagram below shows the process.

Now the result of using a Gaussian blur filter with a radius of 10 (and k=1) is shown below:

 

 

 

 

Unsharp masking in ImageJ – changing parameters

In the previous post we looked at whether image blur could be fixed, and concluded that some of it could be slightly reduced, but heavy blur likely could not. Here is the image we used, showing blur at two ends of the spectrum.

Now the “Unsharp Masking” filter in ImageJ, is not terribly different from that found in other applications. It allows the user to specify a “radius” for the Gaussian blur filter, and a mask weight (0.1-0.9). How does modifying the parameters affect the filtered image? Here are some examples using a radius of 10 pixels, and a variable mask weight.

Radius = 10; Mask weight = 0.25

Radius = 10; Mask weight = 0.5

Radius = 10; Mask weight = 0.75

We can see that as the mask weight increases, the contrast change begins to affect the colour in the image. Our eyes may perceive the “rent K” text to be sharper in the third image with MW=0.75, but the colour has been impacted in such as way that the image aesthetics have been compromised. There is little change to the acuity of the “Mölle” text (apart from the colour contrast). A change in contrast can certainly improve the visibility of detail in the image (i.e. they are easier to discern), however maybe not their actual acuity. It is sometimes a trick of the eye.

What about if we changed the radius? Does a larger radius make a difference? Here is what happens when we use a radius of 40 pixels, and a MW=0.25.

Again, the contrast is slightly increased, and perceptual acuity may be marginally improved, but again this is likely due to the contrast element of the filter.

Note that using a small filter size, e.g. 3-5 pixels in a large image (12-16MP) will have little effect, unless there are features in the image that size. For example, in an image containing features 1-2 pixels in width (e.g. a macro image), this might be appropriate, however will likely do very little in a landscape image. (More on this later)

 

 

 

The usability of old blenders

In many respects, old household appliances hold quite a lot of information about usability, especially those from the 1960s and 1970s. Although “time” saving kitchen appliances had already been around since the 1920s, it was when they started to become more complex and offer interface elements that things started to get interesting. Let’s consider the interface of the Oster “dual pulse matic 10” shown below:

The first thing to notice are the easy to push buttons – there are five buttons for 10 speeds, with the alternator being the dial “Lo” and “Hi” settings. The confusing part of the interface is the fact that there is both an “ON” button, and an “Off” setting on the dial. So one would imagine, maybe the first two choices were “PULSE” or “ON”, and if “ON” was chosen then one could set the dial to “Lo” or “Hi”. More confusing are the 10 blend settings:

Stir → Puree → Whip → Grate → Mix → Chop → Grind → Blend → Liquefy → Frappé

Some of these terms don’t even make sense with respect to blenders. Basically a 10-point scale doesn’t necessarily need a descriptive word for each level. For instance, the word Frappé is not a verb, mix and blend essentially mean the same thing, and blenders don’t really grate food. Here is another blender from Oster, with a simpler On/Off dial, a pulse button, and eight buttons, each with two functions – making the number of functions even more complex.

More ridiculous are some of the labels like “crumb”, and “crush”. So, while the interface has improved in some usability aspects, it still suffers from over an inability to indicate what each button really does. Having 16 different buttons, is also overkill – having only 8, or better still a dial, would work infinitely better. Not to say modern blenders are any better. Some use less buttons, but still use confusing nomenclature. One of the few which has a well designed user interface is the Vitamix series of blenders – a simple 1-10 dial, and On-Off toggle switch, and a toggle switch to convert between High and Variable speed.

 

 

Is blogging an academic pursuit?

I don’t know many academics who have a blog. They are probably too busy writing important journal papers. Likely. I’m probably one of a handful. Why? Probably because in the overall scope of things it’s not considered a very “academic” activity. One is better off writing articles for “peer-reviewed” journals. Or so they would have you think. I doubt that many people read my blog, but likely more than those that read any article I have ever written. Did any of them change the world? No – they were never designed to. Nobody writes life changing journal articles. Don’t get me wrong, I enjoy writing, but I like to tell a story more than I like to pontificate about things I find to be wonderful. “This paper discusses the algorithm I created for… blah blah blah… and it works the best!”. If your algorithm could absorb CO2, or clean the oceans of plastic waste I would be impressed. But it can’t. Much research is meaningless, or at least hard to fathom for the average person (is research into the origins of the universe really purposeful?). Some of it is of course useful, e.g. research into things that make our lives better (yeah and that doesn’t include the latest iPhone).

Blogging is interesting because you can talk about snippets of things – that may ultimately be useful, or not. It’s like a notebook of ideas, concepts that can be put out into the ether – hopefully written in some manner that is accessible to everyone – that’s really the whole point of education isn’t it? That, and its a readily-accessible format.

Blogging *is* academic writing and publication. The world has moved on from the likes of boring long-winded articles. And the reality is that blogging can help improve writing skills – not everyone has the ability to write good text – especially those from the science fields who don’t have the benefit of writing copious essays like those in the humanities. Blog posts are small pieces of text – not a 5000 word essay, most are likely 100 words or less. But they are good at discussing various points of interest, and especially good for writing books, because they allow you to concentrate ideas into a simple note that can be expanded upon at a later date. Blogging requires you to be concise. Posts that are far too long will be ignored – it should be about bullet points, lists, and short paragraphs. Some academic writing involves taking one point and making an argument around it – so blogging can actually help support those other things you write (on paper). It is also easy to include things like images, and pieces of code (very important for computer scientists).

Blogging has improved my writing and analytical skills, and blogging allows me to share ideas quickly. A journal paper may take me 14 months to write. So is it an academic pursuit? Yes. Even more so, blogging is a bridge between academia and the world. And yes, maybe blogging doesn’t work in fields like chemistry (or maybe it does?). But in computer science, a field which moves crazily fast, blogging just makes sense. No-one will publish an article on the usability of the iPhone X, but is it important – unequivocally yes. Journals don’t publish articles reviewing programming languages, or debating the validity of recursion. So blogging fills a void so to speak. It also allows me to communicate information with students taking my classes. If someone asks a question on a technical issue, it is easier to write a blog post that benefits everyone, than reply in a single email.

Blogging is also fun, and who doesn’t like fun?

Writing a textbook ≠ get rich quick scheme

Ever been to a bookstore and wander through the cookbook section? There are literally 100s of titles (even more online), with more published every week. Ever wonder if the authors make money? The answer is most likely don’t, and the reasons are simple. Publishing a book costs money. Books have to be edited, printed, marketed, and distributed. So paying $35 for a hardcover cookbook is a bargain. One cookbook shop owner once told me that authors make their money off speaking engagements, demos, etc. Makes sense.

Now writing a textbook is slightly different, as the audience for the book is more constrained. They are also often overpriced, and exist in a captive market, i.e. students often *have* to buy them, and hence both publishers and university bookshops make $$$, and authors make very little. Of course many students who buy a $100 textbook think the author is making a fortune off the books. The opposite is often true. Most authors get a royalty of roughly 10% off the wholesale price of the book. How does this work, well I’ll explain.

A few years ago I wrote a textbook on programming for my introductory class, “Confessions of a Coding Monkey“. It was meant to provide an easy to understand guide to programming, with a whole series of case studies. It was fun to write. However I didn’t quite understand the intricacies of publishing when it came to pricing the book. The book sold at the campus bookstore for C$110. The whole price was somewhere around C$60. So the bookstore made $50, for basically having a book sit on a shelf. Amazing right? My royalty was 10%, so C$6 per book. So:

Publisher: $54
Bookstore: $50
Author: $6

Now, I get that publishing costs money. But the author gets basically 5% of the price the student pays. Then of course you have to pay taxes, and it’s worse if your publisher is in the US. So if you are lucky, of that C$6 you end up with $C3. Barely enough for a coffee. Now you may end up selling thousands of books. Let’s say you’re lucky and you sell 3000 copies over a five year period. That means you likely make $9,000 after tax. How much effort did it take to write? Six months of time? A year? Probably not enough to retire on. You do the math on how much the publisher makes, and the bookstore. Oh, and my book was printed as a paperback in black-and-white, and I did all the illustrations (bar the cover).

People more often than not write books for the love of it. Sure, some authors do make money. Chef Jamie Oliver has over 20 books to his credit, and is hugely successful. His 30-Minute Meals book sold in excess of 1.5 million copies. Having experienced the whole process of publishing with a large publisher, I would never do it again – I’m planning on self-publishing the book I am currently working on (a hybrid book on digital photography/image processing), and offering it as inexpensively as possible to everyone, probably through something like Blurb.

P.S. Interested in more info? Read this article, Everything You Wanted to Know About Book Sales (But Were Afraid to Ask).
P.P.S. From what I gather, textbook authors who *do* make money are those who write books in fields like math, where their textbooks that are widely used, and have a super amount of editions.

Why learning to code is easier in Julia (iii)

Now some will argue that the true tenets of programming aren’t being taught, but the reality is that many people want to learn how to program, but not become programmers. No different from people who want to learn Norwegian, but don’t want to become translators. Explaining how the image becomes inverted is easy as well. First propose a problem:

Problem: Given a digital image write a program to derive the negative of the image.

Now explain some of the concepts:

Explanation: The digital image is in the form of a “text image”, where each “pixel” in the image has an “intensity” value from 0 to 255. So black has the value 0, white has the value 255, and 1 to 254 are various shades of gray from black to white. Here is an example, with the values of four pixels shown:

The negative of an image is its inverse – so black becomes white, white becomes black etc. This is achieved by subtracting 255 from each pixel, and taking the absolute value of the result. Here is the result of calculating the negative of the example above:

So, for the pixel with an intensity value of 115 in the original, 115-255 = -140, the absolute value of which is 140. So 140 is the negative value of the original pixel.

Now write the algorithm:

  1. Read in the text image from a file.
  2. Calculate the negative of the image.
  3. Write the negative image to a file.

Finally show how the program is written:

image = readdlm("forthenry.txt", Int16::Type)
imageNeg = abs(image-255)
writedlm("forthenryNEG4.txt", imageNeg)

Three lines of code.

Why learning to code is easier in Julia (ii)

Now, in Julia this process becomes easier, because some of the processing is provided in ready-made functionality. The C program was long, and for many novice programmers, somewhat overwhelming.

Now compare this to the Julia program:

function imNegative(img)
   dx,dy = size(img)
   imgN = zeros(dx,dy)
   for i=1:dx, j=1:dy
      negP = abs(img[i,j]-255)
      imgN[i,j] = negP
   end
   return imgN
end

image = readdlm("forthenry.txt",Int16::Type)

imageNeg = imNegative(image)

writedlm("forthenryNEG2.txt",imageNeg)

Much less complex. In the C program, almost 40% of the program deals with image I/O. In the Julia program, most of the code deals with calculating the negative version of the image. But the code in function imNegative() is actually overly complex, because Julia can do things in an even simpler manner:

function imNegative(img)
   imgN = abs(img-255)
   return imgN
end

image = readdlm("forthenry.txt",Int16::Type)

imageNeg = imNegative(image)

writedlm("forthenryNEG3.txt",imageNeg)

The function  imNegative() has been reduced in size by more than half. But this can be reduced even further by folding the image negative operation into the main program. this gives:

image = readdlm("forthenry.txt",Int16::Type)
imageNeg = abs(image-255)
writedlm("forthenryNEG4.txt",imageNeg)

Three lines of code.

Some might think this is too simple, but many individuals who learn programming do so to be able to perform some task. They don’t want to be caught up in the syntactic intricacies of a language. The three lines of code still contain some information which has to be explained, e.g. the use of Int16, but this has to do with the data, and novice programmer has to have some idea about data regardless of the language used.

Input and output of the image data is easy to handle, and the actual process of inverting the image becomes one line of code, basically: “take the data stored in image, subtract 255 from each pixel and convert that to a positive number“.  So if the pixels value were 100, abs(100-255) is 155.

The big difference is that Julia can perform whole array based operations, whereas languages such as C require the use of multiple loops to process each image. Simpler syntax makes it easier for the novice programmer to concentrate on the task at hand. Julia also provides built-in functionality for reading in/writing out files of numbers, through the use of functions like readdlm() and writedlm().

 

Why learning to code is easier in Julia (i)

Are you still stuck trying to learning programming using a language like C, or heaven forbid Java? There are many good languages out there, even the likes of Fortran and Ada, are *good* languages. But there are very few languages which are good for the novice programmer to get their feet wet in. Julia, in my opinion is one of them. I spent over 10 years teaching introductory programming using C as the language, to a large group of students from diverse disciplines – and it doesn’t work. Why? Largely because although the C programming language is compact, it is too compact. There are too many idiosyncrasies with the language to properly learn in a semester for people who have never programmed before. Java is no better. When I was an undergrad (many moons ago), we learnt Pascal first, then C as a second language. It’s also harder to do anything *meaningful* in a language such as C. For example, you can’t process data like images, because of the overhead in programming required to do something as simple as reading in an image. Storing it inside a program is also a nightmare – for novice programmers.

Here’s an example. Imagine you wanted to illustrate a simple program that does nothing but read in a monochrome image, and process it to produce a negative version of the image. (Let’s assume the image is just a simple ASCII file with numbers representing values of pixels in the image).  Basically we want to take an image that looks like this:

and turn it into this:

Now in C, the program might look something like this:

#include <stdio.h>
#include <math.h>
#define dx 336
#define dy 546

# Function to transform an image into a negative image
void imNegative(int img[dx][dy], int imgN[dx][dy])
{    
    int i, j, negP;
    for (i=0; i<dx; i=i+1)    
        for (j=0; j<dy; j=j+1) {       
            negP = abs(img[i][j] - 255);            
            imgN[i][j] = negP;        
    }
}

int main(void)
{    
    int i, j;    
    FILE *ifp, *ofp;    
    int image[dx][dy];    
    int imageNeg[dx][dy];    

    # Read in the image
    ifp = fopen("forthenry.txt", "r");
    for (i=0; i<dx; i=i+1)    
        for (j=0; j<dy; j=j+1)       
            fscanf(ifp,"%d", &image[i][j]);    
    close(ifp);

    # Process the image
    imNegative(image, imageNeg);

    # Write the processed image to file
    ofp = fopen("forthenryNEG.txt", "w");    
    for (i=0; i<dx; i=i+1){    
        for (j=0; j<dy; j=j+1)       
            fprintf(ofp,"%d ", imageNeg[i][j]);        
            fprintf(ofp,"\n");    
    }    
    close(ifp);
    return 0;
}

For the novice programmer, in C this is not a trivial program. It incorporates aspects of arrays, parameter passing in functions, pointers, and file I/O – often topics not covered until later in a course. It is a more basic version of a C program, because it does not even cover dynamic arrays to deal with large images, and the information for the particular image file is hard-coded into the program (e.g. image dimensions).