73,2 Im plem entation
2. Note that the mandrill image in the output slightly differs from that in the input This is
because the output colour map is created as in cmap on page 122, while the input colour map is
slightly different from that. How to handle colour maps from different sources would be another major problem.
- 1 3 2- fun4 c = T r u e , if i n s i d e = F a l s e , o t h e r w i s e w h e r e i n s i d e = ( x - 6 4 ) " 2 + ( y - 6 4 ) " 2 - 6 0 " 2 < 0 im l Spatial Conditional Function imS fun2 c = 2 55* (2 + 1 / 2 * ( s i n ( x * p i / 3 2 ) + s i n ( y * p i / 3 2 ) ) ) / 4
Figure 7-5 An exam ple spatial conditional
7.5
D is c u s s io n s
7.5.1 Applications of non-pixel images
In this chapter, we have demonstrated a method to combine pixel and non-pixel images as a potential of the utility of lazy functional languages. Because functional languages handle functions as first-class objects, an image expressed as a function can be handled without difficulty and processing such images can be written as function compositions. See the implementation of geometric transformations of f Image (Section 7.3.2). In addition, because of the laziness of the languages pixels are produced from a function image only when they are required. This property is of most benefit when a complicated series of functions are applied to images since no intermediate pixel images are produced.
However, how the technique of handling non-pixel images is useful is left as a subject for further research; the examples shown in this chapter arc very primitive and just to show the possibility. One promising area would be computer graphics as discussed in Section 7.5.3,
because lazy functional languages can manipulate mathematical representations directly and eliminate unnecessary operations in rendering by conducting calculations at only required
resolution. In particular, texture mapping [Heckbert86a] combines geometrically transformed
pixel images and geometric objects; a task for which the method we have proposed could be applicable.
As found in a number of image processing textbooks, it is a general practice that many image processing algorithms are defined in the continuous domain using mathematical functions, then they are converted to the discrete domain and implemented to process pixel images. Lazy functional languages may potentially be useful to bridge this gap.
7.5.2 Integration of fim age and pim age
In the implementation described in this chapter fim ag e and pim age are separate, e.g. see the sub-definitions im l, im2 and im3 in cim on page 131. But ideally, these images should be integrated into one data type and individual image types should be hidden from application programmers. In Miranda this may be done by defining an algebraic data type for a general image which is a tagged union of either fim ag e * or pim age. In Haskell, this may be done
by defining a type d ass for a general image whose instances are fim ag e * and pim age.
7.5.3 H ow to integrate m u ltip le representations
Through the thesis, we have developed quite a few representations of an image. We started with a list of lists (Section 2.2.1) in the naive version. Then, based on the list of lists
representation we attached various parameters, i.e. a list of lists with an origin (Section 3.2.2),
with an origin and length (Section 5.3.1), with an origin and length represented as pairs of x and y elements (Section 5.4.1). We then adopted hierarchical data structures as the basic representation and implemented a binary tree of binary trees with a root position and first step
length (Section 6.42), and a quadtree with a root position and first step length in 2D (Section
6.5.2).
What we have not discussed is how later versions can cope with algorithms defined for
previous versions. The way we developed the representations is fairly ad-hoc, i.e. to implement
a new operation a new parameter is necessary, so attach it. Therefore, for example, convolution
cannot be applied to an image represented for rotation. In order to apply convolution defined in Section 3.5.1 to an image represented in Section 5.4.1, it will be necessary to check whether
- 134-
the rows in the image are horizontal and whether the intervals of pixels and rows are equal to 1. That is, in the row data structure:
((x_origin,y_origin), (xjength,y_length), list_of_pixeIs)
it will be necessary to check whether yjength is 0 and xjength is equal to the length of
list_of_pixels., and also to check if the y_origins in the image form an arithmetic series with 1 as
the increment. If they are, then conversion to a convolvable form would be straightforward. If not, an operation akin to 'display' will be required.
We have used 'display' as the demander of pixel evaluation since the original motivation came from laziness in displaying a transformed pixel image. But now it has turned out that 'display' is to convert an image representation to a form suitable for an operation, such as display. In fact, when an operation involving both pixel and non-pixel images is designed, these images are "displayed" to form 2D lists before the operation is carried out. In this case,
a 2D list happens to be the most naive way (See Chapter 2) to combine the two kinds of images,
and the display functions happen to be available to convert each representation to the common representation.
When an image processing library is to be designed using lazy functional languages, how to choose a good representation is an important issue. This is left as further work. One
possible idea would be to use multiple representations or isomorphic representations [Poole92b]
which cany a number of representations of an image as a form of a tuple, an algebraic data type, or a type class (e.g. in Haskell). A processing algorithm may be defined as a function composition of a conversion of representations and the algorithm itself. Because the system works lazily, until a processing path is specified by the user, no conversions take place. Once a processing path has been defined and input data has been made available, the process proceeds, where conversions from one representation to another take place only when necessary. In this way, it would be possible to integrate various representations.
A similar idea has been presented in [Parsons87a] for graphics applications, e.g. specification of coordinates in cartesian and polar systems and colours specified in any of the equivalent colour models.