In this tutorial, you will learn how to apply bitwise AND, OR, XOR, and NOT with OpenCV.
In our previous tutorial on Cropping with OpenCV, you learned how to crop and extract a Region of Interest (ROI) from an image.
In that particular example, our ROI had to be rectangular . . . but what if you wanted to crop a non-rectangular region?
What would you do then?
The answer is to apply both bitwise operations and masking (we’ll discuss how to do that in our guide on image masking with OpenCV).
For now, we’ll cover the basic bitwise operations — and in the next blog post, we’ll learn how to utilize these bitwise operations to construct masks.
To learn how to apply bitwise operators with OpenCV, just keep reading.
OpenCV Bitwise AND, OR, XOR, and NOT
Before we get too far into this tutorial, I’m going to assume that you understand the four basic bitwise operators:
- XOR (exclusive OR)
If you’ve never worked with bitwise operators before, I suggest you read this excellent (and highly detailed) guide from RealPython.
While you don’t have to review that guide, I find that readers who understand the basics of applying bitwise operators to digits can quickly grasp bitwise operators applied to images.
Regardless, computer vision and image processing are highly visual, and I’ve crafted the examples in this tutorial to ensure you understand how bitwise operators are applied to images with OpenCV.
We’ll start this guide by configuring our development environment and then reviewing our project directory structure.
From there, we’ll implement a Python script to perform the AND, OR, XOR, and NOT bitwise operators with OpenCV.
We’ll conclude this guide with a discussion of our results.
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!
Ready to learn how to apply bitwise operators using OpenCV?
Great, let’s get started.
Be sure to use the “Downloads” section of this guide to access the source code, and from there, take a look at our project directory structure:
$ tree . --dirsfirst . └── opencv_bitwise.py 0 directories, 1 file
We have just a single script to review today,
opencv_bitwise.py, which will apply the AND, OR, XOR, and NOR operators to example images.
By the end of this guide, you’ll have a good understanding of how to apply bitwise operators with OpenCV.
Implementing OpenCV AND, OR, XOR, and NOT bitwise operators
In this section, we will review four bitwise operations: AND, OR, XOR, and NOT. While very basic and low level, these four operations are paramount to image processing — especially when working with masks later in this series.
Bitwise operations function in a binary manner and are represented as grayscale images. A given pixel is turned “off” if it has a value of zero, and it is turned “on” if the pixel has a value greater than zero.
Let’s proceed and jump into some code:
# import the necessary packages import numpy as np import cv2 # draw a rectangle rectangle = np.zeros((300, 300), dtype="uint8") cv2.rectangle(rectangle, (25, 25), (275, 275), 255, -1) cv2.imshow("Rectangle", rectangle) # draw a circle circle = np.zeros((300, 300), dtype = "uint8") cv2.circle(circle, (150, 150), 150, 255, -1) cv2.imshow("Circle", circle)
For the first few lines of code import, the packages we will need include: NumPy and our OpenCV bindings.
We initialize our rectangle image as a 300 x 300 NumPy array on Line 6. We then draw a 250 x 250 white rectangle at the center of the image.
Similarly, on Line 11, we initialize another image to contain our circle, which we draw on Line 12 again centered in the middle of the image, with a radius of 150 pixels.
Figure 2 displays our two shapes:
If we consider these input images, we’ll see that they only have two pixel intensity values — either the pixel is
0 (black) or the pixel is greater than zero (white). We call images that only have two pixel intensity values binary images.
Another way to think of binary images is like an on/off switch in our living room. Imagine each pixel in the 300 x 300 image is a light switch. If the switch is off, then the pixel has a value of zero. But if the pixel is on, it has a value greater than zero.
In Figure 2, we can see the white pixels that comprise the rectangle and circle, respectively, all have pixel values that are on, whereas the surrounding pixels have a value of off.
Keep this notion of on/off as we demonstrate bitwise operations:
# a bitwise 'AND' is only 'True' when both inputs have a value that # is 'ON' -- in this case, the cv2.bitwise_and function examines # every pixel in the rectangle and circle; if *BOTH* pixels have a # value greater than zero then the pixel is turned 'ON' (i.e., 255) # in the output image; otherwise, the output value is set to # 'OFF' (i.e., 0) bitwiseAnd = cv2.bitwise_and(rectangle, circle) cv2.imshow("AND", bitwiseAnd) cv2.waitKey(0)
As I mentioned above, a given pixel is turned “on” if it has a value greater than zero, and it is turned “off” if it has a value of zero. Bitwise functions operate on these binary conditions.
To utilize bitwise functions, we assume (in most cases) that we are comparing two pixels (the only exception is the NOT function). We’ll compare each of the pixels and then construct our bitwise representation.
Let’s quickly review our binary operations:
- AND: A bitwise AND is true if and only if both pixels are greater than zero.
- OR: A bitwise OR is true if either of the two pixels is greater than zero.
- XOR: A bitwise XOR is true if and only if one of the two pixels is greater than zero, but not both.
- NOT: A bitwise NOT inverts the “on” and “off” pixels in an image.
On Line 21, we apply a bitwise AND to our rectangle and circle images using the
cv2.bitwise_and function. As the list above mentions, a bitwise AND is true if and only if both pixels are greater than zero. The output of our bitwise AND can be seen in Figure 3:
We can see that edges of our square are lost — this makes sense because our rectangle does not cover as large of an area as the circle, and thus both pixels are not “on.”
Let’s now apply a bitwise OR:
# a bitwise 'OR' examines every pixel in the two inputs, and if # *EITHER* pixel in the rectangle or circle is greater than 0, # then the output pixel has a value of 255, otherwise it is 0 bitwiseOr = cv2.bitwise_or(rectangle, circle) cv2.imshow("OR", bitwiseOr) cv2.waitKey(0)
We apply a bitwise OR on Line 28 using the
cv2.bitwise_or function. A bitwise OR is true if either of the two pixels is greater than zero. Take a look at the output of the bitwise OR in Figure 4:
In this case, our square and rectangle have been combined.
Next is the bitwise XOR:
# the bitwise 'XOR' is identical to the 'OR' function, with one # exception: the rectangle and circle are not allowed to *BOTH* # have values greater than 0 (only one can be 0) bitwiseXor = cv2.bitwise_xor(rectangle, circle) cv2.imshow("XOR", bitwiseXor) cv2.waitKey(0)
We apply the bitwise XOR on Line 35 using the
An XOR operation is true if and only if one of the two pixels is greater than zero, but both pixels cannot be greater than zero.
The output of the XOR operation is displayed in Figure 5:
Here, we see that the center of the square has been removed. Again, this makes sense because an XOR operation cannot have both pixels greater than zero.
Finally, we arrive at the bitwise NOT function:
# finally, the bitwise 'NOT' inverts the values of the pixels; # pixels with a value of 255 become 0, and pixels with a value of 0 # become 255 bitwiseNot = cv2.bitwise_not(circle) cv2.imshow("NOT", bitwiseNot) cv2.waitKey(0)
We apply a bitwise NOT on Line 42 using the
cv2.bitwise_not function. Essentially, the bitwise NOT function flips pixel values. All pixels that are greater than zero are set to zero, and all pixels that are equal to zero are set to
Notice how our circle has been inverted — initially, the circle was white on a black background, and now the circle is black on a white background.
OpenCV bitwise AND, OR, XOR, and NOT results
To perform bitwise operations with OpenCV, be sure to access the “Downloads” section of this tutorial to download the source code.
From there, open a shell and execute the following command:
$ python opencv_bitwise.py
Your output should match mine from the previous section.
Would you like to learn 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 on your own as you struggle to master Computer Vision?
Great, 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 in 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?
In this tutorial, you learned how to perform bitwise AND, OR, XOR, and NOT using OpenCV.
While bitwise operators may not seem useful by themselves, they’re necessary when you start working with alpha blending and masking, a concept that we’ll begin to discuss in another blog post.
Take the time to practice and become familiar with bitwise operations now before proceeding.
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!