I am experimenting with the OpenCV-library in python. Let's say I read in an image such as:

import cv2
import matplotlib.pyplot as plt
import numpy as np

img = cv2.imread('imgs/watermark_no_copy.jpg')

This watermark_no_copy image should be part of some python-library. What I want to do now is to extract just the part of the image that is not white. I have come across the following code to do the job:

 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 mask_inv = cv2.bitwise_not(img_gray)
 img_extracted = cv2.bitwise_and(img, img, mask=mask_inv)

I don't fully understand what's going on tho. I understand that we convert the image into a Grayscale at first. A grayscale-image consists of just one color channel (only black and white with different intensity). In my case the background of the image is white and should, therefore, be assigned intensity 255. The colored part of the image, however, is red. It will not be assigned intensity 0.

Now, how does bitwise_not work? I understand that this should flip any bit 1 to 0 and any bit 0 to 1. However, in that grayscale-image, we don't have just 0 and 1. We have different intensity values. How exactly, does this work? Same question can be applied to the bitwise_and in the last line. bitwise_and of an image with itself, should return just that image, shouldn't it?


1 Answer 1


It works ... bitwise. Assume the value of a pixel is $200_{10} = 11001000_2$; then the bitwise not of that simply is $00110111_b=55$. Do that for all pixels.

It's not a useful transform in the context of intensities, if you ask me.

If the mask was actuall monochromatic (i.e. exactly black or exactly white in each pixel), it would make more sense.

So, don't "come across code" like that :)

  • $\begingroup$ Thx very much for your reply! ... Let me try and understand this: The original figure only consists of colors white (the background) and red (the "watermark"). By converting this into a grayscale image, white stays white and red becomes black. White is assigned intensity value 255. Now, in order to create the mask, I perform bitwise_not on the grayscale. The white background now becomes black (which is intensity 0). In bits, 255 = 1111 1111. And its inverse is just 0. What about the black part? Intensity 0 is binary 0000 0000. Its inverse is 1111 1111. Seems correct. $\endgroup$
    – user503842
    May 13, 2019 at 11:28
  • $\begingroup$ yeah, but only if your red really is converted to 0; I don't think it would be? Red is not black... $\endgroup$ May 13, 2019 at 11:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.