'How to ignore external list in case of lists in list(without using Numpy)

I writing a function that its input is- image_one, image_two, mask). This function outputs a new image by calculating every new pixel according to the formula-

new_image[i][j] = round(image_one[i][j] x mask[i][j] + image_two[i][j] x (1 - mask[i][j]))

I wrote until now-

def image_plus_mask(image_one, image_two, mask):
    hight = len(image_one)
    width = len(image_one[0])
    new_image = [[0 for _ in range(width)] for _ in range(hight)]

    for i in range(hight):
        for j in range(width):
            new_image[i][j] = round((image_one[i][j] * mask[i][j]) + (image_two[i][j] * (1-mask[i][j])))
    return new_image

The function dose work on double lists. For example:

Input-

image_plus_mask([[50, 50, 50]], [[200, 200, 200]], [[0, 0.5, 1]]) 

Output(as expected)-

[[200, 125, 50]]

The problem is that it is not working on 3 lists, and I need it to work on both- 2 and 3 lists.(by 2 I mean-[[]], by 3 I mean- [[[]]])

For example-

Input-

image_plus_mask([[[1,2,3], [4,5,6]],[[7,8,9],[10,11,12]]],
[[[250,250,250], [0,0,0]],[[250,250,100],[1,11,13]]],[[0,0.5]]*2))

Expected Output-

[[[250, 250, 250,], [2,2,3]], [[250, 250, 100], [6, 11, 12]]]

What can I do?



Solution 1:[1]

Like in the comments said:

def image_plus_mask(image_one, image_two, mask):
    
    hight = len(image_one)
    width = len(image_one[0])
    
    #case: 3 lists
    if isinstance(image_one[0][0], (list,tuple)):
        depth = len(image_one[0][0])
        new_image = [[[0 for _ in range(depth)] for _ in range(width)] for _ in range(hight)]
        print(new_image)
        for i in range(hight):
            for j in range(width):
                for k in range(depth):
                    new_image[i][j][k] = round((image_one[i][j][k] * mask[i][j]) + (image_two[i][j][k] * (1-mask[i][j])))

    #case: 2 lists                
    else:
        new_image = [[0 for _ in range(width)] for _ in range(hight)]
        for i in range(hight):
            for j in range(width):
                new_image[i][j] = round((image_one[i][j] * mask[i][j]) + (image_two[i][j] * (1-mask[i][j])))
                
    return new_image

you need to adjust your shape of new_image. Look at your expected Output for 3 lists and look inside the function what you define for new_image. Couldn't work.

Output now:

res1 = image_plus_mask([[[1,2,3], [4,5,6]],[[7,8,9],[10,11,12]]],
[[[250,250,250], [0,0,0]],[[250,250,100],[1,11,13]]],[[0,0.5]]*2)

res2 = image_plus_mask([[50, 50, 50]], [[200, 200, 200]], [[0, 0.5, 1]]) 

print(res1)
[[[250, 250, 250], [2, 2, 3]], [[250, 250, 100], [6, 11, 12]]]

print(res2)
[[200, 125, 50]]

Solution 2:[2]

Your mask has to be the same shape as your inputs. If it is different then the image_one[i][j] * mask[i][j] will not work.

I highly suggest you using numpy arrays like this:

image1 = np.array([[50, 50, 50]])
image2 = np.array([[200, 200, 200]])
mask = np.array([[0, 0.5, 1]])

output = np.round(image1 * mask + image2 * (1 - mask))

print(output)

Output:

[[200. 125.  50.]]

If the shape of your inputs (images and mask) is consistent this will give what you want with any dimensions.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 D.Manasreh