Performing Bitwise Operations on Images using OpenCV

Maximinusjoshus
featurepreneur
Published in
4 min readApr 8, 2021

OpenCV is a library of programming functions mainly aimed at real-time computer vision. In this article, we are going to perform bitwise operations on images using OpenCV.

When do we require bitwise operations to be performed on images?

Bitwise operations are performed on an image when we need to extract only the required parts of the image. Consider a situation, in which we need to extract an irregular-shaped object from an image and paste it on another image. That’s exactly when we use bitwise operations on the image to separate the foreground from the background.

Let us begin with the basics…

And, Or and Not operations on images

OpenCV has inbuilt methods to perform and, or and not operations. They are bitwise_and, bitwise_or, and bitwise_not. Consider the below two black and white images. Let us perform these three operations between these two images and observe the result.

#import opencv
import cv2 as cv
#read the images
img1 = cv.imread('circle.png')
img2 = cv.imread('background.png')
bitwise_AND = cv.bitwise_and(img1, img2)
bitwise_OR = cv.bitwise_or(img1, img2)
bitwise_NOT = cv.bitwise_not(img1)
cv.imshow('img1',img1)
cv.imshow('img2',img2)
cv.imshow('AND',bitwise_AND)
cv.imshow('OR',bitwise_OR)
cv.imshow('NOT',bitwise_NOT)
if cv.waitKey(0) & 0xff == 27:
cv.destroyAllWindows()

The output of the above code snippet will be as follows..

Application of bitwise operations in masking

Bitwise operations are used to extract specific regions of interest from images by using masks. Masks can be created by performing thresholding on images. Let us see this with an example. Consider the images below.

Photo by Simon John-McHaffie on Unsplash
Photo by Neven Krcmarek on Unsplash

Now say we want to extract the moon from the second image and paste it on the upper left corner of the first image. Here is how we do it using masks.

import cv2 as cvimg1 = cv.imread('night_sky.jpg')
img2 = cv.imread('moon.jpg')
img_2_shape = img2.shape
roi = img1[0:img_2_shape[0],0:img_2_shape[1]]
img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
# Now black-out the area of moon in ROI
img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)
print(img1.shape, mask.shape)
# Take only region of moon from moon image.
img2_fg = cv.bitwise_and(img2,img2,mask = mask)
# Put moon in ROI and modify the main image
dst = cv.add(img1_bg,img2_fg)
img1[0:img_2_shape[0], 0:img_2_shape[1]] = dst
#Create resizable windows for our display images
cv.namedWindow('img1_bg', cv.WINDOW_NORMAL)
cv.namedWindow('img2_fg', cv.WINDOW_NORMAL)
cv.namedWindow('mask', cv.WINDOW_NORMAL)
cv.namedWindow('maskinv', cv.WINDOW_NORMAL)
cv.namedWindow('res', cv.WINDOW_NORMAL)
cv.imshow('mask',mask)
cv.imshow('maskinv',mask_inv)
cv.imshow('img1_bg',img1_bg)
cv.imshow('img2_fg',img2_fg)
cv.imshow('res',img1)
if cv.waitKey(0) & 0xff == 27:
cv.destroyAllWindows()

When the mask parameter is set to a mask in the bitwise_and method, the AND operation is performed a bit differently than when the mask parameter is set to an empty array(default value). Here are screenshots from the official OpenCV documentation on bitwise_and.

So when a mask is provided the AND operation is performed between the first and second image arrays only where the corresponding mask values do not equal zero. In our case, the first and second images are the same image. So the AND operation is performed between the same image arrays where the corresponding mask value does not equal zero.

The outputs are as follows

mask(left) and mask inverse(right)
foreground(left) and background(right)
added foreground and background
Final image after stitching the added image over the upper left corner of first image

And that’s it! this is how we use bitwise operations on images to extract regions of interest.

HAPPY CODING!

--

--