Python 3: I am trying to find find all green pixels in an image by traversing all pixels using an np.array, but can't get around index error

后端 未结 1 1601
被撕碎了的回忆
被撕碎了的回忆 2020-11-30 14:48

My code currently consists of loading the image, which is successful and I don\'t believe has any connection to the problem.

Then I go on to transform the color imag

相关标签:
1条回答
  • 2020-11-30 15:21

    In direct answer to your question, the y axis is given first in numpy arrays, followed by the x axis, so interchange your indices.


    Less directly, you will find that for loops are very slow in Python and you are generally better off using numpy vectorised operations instead. Also, you will often find it easier to find shades of green in HSV colourspace.

    Let's start with an HSL colour wheel:

    and assume you want to make all the greens into black. So, from that Wikipedia page, the Hue corresponding to Green is 120 degrees, which means you could do this:

    #!/usr/local/bin/python3
    import numpy as np
    from PIL import Image
    
    # Open image and make RGB and HSV versions
    RGBim = Image.open("image.png").convert('RGB')
    HSVim = RGBim.convert('HSV')
    
    # Make numpy versions
    RGBna = np.array(RGBim)
    HSVna = np.array(HSVim)
    
    # Extract Hue
    H = HSVna[:,:,0]
    
    # Find all green pixels, i.e. where 100 < Hue < 140
    lo,hi = 100,140
    # Rescale to 0-255, rather than 0-360 because we are using uint8
    lo = int((lo * 255) / 360)
    hi = int((hi * 255) / 360)
    green = np.where((H>lo) & (H<hi))
    
    # Make all green pixels black in original image
    RGBna[green] = [0,0,0]
    
    count = green[0].size
    print("Pixels matched: {}".format(count))
    Image.fromarray(RGBna).save('result.png')
    

    Which gives:


    Here is a slightly improved version that retains the alpha/transparency, and matches red pixels for extra fun:

    #!/usr/local/bin/python3
    import numpy as np
    from PIL import Image
    
    # Open image and make RGB and HSV versions
    im = Image.open("image.png")
    
    # Save Alpha if present, then remove
    if 'A' in im.getbands():
        savedAlpha = im.getchannel('A')
        im = im.convert('RGB')
    
    # Make HSV version
    HSVim = im.convert('HSV')
    
    # Make numpy versions
    RGBna = np.array(im)
    HSVna = np.array(HSVim)
    
    # Extract Hue
    H = HSVna[:,:,0]
    
    # Find all red pixels, i.e. where 340 < Hue < 20
    lo,hi =  340,20
    # Rescale to 0-255, rather than 0-360 because we are using uint8
    lo = int((lo * 255) / 360)
    hi = int((hi * 255) / 360)
    red = np.where((H>lo) | (H<hi))
    
    # Make all red pixels black in original image
    RGBna[red] = [0,0,0]
    
    count = red[0].size
    print("Pixels matched: {}".format(count))
    
    result=Image.fromarray(RGBna)
    
    # Replace Alpha if originally present
    if savedAlpha is not None:
        result.putalpha(savedAlpha)
    
    result.save('result.png')
    

    Keywords: Image processing, PIL, Pillow, Hue Saturation Value, HSV, HSL, color ranges, colour ranges, range, prime.

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