psst... I heard you might be interested in bitcoin, blockchains and cryptocurrencies.

If so, you might be interested in our new tutorial page, LearningBlockchains.com! It has great lessons on using crypto, coding for it, and more lessons are coming all the time.

# Arrays and working with Images

In this tutorial, we are going to work with an image, in order to visualise changes to an array. Arrays are powerful structures, as we saw briefly in the previous tutorial. Generating interesting arrays can be difficult, but images provide a great option.

First, download this image (Right Click, and look for an option like “Save Image As…”) to your computer.

This image comes from Wikimedia Commons, by user Uoaei1.

To work with images, we will need matplotlib. We will also need the pillow library, which overrides the deprecated PIL library for working with images. You can install both in your environment using Anaconda’s installation method:

conda install matplotlib pillow

To load the image, we use matplotlib’s image module:

The above code reads in the image as a NumPy array, and prints out the size. Note that the filename needs to be a full path (absolute or relative) to the downloaded image file.

You’ll see the output, which is (5528, 3685, 3). This means the image is 5528 pixels high, 3685 pixels wide, and 3 colors “deep”.

You can view the current image using pyplot, like so:

Now that we have our image, lets use TensorFlow to do some changes to it.

## Geometric Manipulations

The first transformation we will perform is a transpose, turning the image 90 degrees counter-clockwise. The full program is below, most of which you have seen.

The result of the transpose operation:

The new bit is this line:

This line uses TensorFlow’s transpose method, swapping the axes 0 and 1 around using the perm parameter (axis 2 stays where it is).

The next manipulation we will do is a flip (left-right), swapping the pixels from one side to another. TensorFlow has a method for this called reverse_sequence, but the signature is a bit odd. Here is what the documentation says (from that page):

##### tf.reverse(tensor, axis, name=None)

Reverses specific dimensions of a tensor.

NOTE tf.reverse has now changed behavior in preparation for 1.0. tf.reverse_v2 is currently an alias that will be deprecated before TF 1.0. Given a tensor, and a int32 tensor axis representing the set of dimensions of tensor to reverse. This operation reverses each dimension i for which there exists j s.t. axis[j] == i. tensor can have up to 8 dimensions. The number of dimensions specified in axis may be 0 or more entries. If an index is specified more than once, a InvalidArgument error is raised.

For this function, it can be best thought of as:

1. Iterate through the array according to batch_dim. Setting batch_dim=0 means we go through the rows (top to bottom).
2. For each item in the iteration
• Slice a second dimension, denoted by seq_dim. Setting seq_dim=1 means we go through the columns (left to right).
• The slice for the nth item in the iteration is denoted by the nth item in seq_lengths

Lets see it in action:

The new bit is this line:

It iterates over the image top to bottom (along its height), and slices left to right (along its width). From here, it then takes a slice of size width, where width is the width of the image.

The code np.ones((height,)) * width creates a NumPy array filled with the value width. This is not very efficient! Unfortunately, at time of writing, it doesn’t appear that this function allows you to specify just a single value.

The result of the “fliplr” operation:

# Exercises

### Stuck? Looking for more content?

If you are looking for solutions on the exercises, or just want to see how I solved them, then our solutions bundle is what you are after. Buying the bundle gives you free updates for life - meaning when we add a new lesson, you get an updated bundle with the solutions. It's just \$7, and it also helps us to keep running the site with free lessons.

1) Combine the transposing code with the flip code to rotate clock wise.

2) Currently, the flip code (using reverse_sequence) requires width to be precomputed. Look at the documentation for the tf.shape function, and use it to compute the width of the x variable within the session.

3) Perform a “flipud”, which flips the image top-to-bottom.

4) Compute a “mirror”, where the first half of the image is copied, flipped (l-r) and then copied into the second half.