Computer Vision for Beginners (part 2)

Siddhant Swaroop Dash
Subex AI Labs
Published in
6 min readOct 12, 2020

In part one we discussed some of the basics of computer vision like reading/writing/displaying an image, what an image is at an atomic level, drawing/writing on an image and image thresholding. If you are new to computer vision I highly recommend you to check out my previous article on Computer Vision. Now let’s jump into some more functions offered by OpenCV.

Courtesy of Good Housekeeping

Overview

In this article we will be looking at some more basic functionalities offered by OpenCV.

  1. Image Arithmetics
  2. Logical Operations

Lets again import the required libraries

We will need to use different images to demonstrate the usage of these different functionalities, since the scenario in which we can use these things maybe different and it’s better not to see the same image again and again and get bored. :)

Image Arithmetics and Logical Operations

Image Arithmetics is used when we are doing image analysis e.g. when there is image overlay and Logical Operations are an important functionality and is used exclusively in computer vision tasks.

We will be working on three images shown below. Lets read these images first.

Left: Among Us logo; Middle: Left arrow; Right: Up arrow

If you have been coding in python for a while now you know that we can have arithmetic operations with numpy arrays. From the previous article we know that the images are nothing but n-dimensional numpy arrays. So we can do various operations to these numpy arrays.

Operations with scalars using operators

Let us first work with the ‘left arrow’ image.

The frame names represent the manipulation done. This image looks like a grayscale image to begin with, but when I read the image with cv2.imread(), it was read as a color image. Try playing around with the numbers and with grayscale images as well. Note: scalar division is not shown as discussion of the behaviour is out of scope of this article. Best if you find out for yourself.

Operations with scalars using cv2 functions

We tried using mathematical operators on images. Lets leverage the functions provided by OpenCV.

The frame names represent the manipulation done. OpenCV provides functions such as cv2.add(), cv2.subtract(), cv2.multiply() and cv2.divide() for arithmetic operations. Each of the functions takes two parameters since these are binary operations. The change in the order of parameters results in changes as per the associativity nature of their basic mathematical operations. What I mean is in mathematical terms

Again cv2.divide() is left for you to experiment. :)

Operations with image

Now lets see what happens if we use images instead of scalars. One thing to keep in mind while going forward with this is that, the images should be of the same dimensions strictly.

Lets now add, subtract and multiply img1 which is the ‘left arrow’ image and img2 which is the ‘up arrow’ image.

The frame names containing symbols signify the use of mathematical operators and the frame names containing text signify the OpenCV functions.

You can notice using mathematical operators have a different effect on the images formed than when we use OpenCV functions. I can’t emphasize enough on the importance of trying this on your own with different images to get the idea of the it.

Another function offered by OpenCV is the cv2.addWeighted(). What this does basically is it overlays one image over the other based on the weight parameters of each image.

cv2.addWeighted() takes 5 parameters. These are the first image, weightage of first image, second image, weightage of second image and finally a gamma value. Weight here means how much of the actual intensity value is to be taken when the new image if formed. Here we have set gamma as 0 because we don’t want to alter the opacity of the new image. Gamma essentially does not mean opacity but the effect it has can only be described as such.

Logical Operations

Yes we can do logical operations like AND, OR, NOT, XOR that you may have learnt in the basic mathematics. If you don’t remember check out the truth tables of how these work.

Lets work with the ‘arrow’ images again.

OpenCV contains cv2.bitwise_not(), cv2.bitwise_and(), cv2.bitwise_or() and cv2.bitwise_xor() which perform NOT, AND, OR & XOR operations respectively.

Note: NOT is a unary operator so it only takes one image as input while the rest take two images as input.

The frame names represent the operations performed with the images.

The output of these functions is similar to that of their mathematical counterparts. There is no XNOR function in OpenCV because it is the same as doing an XOR operation on two images and then doing NOT operation on the resulting XOR image.

Again to perform these logical operations the image dimensions should be same.

Lets now perform a more complicated operation. Remember the first image, i.e. Among Us Logo? Now lets try to impose another color arrow image onto that logo image.

image to be imposed

So our objective is to impose the ‘arrow’ image onto the ‘logo’ image without overwriting the background of the ‘logo’ image.

Assume the above image has been read and stored in the variable img2.

First we find out the shape of the image and cut out a part from the logo image of the same size. As we discussed these operations require images to be of same size. In this case the images are of different sizes. Hence we need to crop out an ROI of the ‘logo’ image.

We will now use the concept of masking to eliminate the white background of the ‘arrow’ image. To create a mask we need a binary image. So first we convert the ‘arrow’ image into grayscale using cv2.cvtColor() and then we apply thresholding and it becomes our mask.

Then we create the inverse of the mask using cv2.bitwise_not().

Finally what we need to do is divide the region to be changed into foreground and background. The background will be the same as that of the ‘logo’ image. Hence we AND the ROI of the image with itself while considering the mask. Now the foreground needs to be the colored part of the ‘arrow’ image. Hence we AND the ‘arrow’ image with itself while considering the invisible mask.

Then we use cv2.add() to add the foreground and background images to form the altered image. So we have the manipulated/altered part of the image ready. Now we need to replace the part of the ‘logo’ image with the created image. This is done by assigning the sliced portion of the ‘logo’ image with the altered image. And voila.

We successfully imposed one image on another without affecting the background of the concerned image.

Conclusion

So we looked at some basic image arithmetics and logical operations provided by OpenCV and using these basic operations we achieved a quite complicated task of stickering on image on another. There can be many use cases and we can pipeline these operations as a preprocessing task for further analysis or functions.

Please let me know if you need further clarifications on this article by commenting below. Thanks for reading. More articles coming up soon.

Hope you had a fun and informative session in this article :)

--

--