pythonimage-processingnumpyscikit-imagemahotas

How can i know if there are white pixels in a binary image in some coordinates (stored in a list) in python?


I have a numpy array binary (black and white) image and coordinates in a list of tuples like:

coordlist =[(110, 110), (110, 111), (110, 112), (110, 113), (110, 114), (110, 115), (110, 116), (110, 117), (110, 118), (110, 119), (110, 120), (100, 110), (101, 111), (102, 112), (103, 113), (104, 114), (105, 115), (106, 116), (107, 117), (108, 118), (109, 119), (110, 120)]

or as:

coordx = [110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110]
coordy = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120]

How can i check if there is a "white" pixel in the image with that coordinates list? I also would like check the white pixels that are around 3 pixels range far from that coordinates list.

i.e.:

for i, j in coordx, coordy:
    for k in a range (k-3, k + 3)
        for l in a range (l-3, l + 3)
            #checking white pixels also for pixel near coordinates list

I thought about "where" function.

from skimage import morphology
import numpy as np

path = 'image/a.jpg'
col = mh.imread(path)
bn0 = col[:,:,0]
bn = (bn0 < 127)
bnsk = morphology.skeletonize(bn)
bnskInt = np.array(bnsk, dtype=np.uint8)

#finding if there are white pixel in the coord list and around that in a 5 pixel range
for i in coordlist:
np.where(?)

UPDATE.

I tried to use shape (128, 128) instead of (128, 128, 3) because my image have this shape: (a,b) but now it does not find the white pixels! Why in this way does it find anything?

    white_pixel = np.array([255, 255])
    img = np.random.randint(0, 256, (128, 128))
    print(img[150])
    print(img.shape)
    img[110, 110] = 255
    img[109, 110] = 255

    mask = np.zeros((128, 128), dtype=bool)
    mask[coordx, coordy] = 1
    #structure = np.ones((3, 3, 1))
    #mask = scipy.ndimage.morphology.binary_dilation(mask, structure)

    is_white = np.all((img * mask) == white_pixel, axis=-1)

    # This will tell you which pixels are white
    print np.where(is_white)

    # This will tell you if any pixels are white
    print np.any(is_white)

output:

(array([], dtype=int32),)
False

Solution

  • Update, I've updated the answer to work with binary or gray scale images. Notice that image intensities are now just scalars instead of (R, G, B) values and all images, masks and structure elements are 2d-arrays instead of 3d arrays. You may need to adjust the value of white_pixel (or otherwise modify this code to suit your needs).

    import numpy as np
    from skimage.morphology import binary_dilation
    # Setup
    coordx = [110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 100, 101, 102,
              103, 104, 105, 106, 107, 108, 109, 110]
    coordy = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 110, 111, 112,
              113, 114, 115, 116, 117, 118, 119, 120]
    img = np.random.random((128, 128))
    img[110, 110] = 1.
    img[109, 110] = 1.
    
    
    # values grater than white_pixel will get detected as white pixels
    white_pixel = 1
    
    mask = np.zeros((128, 128), dtype=bool)
    mask[coordx, coordy] = 1
    
    structure = np.ones((7, 7))
    mask = binary_dilation(mask, structure)
    
    is_white = (img * mask) >= white_pixel
    
    # This will tell you which pixels are white
    print np.where(is_white)
    
    # This will tell you if any pixels are white
    print np.any(is_white)
    

    Original answer:

    You only need to use numpy.where if you wan to know which pixels are white. I would just multiply the image by a mask and use np.any, something like this:

    # Setup
    coordx = [110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 100, 101, 102,
              103, 104, 105, 106, 107, 108, 109, 110]
    coordy = [110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 110, 111, 112,
              113, 114, 115, 116, 117, 118, 119, 120]
    white_pixel = np.array([255, 255, 255])
    img = np.random.randint(0, 256, (128, 128, 3))
    img[110, 110, :] = 255
    img[109, 110, :] = 255
    
    mask = np.zeros((128, 128, 1), dtype=bool)
    mask[coordx, coordy] = 1
    
    structure = np.ones((7, 7, 1))
    mask = binary_dilation(mask, structure)
    
    is_white = np.all((img * mask) == white_pixel, axis=-1)
    
    # This will tell you which pixels are white
    print np.where(is_white)
    
    # This will tell you if any pixels are white
    print np.any(is_white)