Numpy.putmask с изображениями

У меня есть изображение, преобразованное в ndarray с значениями RGBA. Предположим, что это 50 x 50 x 4.

Я хочу заменить все пиксели на array([255, 255, 255, 255]) значений array([255, 255, 255, 255]) для array([0, 0, 0, 0]) . Так:

 from numpy import * from PIL import Image def test(mask): mask = array(mask) find = array([255, 255, 255, 255]) replace = array([0, 0, 0, 0]) return putmask(mask, mask != find, replace) mask = Image.open('test.png') test(mask) 

Что я делаю не так? Это дает мне значение ValueError: putmask: mask and data must be the same size . Но если я изменю массивы на числа (find = 255, replace = 0), это сработает.

3 Solutions collect form web for “Numpy.putmask с изображениями”

Один из способов сделать это маскирование каналов – это разбить массив на r, g, b, каналы, а затем определить индекс с помощью операций с numpy-логическим битом:

 import numpy as np import Image def blackout(img): arr = np.array(img) r,g,b,a=arr.T idx = ((r==255) & (g==255) & (b==255) & (a==255)).T arr[idx]=0 return arr img = Image.open('test.png') mask=blackout(img) img2=Image.fromarray(mask,mode='RGBA') img2.show() 

Более краткий способ сделать это

 img = Image.open('test.png') a = numpy.array(img) a[(a == 255).all(axis=-1)] = 0 img2 = Image.fromarray(a, mode='RGBA') 

В более общем плане, если элементы find и repl не все одинаковы, вы также можете сделать

 find = [1, 2, 3, 4] repl = [5, 6, 7, 8] a[(a == find).all(axis=-1)] = repl 

Это решение использует putmask и я думаю, что он наиболее близок к OPs-коду. В исходном коде, который должен знать OP, есть две ошибки: 1) putmask – это операция на месте. Он возвращает None . 2) putmask также требует массивы одинакового размера. Он (слишком плохой) не имеет аргумента ключевого слова axis .

 import numpy as np from PIL import Image img1 = Image.open('test.png') arry = np.array(img1) find = np.array([255, 255, 255, 255]) repl = np.array([ 0, 0, 0, 0]) # this is the closest to the OPs code I could come up with that # compares each pixel array with the 'find' array mask = np.all(arry==find, axis=2) # I iterate here just in case repl is not always the same value for i,rep in enumerate(repl): # putmask works in-place - returns None np.putmask(arry[:,:,i], mask, rep) img2 = Image.fromarray(arry, mode='RGBA') img2.save('testx.png') 
Python - лучший язык программирования в мире.