Book Image

Hands-On Computer Vision with Julia

By : Dmitrijs Cudihins
Book Image

Hands-On Computer Vision with Julia

By: Dmitrijs Cudihins

Overview of this book

Hands-On Computer Vision with Julia is a thorough guide for developers who want to get started with building computer vision applications using Julia. Julia is well suited to image processing because it’s easy to use and lets you write easy-to-compile and efficient machine code. . This book begins by introducing you to Julia's image processing libraries such as Images.jl and ImageCore.jl. You’ll get to grips with analyzing and transforming images using JuliaImages; some of the techniques discussed include enhancing and adjusting images. As you make your way through the chapters, you’ll learn how to classify images, cluster them, and apply neural networks to solve computer vision problems. In the concluding chapters, you will explore OpenCV applications to perform real-time computer vision analysis, for example, face detection and object tracking. You will also understand Julia's interaction with Tesseract to perform optical character recognition and build an application that brings together all the techniques we introduced previously to consolidate the concepts learned. By end of the book, you will have understood how to utilize various Julia packages and a few open source libraries such as Tesseract and OpenCV to solve computer vision problems with ease.
Table of Contents (11 chapters)
9
Assessments

Cropping, scaling, and resizing

Now that you know how to load and preview your image, it is time to start working on content. Three of the most frequent activities you will do when working with images are as follows:

  • Crop: Select a specific area of an image
  • Resize: Change the size of an image without keeping the proportions
  • Scale: Enlarge or shrink an image while keeping the proportions

Cropping an image

Let's go back to the image with the two cats we previewed recently. Here, we will create a new picture, which will only contain the cat on the right:

Our first step will be to identify an area of interest. We will do this by loading the image to Julia and checking its width and height:

  using Images, ImageView
source_image = load("sample-images/cats-3061372_640.jpg");
size(source_image)

The size function will output (360, 640), which stands for 360px in height (y-axis) and 640px in width (x-axis). Both coordinates start from the top-left corner.

I have run a number of experiments and identified an area we are interested in—the height from 100 to 290 and the width from 280 to 540. You can try playing around with the following code to see how changing the region will affect the output:

  cropped_image = img[100:290, 280:540];
imshow(cropped_image)

This will result in the following image being created and stored in the cropped_image variable. This will also allocate memory so that you can store the newly created image:

Images are vertical-major, which means that this first index corresponds to the vertical axis and the second to the horizontal axis. This might be different from other programming languages.

There is also another way to create a cropped image, which is by creating a view to the original image. Views don't create a new object or allocate memory, they just point to the original image (or array). They are great when you want to analyze or change a specific part of the picture without interfering with the rest of it:

  cropped_image_view = view(img, 100:290, 280:540);
imshow(cropped_image_view)

If you run the preceding code, you will see that it returns an identical result. You can also save the image to disk without any problems.

Resizing an image

Image resizing is the process of changing an image's size without keeping proportions. This is done by calling the imresize function and supplying a new width and height.

Let's take our image with the cats as an example and resize it to 100 x 250 so that we can see what has changed:

We will use our classic code and load the image from disk:

  using Images, ImageView
source_image = load("sample-images/cats-3061372_640.jpg");
resized_image = imresize(source_image, (100, 250));
imshow(resized_image);

You should be able to see an image of a smaller size. It has a width of 250 pixels and a height of 100 pixels:

A typical example would be to resize an image to fit a square. You would need to pass the width and height as equal values:

  using Images, ImageView
source_image = load("sample-images/cats-3061372_640.jpg");
resized_image = imresize(source_image, (200, 200));
imshow(resized_image);

This would result in an image like this:

Scaling an image

But what if you want to create a thumbnail and keep the original proportions? You will need to scale the image.

Image scaling is the process of changing the size of an image and saving the original proportions. If in the previous section, we manually picked the width and height, we will now calculate it.

Scaling by percentage

Let's start by scaling the image using percentages. Let's say we want to scale the image to be 60% of the original size:

  using Images, ImageView
source_image = load("sample-images/cats-3061372_640.jpg");
scale_percentage = 0.6
new_size = trunc.(Int, size(source_image) .* scale_percentage)
resized_image = imresize(source_image, new_size)
imshow(resized_image);

We have done the following:

  • We have loaded the image using the load function from the Images package
  • We have defined the scaling percentage in the scale_percentage variable
  • We have calculated the new_size by first multiplying the current size by our proportion and then converting the float values to int
  • We have resized the image using the new_size values

The resulting image is neat and tidy. All of the proportions have been saved:

Don't forget that you can scale the image upward or downward if you so desire.

Scaling to a specific dimension

It is very common to scale your image to a given width and adapt the height automatically or vice versa.

There are multiple ways to approach this problem, but the most straightforward option would be to reuse and extend the code we wrote when scaling by percentage.

Given the original dimension and desired width, what would be the easiest way to calculate the change in percentage? That's correct—just divide the desired width or height by the original.

Let's assume we want to fix our width to 200 and calculate the value for scale_percentage:

  new_width = 200
scale_percentage = new_width / size(source_image)[2]

Let's put it all together:

  using Images, ImageView
source_image = load("sample-images/cats-3061372_640.jpg");
new_width = 200
scale_percentage =
new_width / size(source_image)[2]
new_size = trunc.(Int, size(source_image) .* scale_percentage)
resized_image = imresize(source_image, new_size)
imshow(resized_image);

We have updated our scale by percentage solution to calculate scale_percentage dynamically based on a change in one of the dimensions.

Remember: size(source_image)[1] corresponds to height, while size(source_image)[2] corresponds to width.

Scaling by two-fold

This is a bonus section for scaling/resizing. The JuliaImages package has a very useful function called somepkg(restrict), which reduces the size of an image by two-fold along the dimensions specified. In other words, it scales the image by 50%.

restrict can be run in three ways:

  • Without an additional argument—the image will become twice as small in width and height
  • Sending 1 as an argument will make the height twice as small
  • Sending 2 as an argument will make the width twice as small

Let's run a demo. Try sending 1 as an additional argument so that we decrease the height by 50%:

Consider the following code:

  using Images
source_image
= load("sample-images/cats-3061372_640.jpg");
resized_image = restrict(source_image, 1); # height
imshow(resized_image);