Python Forum
numpy masking/filtering
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
numpy masking/filtering
#1
I'm working on a project where I'm using numpy for generative art, and I've got a question with how to filter an array without copying the data (so the original array will still be edited by a change to the filtered version). It works great for index slices, but apparently copies the data if you slice using another array as a mask?

I'm hoping this is actually super simple, and I just don't know what word numpy calls it.

import numpy as np
from PIL import Image

# small image, all black
df = np.zeros((100, 100, 3), dtype=np.uint8)

mask = np.zeros((100, 100), dtype=bool)
band = 10
for rndx, row in enumerate(mask):
    for cndx, col in enumerate(mask[rndx]):
        if abs(cndx - rndx) <= band:
            mask[rndx, cndx] = True

use_working_method = False
if use_working_method:
    # red diagonal line
    df[mask, 0] = 255
else:
    view = df[mask, :]

    # ...sometime later
    view[:, 0] = 255

    # for reference, this does work:
    view1 = df[45:55, 45:55, :]
    view1[:, :, 2] = 255  # blue, centered


im = Image.fromarray(df)
im.show()
Reply
#2
I think you could get something by using numpy's MaskedArray type, something along the line of
import numpy as np
import numpy.ma as ma

N = 10
band = 3
x = np.tile(np.arange(N, dtype=int), (N, 1))
mask = (abs(x-x.T) <= band)

print(mask)
m = np.repeat(mask[:,:,np.newaxis], 3, axis=2)

df = np.zeros((N, N, 3), dtype=np.uint8)
view = ma.masked_array(df, mask=m)
view[:, 0] = 255

print(df)
Reply
#3
That sounds great, but I'm not sure it's actually working? That modification to the view was applied to the entire array, not just the masked portion. But the MaskedArray module is new to me, so I'll keep playing around with it and see if I can figure it out. Thanks :)

>>> view.size
300
>>> df.size
300
Reply
#4
I've got it working :)
The mask maintains all data, and you need to specifically filter out the masked values when altering the view. It means I'll need to rewrite the rest of my code to work with masks, but at least now I can do what I wanted :)

Working code to select a diagonal bar of the image, and paint just one channel of the selection:
import numpy as np
import numpy.ma as ma
from PIL import Image


def get_array():
    # small image, all black
    df = np.zeros((100, 100, 3), dtype=np.uint8)
    # convert to masked array, without masking anything
    return ma.array(df)


def select_data(df):
    mask = np.ones(df.shape[0:2], dtype=bool)
    band = 10
    for rndx, row in enumerate(mask):
        for cndx, col in enumerate(mask[rndx]):
            if abs(cndx - rndx) <= band:
                mask[rndx, cndx] = False

    mask = np.repeat(mask[:, :, np.newaxis], 3, 2)
    view = ma.MaskedArray(df, mask=mask)
    return view


def alter_data(df):
    # only change red
    channels = df.mask.copy()
    channels[:, :, :] = True
    channels[:, :, 0] = False
    view = ma.MaskedArray(df, mask=channels)
    view[~view.mask] = 255


def show_image(df):
    im = Image.fromarray(df)
    im.show()


def main():
    df = get_array()
    work_set = select_data(df)
    alter_data(work_set)
    show_image(df)


if __name__ == "__main__":
    main()
This was needed, because I'm working on a generative algorithm that combines selectors together, and then makes changes to the selected regions. For example, I might combine a Diagonal selector with a Blinds selector to get rectangular boxes in a diagonal pattern, evenly spaced, and equal widths, that I then paint over. It's really just an excuse for me to play with numpy, lol
Gribouillis likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Numpy] How to store different data type in one numpy array? water 7 614 Mar-26-2024, 02:18 PM
Last Post: snippsat
  Numpy returns "TypeError: unsupported operand type(s) for *: 'numpy.ufunc' and 'int'" kalle 2 2,632 Jul-19-2022, 06:31 AM
Last Post: paul18fr
  Problem with masking precipitation data into a shapefile atrwmb109 0 1,901 Jul-22-2019, 05:10 PM
Last Post: atrwmb109
  "erlarge" a numpy-matrix to numpy-array PhysChem 2 2,994 Apr-09-2019, 04:54 PM
Last Post: PhysChem

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020