In this tutorial, you will learn how to rotate an image using OpenCV. Additionally, I’ll also show you how to rotate an image using my two convenience functions from the imutils library, imutils.rotate
and imutils.rotate_bound
, which make rotating images with OpenCV easier (and requires less code).

Previously, we learned how to translate (i.e., shift) an image, up, down, left, and right (or any combination). We are now moving on to our next image processing topic — rotation.
Rotation is exactly what it sounds like: rotating an image by some angle, . We’ll use
to represent how many degrees (not radians) we are rotating an image.
I’ll also show you some techniques that will make rotating images with OpenCV easier.
To learn how to rotate images with OpenCV, just keep reading.
OpenCV Rotate Image
In the first part of this tutorial, we’ll discuss how OpenCV rotates images and the functions available for rotation.
From there, we’ll configure our development environment and review our project directory structure.
I’ll then show you three ways to rotate an image with OpenCV:
- Use the
cv2.rotate
function: Built into OpenCV, but requires constructing a rotation matrix and explicitly applying an affine warp, making the code more verbose. - Use the
imutils.rotate
function: Part of my imutils library. Makes it possible to rotate an image with OpenCV in a single function call. - Use the
imutils.rotate_bound
function: Also part of my imutils library. Ensures that no part of the image is cut off during rotation.
We’ll wrap up this tutorial by reviewing our OpenCV rotation results.
How does OpenCV rotate images?
Similar to translation, and perhaps unsurprisingly, rotation by an angle can be defined by constructing a matrix, M, in the form:
Given an (x, y)-Cartesian plane, this matrix can be used to rotate a vector degrees (counterclockwise) about the origin. In this case, the origin is normally the center of the image; however, in practice, we can define any arbitrary (x, y)-coordinate as our rotation center.
From the original image, I, the rotated image, R, is then obtained by simple matrix multiplication:
However, OpenCV also provides the ability to (1) scale (i.e., resize) an image and (2) provide an arbitrary rotation center around which to perform the rotation.
Our modified rotation matrix, M, is thus:
where and
and
and
are the respective (x, y)-coordinates around which the rotation is performed.
If the mathematics is starting to get a bit overwhelming, no worries — we’ll jump into some code that will make these concepts much clearer.
Configuring your development environment
To follow 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 systems?
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 implement rotation with OpenCV, let’s first review our project directory structure.
Be sure you access the “Downloads” section of this tutorial to retrieve the source code and example images, and from there, take a peek inside:
$ tree . --dirsfirst . ├── opencv_logo.png └── opencv_rotate.py 0 directories, 2 files
Here, we have opencv_rotate.py
. This script will load opencv_logo.png
(or any other image you choose) and then apply a series of rotations to it, thereby demonstrating how to perform rotation with OpenCV.
Implementing image rotation with OpenCV
We are now ready to implement image rotation with OpenCV.
Open the opencv_rotate.py
file in your project directory structure and insert the following code:
# import the necessary packages import argparse import imutils import cv2 # 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())
Lines 2-4 import our required Python packages. We’ll use argparse
for command line arguments, imutils for my set of OpenCV convenience functions (namely the imutils.rotate
and imutils.rotate_bound
methods), and cv2
for our OpenCV bindings.
We only have a single command line argument, --image
, which is the path to the input image we want to rotate (which we default to opencv_logo.png
).
Next, let’s load our input image from disk and do some basic resizing:
# load the image and show it image = cv2.imread(args["image"]) cv2.imshow("Original", image) # grab the dimensions of the image and calculate the center of the # image (h, w) = image.shape[:2] (cX, cY) = (w // 2, h // 2) # rotate our image by 45 degrees around the center of the image M = cv2.getRotationMatrix2D((cX, cY), 45, 1.0) rotated = cv2.warpAffine(image, M, (w, h)) cv2.imshow("Rotated by 45 Degrees", rotated) # rotate our image by -90 degrees around the image M = cv2.getRotationMatrix2D((cX, cY), -90, 1.0) rotated = cv2.warpAffine(image, M, (w, h)) cv2.imshow("Rotated by -90 Degrees", rotated)
We start by loading our input image and displaying it on our screen:

When we rotate an image, we need to specify around which point we want to rotate. In most cases, you will want to rotate around the center of an image; however, OpenCV allows you to specify any arbitrary point you want to rotate around (as detailed above).
Let’s just go ahead and rotate about the center of the image. Lines 18 and 19 grab the width and height of the image and then divide each component by 2
to determine the center of the image.
Just as we define a matrix to translate an image, we also define a matrix to rotate the image. Instead of manually constructing the matrix using NumPy (which can be a bit tedious), we’ll just make a call to the cv2.getRotationMatrix2D
method on Line 22.
The cv2.getRotationMatrix2D
function takes three arguments. The first argument is the point where we rotate the image (in this case, the center cX
and cY
of the image).
We then specify , the number of (counterclockwise) degrees by which we will rotate the image. In this case, we are going to rotate the image 45 degrees.
The last argument is the scale of the image. We haven’t discussed resizing an image yet, but here you can specify a floating-point value, where 1.0 means the same, original dimensions of the image are used. However, if you specified a value of 2.0, the image doubles in size — similarly, a value of 0.5 halves the image size.
Once we have our rotation matrix M
from the cv2.getRotationMatrix2D
function, we can apply the rotation to our image using the cv2.warpAffine
method on Line 23.
The first argument to this function is the image
we want to rotate. We then specify our rotation matrix M
and the output dimensions (width and height) of our image. Line 24 then shows our image rotated by 45 degrees:

Lines 27-29 do the same, but this time rotating an image -90
degrees (clockwise) about the center cX
and cY
coordinates.
Note: Remember that in OpenCV, positive degrees specify counterclockwise rotation while negative degrees indicate clockwise rotation. Keep this in mind; otherwise, you may be confused when applying rotation to your own images!
Figure 4 displays the output of these resizing operations:

As you can see, our image has been rotated. Take a second to note that OpenCV does not automatically allocate space for our entire rotated image to fit into the frame.
This is the intended behavior! If you want the entire image to fit into view after the rotation, you’ll need to modify the width and height, denoted as (w, h)
in the cv2.warpAffine
function. As we’ll see later in this script, the imutils.rotate_bound
function takes care of all that for us.
Until this point, we have only rotated an image about the center of the image. But what if we wanted to rotate the image about some arbitrary point?
Let’s go ahead and see how this can be accomplished:
# rotate our image around an arbitrary point rather than the center M = cv2.getRotationMatrix2D((10, 10), 45, 1.0) rotated = cv2.warpAffine(image, M, (w, h)) cv2.imshow("Rotated by Arbitrary Point", rotated)
By now, this code should look fairly standard for performing a rotation. However, take note of the first argument of the cv2.getRotationMatrix2D
function. Here, we indicate that we want to rotate the image around x = 10, y = 10, or approximately the top-left corner of the image.
When we apply this rotation, our output image looks like this:

We can see that the center of the rotation is no longer the center of the image.
However, just like translating an image, making calls to both cv2.getRotationMatrix2D
and cv2.warpAffine
can become quite tedious — not to mention it also makes our code substantially more verbose.
Let’s reduce the amount of code we need to write by calling imutils.rotate
, a convenience function that wraps calls to cv2.getRotationMatrix2D
and cv2.warpAffine
:
# use our imutils function to rotate an image 180 degrees rotated = imutils.rotate(image, 180) cv2.imshow("Rotated by 180 Degrees", rotated)
Here, we rotate our image by 180 degrees, but we could make our code substantially less verbose by using the rotate
method.
Figure 6 displays the output of our rotation:

As you saw in previous examples, OpenCV does not allocate enough space to store the entire image if part of the image is cut off during the rotation process.
The way around that is to use the imutils.rotate_bound
function:
# rotate our image by 33 degrees counterclockwise, ensuring the # entire rotated image still renders within the viewing area rotated = imutils.rotate_bound(image, -33) cv2.imshow("Rotated Without Cropping", rotated) cv2.waitKey(0)
This function will automatically expand the image array such that the entire rotated image fits within it.
The results of applying the rotate_bound
function can be seen in Figure 7, where we rotate an image 33 degrees counterclockwise:

And that’s all there is to it!
Note: The imutils.rotate_bound
function inverts the relationship between positive/negative values and clockwise/counterclockwise rotation. Here, negative values will rotate counterclockwise while positive values will rotate clockwise.
When applying image rotation with OpenCV, you have three options:
cv2.getRotationMatrix2D
andcv2.warpAffine
imutils.rotate
imutils.rotate_bound
Mix and match them as you see fit for your own applications.
OpenCV image rotation results
To rotate images with OpenCV, be sure to access the “Downloads” section of this tutorial to retrieve the source code and example images.
We’ve already reviewed the results of this script in the previous section, but when you’re ready to run the script for yourself, you can use the following command:
$ python opencv_rotate.py
Your OpenCV rotation results should match mine from the previous section.
What’s next?

Would you enjoy learning how to successfully and confidently apply OpenCV to your projects?
Are you worried that configuring your development environment for Computer Vision, Deep Learning, and OpenCV will be too challenging, resulting in confusing, hard to debug error messages?
Concerned that you’ll get lost sifting through endless tutorials and video guides as you struggle to master Computer Vision?
No problem, because I’ve got you covered. PyImageSearch University is your chance to learn from me at your own pace.
You’ll find everything you need to master the basics (like we did together in this tutorial) and move on to advanced concepts.
Don’t worry about your operating system or development environment. I’ve got you covered with pre-configured Jupyter Notebooks in Google Colab for every tutorial on PyImageSearch, including Jupyter Notebooks for our new weekly tutorials as well!
Best of all, these Jupyter Notebooks will run on your machine, regardless of whether you are using Windows, macOS, or Linux! Irrespective of the operating system used, you will still be able to follow along and run the code in every lesson (all inside the convenience of your web browser).
Additionally, you can massively accelerate your progress by watching our video lessons accompanying each post. Every lesson at PyImageSearch University includes a detailed, step-by-step video guide.
You may feel that learning Computer Vision, Deep Learning, and OpenCV is too hard. Don’t worry; I’ll guide you gradually through each lecture and topic, so we build a solid foundation and you grasp all the content.
When you think about it, PyImageSearch University is almost an unfair advantage compared to self-guided learning. You’ll learn more efficiently and master Computer Vision faster.
Oh, and did I mention you’ll also receive Certificates of Completion as you progress through each course at PyImageSearch University?
I’m sure PyImageSearch University will help you master OpenCV drawing and all the other computer vision skills you will need. Why not join today?
Summary
In this tutorial, you learned how to rotate an image using OpenCV. To rotate an image by an arbitrary angle with OpenCV, we need to:
- Construct a 2D rotation matrix using the
cv2.getRotationMatrix2D
function - Perform an affine warp using the
cv2.warpAffine
function, supplying our input image and computed rotation matrix,M
The result is an image that has been rotated degrees.
The problem with using OpenCV’s functions to rotate an image is that they require two lines of code — one to construct the rotation matrix and then another to perform the transform.
To help make image rotation with OpenCV easier, I’ve implemented two methods in my imutils library:
imutils.rotate
: Performs OpenCV image rotation in a single line of code.imutils.rotate_bound
: Also performs image rotation with OpenCV but ensures the image (after rotation) is still viewable, and no parts of the image are cut off.
I suggest you get familiar with all three rotation techniques as you’ll likely use each of them when developing your own respective image processing pipelines.
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!
The post OpenCV Rotate Image appeared first on PyImageSearch.