In this tutorial, we will learn how to perform different arithmetic operations on images using Python. We’ll perform different operations like addition, subtraction, multiplication, and division.
What do we mean by arithmetic operations on images?
Image arithmetic refers to the arithmetic operations on images. Whenever we perform any arithmetic operation on an image, it is performed on individual pixel values. For Example: If the image is colored then the addition is performed like this:
f_img(i, j, k) = img1(i, j, k) + img2(i, j, k)
or
f_img(i, j, k) = img1(i, j, k) + constant
If the image is a grayscale image then the addition is performed like this:
f_img(i, j) = img1(i, j) + img2(i, j)
or
f_img(i, j) = img1(i, j) + constant
Similarly, the other arithmetic operations are also performed on images. To perform any arithmetic operation on an image first, we have to load the image using the cv2.imread() method.
As we know the images are being loaded as NumPy N-dimensional array so it becomes very easy to perform different arithmetic operations on them. NOTE: If the arithmetic operations are performed on two or more images then all the images should be of the same type like jpeg, jpg, png, etc., **depth, and dimensions.
**depth: The number of bits used to represent each pixel like 8 bits per channel is often referred to as a 24-bit color image (8 bits x 3 channels).
Using OpenCV to perform arithmetic operations on images
First, we have to install the OpenCV-Python library and then import the cv2 module inside the Python program. Following are the commands to install OpenCV-Python and import the cv2 module:
# Installing OpenCV-Python library
pip install opencv-python
# Importing cv2 module
import cv2
1. Image Addition
We can either add two images or add a constant value to an image. Image addition is commonly used as an intermediate step in some complicated processes rather than as a useful operation on its own.
It can be used to overlay one image over another after suitable masking has been carried out. We can perform image addition in two ways:
- NumPy Addition: In this, we simply load the image files and add the NumPy N-d arrays returned after loading the images using the (+) operator. It is a modulo operation that means if the resultant pixel value is greater than 255 after the addition of the pixel values of the input (loaded) images then modulo (%) of the resultant pixel value with 256 (for 8-bit image format) is calculated and assigned to the resultant pixel value to keep it below 255 or 255 as any pixel value cannot exceed 255. For example:
250+10 = 260 => 260 % 256 = 4


# Reading image files
img1 = cv2.imread('sample-img-1.jpg')
img2 = cv2.imread('sample-img-2.jpg')
# Applying NumPy addition on images
fimg = img1 + img2
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

OpenCV addition: In this, we simply load the image files and pass the NumPy N-d arrays returned after loading the images to the cv2.add()
method as arguments. It is a saturated operation that means if the resultant pixel value is greater than 255 after the addition of the pixel values of the input (loaded) images then it is saturated to 255 so that any pixel value cannot exceed 255. This is called **saturation. For example: 250+10 = 260 => 255
**saturation is an image processing technique that is used to handle the pixel overflow in which we set all overflowing pixels to the maximum possible values.
# Reading image files
img1 = cv2.imread('sample-img-1.jpg')
img2 = cv2.imread('sample-img-2.jpg')
# Applying OpenCV addition on images
fimg = cv2.add(img1, img2)
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

NOTE: It is always advisable to stick with OpenCV functions for performing different operations on images because they provide better results as you can see from the outputs of the above two examples.
2. Image subtraction
Image subtraction is simply the pixel subtraction that takes two images as input and produces a third image as output whose pixel values are simply those of the first image minus the corresponding pixel values from the second image. We can also use a single image as input and subtract a constant value from all its pixel values. Some versions of the operator will output the absolute difference between pixel values, rather than the straightforward signed output.
Implementations of the image subtraction vary as to what they do if the output pixel values are negative. If the image formats support negative values of pixels, in that case, the negative values are fine. If the image format does not support negative pixel values then often such pixels are set to zero (i.e. black typically). Or
If the image subtraction calculates absolute differences of the two input images which use the same pixel value type, then the output pixel values can’t be outside the specified range that may be represented by the input images pixel type and so this problem does not arise. That’s why it is good to use absolute differences. Again we can perform image subtraction in two ways:
NumPy Subtraction and OpenCV subtraction.
We will only use the OpenCV subtraction as it produces better results and is widely used. The cv2.subtract()
method is used for image subtraction and the result will be like res = img1 - img2
where img1 & img2 are the images of the same depth and type.
Image subtraction is used both as an intermediate step in complicated image processing techniques and also as an important operation on its own. One most common use of image subtraction is to subtract background variations in illumination from a scene so that the objects in foreground can be analyzed more easily and clearly.
NOTE: We will be using the same sample images for image subtraction also.
# Reading image files
img1 = cv2.imread('sample-img-1.jpg')
img2 = cv2.imread('sample-img-2.jpg')
# Applying OpenCV subtraction on images
fimg = cv2.subtract(img1, img2)
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

3. Image multiplication
Like other arithmetic operations on images, image multiplication can also be implemented in forms. The first form of image multiplication takes two input images and produces an output image in which the pixel values are the product of the corresponding pixel values of the input images.
And the second form takes a single input image and produces output in which each pixel value is the product of the corresponding pixel values of the input image and a specified constant (scaling factor). This second form of image multiplication is more widely used and is generally called scaling.
There are several uses of image scaling but in general a scaling factor greater than unity, the scaling will brighten the image, and a scaling factor less than unity will darken the image.
Scaling normally produces a much more natural brightening or darkening effect in the image than simply adding an offset to the pixel values because it preserves the relative contrast of the image better.
Note: The constant value is often a floating-point number, depending upon which the image intensity can be increased or decreased. It can be negative if the image format supports that. If the output values are calculated to be larger than the maximum allowed pixel value, then it is truncated at that maximum allowed pixel value.
Let’s use NumPy image multiplication to increase the brightness of the sample image given below.

# Reading image file
img = cv2.imread('sample_img.jpg')
# Applying NumPy scalar multiplication on image
fimg = img * 1.5
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

Now let’s see the change in this sample image on applying OpenCV image multiplication using the cv2.multiply()
method which usually takes either two image arrays or one image array and one specified constant.
# Reading image file
img = cv2.imread('sample_img.jpg')
# Applying OpenCV scalar multiplication on image
fimg = cv2.multiply(img, 1.5)
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

4. Image division
The image division operation normally takes two images as input and produces a third image whose pixel values are the pixel values of the first image divided by the corresponding pixel values of the second image.
It can also be used with a single input image, in which case every pixel value of the image is divided by a specified constant.
Image division operation can be used for change detection like a subtraction but instead of giving the absolute change for each pixel value from one image to another, division operation gives the fractional change or ratio between corresponding pixel values.
That’s why it is commonly known as rationing.
Let’s use image division to decrease the brightness of the above sample image using the cv2.divide()
method which usually takes either two image arrays or one image array and one specified constant.
# Reading image file
img = cv2.imread('sample_img.jpg')
# Applying OpenCV scalar division on image
fimg = cv2.divide(img, 2)
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

Or we can also use the NumPy division also to decrease the brightness of the above sample image as follows:
# Reading image file
img = cv2.imread('sample_img.jpg')
# Applying NumPy scalar division on image
fimg = img / 2
# Saving the output image
cv2.imwrite('output.jpg', fimg)
Output:

Conclusion
In this tutorial we have learned how to perform different arithmetic operations on images, analyzed the working of different OpenCV methods used for performing image arithmetic, and learned where these image arithmetic operations are used like saturation, rationing, scaling, etc.