In this tutorial, you will learn how to translate and shift images using OpenCV.
Translation is the shifting of an image along the x- and y-axis. To translate an image using OpenCV, we must:
- Load an image from disk
- Define an affine transformation matrix
- Apply the
cv2.warpAffine
function to perform the translation
This sounds like a complicated process, but as you will see, it can all be done in only two lines of code!
To learn how to translate images with OpenCV, just keep reading.
Looking for the source code to this post?
Jump Right To The Downloads SectionOpenCV Image Translation
In the first part of this tutorial, we will discuss what a translation matrix is and how we can define it using OpenCV and NumPy.
From there, we will configure our development environment and review our project directory structure.
With our project directory structure reviewed, we will move on to implement a Python script to perform translation with OpenCV, opencv_translate.py
.
We will review this script in detail, along with our results generated by the script.
By the end of this guide, you will understand how to perform image translation using OpenCV.
Defining a translation matrix with OpenCV
To perform image translation with OpenCV, we first need to define a 2 x 3 matrix called an affine transformation matrix:
For the purposes of translation, all we care about are the and values:
- Negative values for the value will shift the image to the left
- Positive values for shifts the image to the right
- Negative values for shifts the image up
- Positive values for will shift the image down
For example, let’s suppose we want to shift an image 25 pixels to the right and 50 pixels down. Our translation matrix would look like the following (implemented as a NumPy array):
M = np.float32([ [1, 0, 25], [0, 1, 50] ])
Now, if we want to shift an image 7 pixels to the left and 23 pixels up, our translation matrix would look like the following:
M = np.float32([ [1, 0, -7], [0, 1, -23] ])
And as a final example, let’s suppose we want to translate our image 30 pixels to the left and 12 pixels down:
M = np.float32([ [1, 0, -30], [0, 1, 12] ])
As you can see, defining our affine transformation matrix for image translation is quite easy!
And once our transformation matrix is defined, we can simply perform the image translation using the cv2.warpAffine
function, like so:
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
We will see a complete example of defining our image translation matrix and applying the cv2.warpAffine
function later in this guide.
Configuring your development environment
To follow along with this guide, you need to have the OpenCV library installed on your system.
Luckily, OpenCV is pip-installable:
$ pip install opencv-contrib-python
If you need help configuring your development environment for OpenCV, I highly recommend that you read my pip install OpenCV guide — it will have you up and running in a matter of minutes.
Having problems configuring your development environment?
All that said, are you:
- Short on time?
- Learning on your employer’s administratively locked system?
- Wanting to skip the hassle of fighting with the command line, package managers, and virtual environments?
- Ready to run the code right now on your Windows, macOS, or Linux system?
Then join PyImageSearch Plus today!
Gain access to Jupyter Notebooks for this tutorial and other PyImageSearch guides that are pre-configured to run on Google Colab’s ecosystem right in your web browser! No installation required.
And best of all, these Jupyter Notebooks will run on Windows, macOS, and Linux!
Project structure
Before we can perform image translation with OpenCV, let’s first review our project directory structure:
$ tree . --dirsfirst . ├── opencv_logo.png └── opencv_translate.py 0 directories, 2 files
We have a single Python script, opencv_translate.py
, which we will be reviewing in detail.
This script will load the opencv_logo.png
image from disk and then translate/shift it using the OpenCV library.
Image translation with OpenCV
Translation is the shifting of an image along the x- and y-axis. Using translation, we can shift an image up, down, left, or right, along with any combination of the above.
Mathematically, we define a translation matrix, M, that we can use to translate an image:
This concept is better explained through some code:
# import the necessary packages import numpy as np import argparse import imutils import cv2
On Lines 2-5, we simply import the packages we will make use of. At this point, using NumPy, argparse
, and cv2
should feel commonplace.
However, I am introducing a new package here: imutils. This isn’t a package included in NumPy or OpenCV. Rather, it’s a library that I personally wrote containing a handful of “convenience” methods to more easily perform common tasks like translation, rotation, and resizing (and with less code).
If you don’t already have imutils
installed on your machine, you can install it with pip
:
$ pip install imutils
Let’s now parse our command line arguments:
# construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", type=str, default="opencv_logo.png", help="path to the input image") args = vars(ap.parse_args())
We only need a single argument, --image
, which points to the input image we want to load from disk and apply OpenCV translation operations to. By default, we will set the --image
argument to be opencv_logo.png
.
Let’s now load our image from disk and perform our first translation:
# load the image and display it to our screen image = cv2.imread(args["image"]) cv2.imshow("Original", image) # shift the image 25 pixels to the right and 50 pixels down M = np.float32([[1, 0, 25], [0, 1, 50]]) shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) cv2.imshow("Shifted Down and Right", shifted)
Lines 14 and 15 load our input image
from disk and then display it to our screen:
The first actual translation takes place on Lines 18-20, where we start by defining our translation matrix, M
.
This matrix tells us how many pixels to the left or right our image will be shifted, and then how many pixels up or down the image will be shifted, again keeping in mind that the translation matrix has the form:
M = np.float32([ [1, 0, shiftX], [0, 1, shiftY] ])
Our translation matrix M is defined as a floating point array — this is important because OpenCV expects this matrix to be of floating point type. The first row of the matrix is , where is the number of pixels we will shift the image left or right. Negative values of will shift the image to the left, and positive values will shift the image to the right.
Then, we define the second row of the matrix as , where is the number of pixels we will shift the image up or down. Negative values of will shift the image up, and positive values will shift the image down.
Using this notation, on Line 18, we can see that and , indicating that we are shifting the image 25 pixels to the right and 50 pixels down.
Now that we have our translation matrix defined, the actual translation takes place on Line 19 using the cv2.warpAffine
function. The first argument is the image we wish to shift, and the second argument is our translation matrix, M
. Finally, we manually supply the image’s dimensions (width and height) as the third argument.
Line 20 displays the results of the translation, which we can see below:
Notice how the image has clearly been “shifted” down and to the right.
Let’s examine another example of image translation with OpenCV.
# now, let's shift the image 50 pixels to the left and 90 pixels # up by specifying negative values for the x and y directions, # respectively M = np.float32([[1, 0, -50], [0, 1, -90]]) shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0])) cv2.imshow("Shifted Up and Left", shifted)
Line 25 sets and , implying that we are shifting the image 50 pixels to the left and 90 pixels up. The image is shifted left and up rather than right and down because we are providing negative values for both and .
Figure 6 shows the output of supplying negative values for both and :
Again, notice how our image is “shifted” to the left 50 pixels and up 90 pixels.
However, manually constructing this translation matrix and calling the cv2.warpAffine
method takes a bit of effort — and it’s not necessarily pretty code either!
This is where my imutils
package comes in. Instead of having to define our matrix M
and make a call to cv2.warpAffine
each time we want to translate an image, we can instead call imutils.translate
to take care of the operation for us:
# use the imutils helper function to translate the image 100 pixels # down in a single function call shifted = imutils.translate(image, 0, 100) cv2.imshow("Shifted Down", shifted) cv2.waitKey(0)
The output of the translation operation can be seen in Figure 7:
The benefit of using imutils.translate
is cleaner code — the output of imutils.translate
versus cv2.warpAffine
will be the same, regardless.
Note: If you are interested in seeing the implementation of the imutils.translate
function, simply refer to my GitHub repo.
OpenCV image translation results
To perform image translation with OpenCV, be sure to access the “Downloads” section of this tutorial to retrieve the source code and example image.
You can then execute the following command:
$ python opencv_translate.py
Your results should look like mine from the previous section.
What's next? I recommend PyImageSearch University.
30+ total classes • 39h 44m video • Last updated: 12/2021
★★★★★ 4.84 (128 Ratings) • 3,000+ Students Enrolled
I strongly believe that if you had the right teacher you could master computer vision and deep learning.
Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?
That’s not the case.
All you need to master computer vision and deep learning is for someone to explain things to you in simple, intuitive terms. And that’s exactly what I do. My mission is to change education and how complex Artificial Intelligence topics are taught.
If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to successfully and confidently apply computer vision to your work, research, and projects. Join me in computer vision mastery.
Inside PyImageSearch University you'll find:
- ✓ 30+ courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 30+ Certificates of Completion
- ✓ 39h 44m on-demand video
- ✓ Brand new courses released every month, ensuring you can keep up with state-of-the-art techniques
- ✓ Pre-configured Jupyter Notebooks in Google Colab
- ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
- ✓ Access to centralized code repos for all 500+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
Summary
In this tutorial, you learned how to perform image translation using OpenCV.
You accomplished this task by first defining an affine transformation matrix:
You then specified how you wanted to shift the image:
- Negative values for the value will shift the image to the left
- Positive values for shifts the image to the right
- Negative values for shifts the image up
- Positive values for will shift the image down
While performing image translation with OpenCV requires only two lines of code, it’s not exactly the most “pretty” code in the world. For convenience, you can use the imutils.translate
function to perform image translation in a single, concise, and readable function call.
To download the source code to this post (and be notified when future tutorials are published here on PyImageSearch), simply enter your email address in the form below!
Download the Source Code and FREE 17-page Resource Guide
Enter your email address below to get a .zip of the code and a FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning. Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!
Comment section
Hey, Adrian Rosebrock here, author and creator of PyImageSearch. While I love hearing from readers, a couple years ago I made the tough decision to no longer offer 1:1 help over blog post comments.
At the time I was receiving 200+ emails per day and another 100+ blog post comments. I simply did not have the time to moderate and respond to them all, and the sheer volume of requests was taking a toll on me.
Instead, my goal is to do the most good for the computer vision, deep learning, and OpenCV community at large by focusing my time on authoring high-quality blog posts, tutorials, and books/courses.
If you need help learning computer vision and deep learning, I suggest you refer to my full catalog of books and courses — they have helped tens of thousands of developers, students, and researchers just like yourself learn Computer Vision, Deep Learning, and OpenCV.
Click here to browse my full catalog.