Search code examples
pythonopencvimshowimread

cv2.Imshow() show same channel color on different images


I have encountered a very strange problem. Imshow() is showing the same image for the three first imshows - why? (Only the red channel, it seems to have zeroed blue and green) I'm creating a copy of the original image, but it seems the operations affect all images. The forth imshow shows the red channel as grey-scale as expected. What am I doing wrong?

    ##### Image processing ####
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('/home/pi/Documents/testcode_python/Tractor_actual/Pictures/result2.jpg') #reads as BGR
print(img.shape)

no_blue=img
no_green=img
only_red=img[:,:,2] #Takes only red channel from BGR image and saves to "only_red"

no_blue[:,:,0]=np.zeros([img.shape[0], img.shape[1]]) #Puts Zeros on Blue channels for "no_blue"
no_green[:,:,1]=np.zeros([img.shape[0], img.shape[1]])

print(no_blue.shape)

cv2.imshow('Original',img)
cv2.imshow('No Blue',no_blue)
cv2.imshow('No Green',no_green)
cv2.imshow('Only Red', only_red)
cv2.waitKey(0)
cv2.destroyAllWindows()

enter image description here


Solution

  • You would need to create a copy of the image to avoid using the same memory location as img. Not sure if this is what you are looking in for only_red, but having all three channels with blue and green set to 0 will avoid it from being considered a single channel grayscale image.

        ##### Image processing ####
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = cv2.imread('/home/pi/Documents/testcode_python/Tractor_actual/Pictures/result2.jpg') #reads as BGR
    print(img.shape)
    
    no_blue=img.copy() # copy of img to avoid using the same memory location as img
    no_green=img.copy() # copy of img to avoid using the same memory location as img
    only_red=img.copy() # similarly to above. 
    
    # You also need all three channels of the RGB image to avoid it being interpreted as single channel image.
    only_red[:,:,0] = np.zeros([img.shape[0], img.shape[1]])
    only_red[:,:,1] = np.zeros([img.shape[0], img.shape[1]])
    # Puts zeros for green and blue channels
    
    no_blue[:,:,0]=np.zeros([img.shape[0], img.shape[1]]) #Puts Zeros on Blue channels for "no_blue"
    no_green[:,:,1]=np.zeros([img.shape[0], img.shape[1]])
    
    print(no_blue.shape)
    
    cv2.imshow('Original',img)
    cv2.imshow('No Blue',no_blue)
    cv2.imshow('No Green',no_green)
    cv2.imshow('Only Red', only_red)
    cv2.waitKey(0)
    cv2.destroyAllWindows()