# Functional design clunkers

Sometimes I'd really like to be able to go back in time and fix a few of the functional designs in the Image Processing Toolbox. In a few cases the original design flaw is that we bundled up a little too much functionality in a single function. I'll give you two examples: graythresh and edge.

The function graythresh uses Otsu's method to automatically determine a "good" threshold for a gray-scale image. You use it like this:

I = imread('coins.png');
imshow(I)
T = graythresh(I); % T is a normalized threshold value between 0 and 1
bw = im2bw(I, T);
imshow(bw)

The functional design flaw here is that Otsu's method doesn't really need the original image at all. It is defined solely in terms of the histogram of the image. The first thing graythresh does is compute the histogram.

But what if you had already computed the histogram for some other purpose? There's no way to use graythresh without computing it again.

My own functional design sensibility has evolved toward writing more functions that do smaller, simpler steps. So today I would design a function like graythresh so that it took a histogram as the input argument.

But isn't that less convenient? Yes. But I would move the "convenience" syntax elsewhere, probably to im2bw by giving it an "automatic threshold" syntax. If I could redesign im2bw together with graythresh, I would probably make the single-input syntax im2bw(I) use graythresh behind the scenes to compute the threshold automatically.

That design would be more convenient than it is today, because you could type im2bw(I) instead of im2bw(I, graythresh(I)), and it would also be more flexible because you would have access to smaller computational pieces.

The function edge has a similar problem. Several of the supported edge detection methods, such as Sobel and Roberts, use the gradient magnitude. The gradient magnitude is computed within edge, but there's no separate toolbox function for computing it. The toolbox and MATLAB have the low-level functions and operators that can be used to compute the gradient magnitude (fspecial, imfilter, ^2, sqrt), and the high-level function edge uses the gradient magnitude, but there's no function in the middle that conveniently computes the gradient magnitude for you.

I mention these examples to encourage you to think about your own approach to breaking down your computations into functions.