How to select all non-black pixels in a NumPy array?

前端 未结 2 884
梦如初夏
梦如初夏 2020-12-28 08:57

I am trying to get a list of an image\'s pixels that are different from a specific color using NumPy.

For example, while processig the following image:

相关标签:
2条回答
  • 2020-12-28 09:36

    You should use np.any instead of np.all for the second case of selecting all but black pixels:

    np.any(image != [0, 0, 0], axis=-1)
    

    Or simply get a complement of black pixels by inverting a boolean array by ~:

    black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
    non_black_pixels_mask = ~black_pixels_mask
    

    Working example:

    import numpy as np
    import matplotlib.pyplot as plt
    
    
    image = plt.imread('example.png')
    plt.imshow(image)
    plt.show()
    

    image_copy = image.copy()
    
    black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
    
    non_black_pixels_mask = np.any(image != [0, 0, 0], axis=-1)  
    # or non_black_pixels_mask = ~black_pixels_mask
    
    image_copy[black_pixels_mask] = [255, 255, 255]
    image_copy[non_black_pixels_mask] = [0, 0, 0]
    
    plt.imshow(image_copy)
    plt.show()
    


    In case if someone is using matplotlib to plot the results and gets completely black image or warnings, see this post: Converting all non-black pixels into one colour doesn't produce expected output

    0 讨论(0)
  • 2020-12-28 09:50

    Necessity: Need matrix with this shape = (any,any,3)

    Solution:

    COLOR = (255,0,0)
    indices = np.where(np.all(mask == COLOR, axis=-1))
    indexes = zip(indices[0], indices[1])
    for i in indexes:
        print(i)
    

    Solution 2:

    get interval of specific color, for example RED:

    COLOR1 = [250,0,0]
    COLOR2 = [260,0,0] # doesnt matter its over limit
    
    indices1 = np.where(np.all(mask >= COLOR1, axis=-1))
    indexes1 = zip(indices[0], indices[1])
    
    indices2 = np.where(np.all(mask <= COLOR2, axis=-1))
    indexes2 = zip(indices[0], indices[1])
    
    # You now want indexes that are in both indexes1 and indexes2
    

    Solution 3 - PROVED to be WORKING

    If previous doesnt work, then there is one solution that works 100%

    Transform from RGB channel to HSV. Make 2D mask from 3D image. 2D mask will contain Hue value. Comparing Hues is easier than RGB as Hue is 1 value while RGB is vector with 3 values. After you have 2D matrix with Hue values, do like above:

    HUE1 = 0.5
    HUE2 = 0.7 
    
    indices1 = np.where(HUEmask >= HUE1)
    indexes1 = zip(indices[0], indices[1])
    
    indices2 = np.where(HUEmask <= HUE2)
    indexes2 = zip(indices[0], indices[1])
    

    You can dothe same for Saturation and Value.

    0 讨论(0)
提交回复
热议问题