#MonthOfJulia Day 38: Imaging
Julia has a few packages aimed at image processing. We’ll start by looking at the TestImages package, which hosts a selection of sample images, then briefly visit the ImageView package before moving onto the Images package, which implements a range of functions for image manipulation.
The TestImages package currently provides 25 sample images, which form a convenient basis for experimentation.
We’ll load the archetypal test image (the November 1972 Playboy centerfold of Lena Söderberg).
Of course, now that we’ve loaded that image, we’ll want to take a look at it. To do that we’ll need the ImageView package.
You can optionally specify the pixel spacing as a parameter to
view(), which then ensures that the aspect ratio of the image is conserved on resizing. There are various other bobs and whistles associated with
view(): you can click-and-drag within the image to zoom in on a particular region; various simple transformations (flipping and rotation) are possible; images can be annotated and multiple images can be arranged on a canvas for simultaneous viewing.
Outside of the test images, an arbitrary image file can be loaded using
imread() from the Images package. Naturally, there are also functions for writing images,
The default representation for the
Image object tells us its dimensions, storage type and colour space. The spatial order indicates that the image data are stored using row major ordering. It’s also possible to specify physical units for the pixel spacing, which is particularly important if you are analysing images where absolute scale matters (for example, medical imaging). There are convenience methods for a few image properties.
We can examine individual pixels within the image using the indexing operator.
Each pixel is of type
RGB (defined in the
Colors package), which encapsulates a tuple giving the proportion of red, green and blue for that pixel. The underlying image data can also be accessed via the
The image can be split into its component colour channels using
Note that the result is a three-dimensional
Array. The spatial order has also changed, which means that the data are now represented using column major ordering. The data are thus effectively transposed.
Simple Image Processing
Kernel-based filtering can be applied using
imfilter_fft(), where the latter is better suited to larger kernels. There’s a variety of helper functions for constructing kernels, like
The effects of the above smoothing operations can be seen below, with the original image on the left, followed by the 3-by-3 and 10-by-10 boxcar filtered versions and finally the Gaussian filtered image.
imgradients() function calculates gradients across the image. You can choose from a set of methods for calculating the gradient. The morphological dilation and erosion operations are available via
Below are the two components of the image gradient calculated using the Sobel operator followed by the results of
The ImageMagick package implements further imaging functionality. If, in the future, it provides an interface to the full functionality on the ImageMagick suite then it will be a truly phenomenal resource. Also worth looking at is the PiecewiseAffineTransforms package which implements a technique for warping portions of an image.