OpenCV imread of grayscale image returns 3-channel (color?) array instead of single-channel

Question:

I have the following python function below which takes in an image and a noise coefficent as input parameters such that the percentage of total pixels converted to noise is proportionate to the coefficient (represented as the noise matrix). This noise matrix is then multiplied to the original image to obtain the noisy image.

def dot_salt_pepper(img, noise_coeff):
    height = img.shape[0]
    width = img.shape[1]
    noise_matrix = np.ones([height, width])
    num_noise_pixels = int(height * width * noise_coeff)
    
    for i in range(num_noise_pixels):
        noise_matrix[np.random.randint(height)][np.random.randint(width)] = 0
        
    new_img = np.multiply(img, noise_matrix)
    new_img = np.uint8(img)
    
    return new_img

I understand that in order to add dot noise to an existing image, the image must first be converted to grayscale. However the image I am working with came in grayscale format, thus when I read it in OpenCV using cv2.imread('img.jpg'), calling print(img.shape) outputs the tuple (3000, 4000, 3) which suggests that the BGR channels are still present in the image (thus I cannot multiply the 2D noise matrix to the 3D image matrix). How do I go around this issue?

This is the image in question

Asked By: Naja

||

Answers:

The JPEG file you provided is grayscale, not RGB.

imread always converts to BGR, unless you pass some flags.

Pass the IMREAD_UNCHANGED flag to get exactly what’s in the file. This will work for your file because it is grayscale.

Pass IMREAD_GRAYSCALE to force conversion to gray.

Answered By: Christoph Rackwitz

The image is in RGB datatype, even though it has no colour
Convert to greyscale

This can be done on read of the image cv2.imread(IMAGE_FILE, cv2.IMREAD_GRAYSCALE)

Answered By: Jess
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.