Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

np arrays being immutable - "assignment destination is read-only"

FD** - I am a Python newb as well as a stack overflow newb as you can tell. I have edited the question based on comments.

My goal is to read a set of PNG files, create Image(s) with Image.open('filename') and convert them to simple 2D arrays with only 1s and 0s. The PNG is of the format RGBA with mostly only 255 and 0 as values. Quite often in the images, the edges are grey scale values, which I would like to avoid in the 2D array.

I created the 2D array from image using np.asarray(Image) getting only the 'Red' channel. In each of the 2d image array, I would like to set the cell value = 1 if the current value is non zero.

So, I loop into the 2d array and I check the cell value and try to set it to 1.

It gives me an error indicating that the array is read-only. I read through several stack overflow threads discussing that np arrays are immutable and it is a still bit unclear. I use PIL and numpy

Thanks @user2314737. I will attempt to set that flag. @Eric, thanks for your comments as well.

from PIL import Image
import numpy as np

The relevant code:

prArray = [np.asarray(img)[:, :, 0] for img in problem_images]

for img in prArray:
    for x in range(184):
        for y in range(184):
            if img[x][y] != 0:
                img[x][y] = 1

The error "assignment destination is read-only" is in the last line.

Thank you everyone for help.

like image 759
Ramesh Ramasubramanian Avatar asked Sep 18 '16 06:09

Ramesh Ramasubramanian


People also ask

Is NumPy array immutable?

Numpy Arrays are mutable, which means that you can change the value of an element in the array after an array has been initialized.

How do I load an image into a NumPy array?

Using OpenCV Libraryimread() function is used to load the image and It also reads the given image (PIL image) in the NumPy array format. Then we need to convert the image color from BGR to RGB. imwrite() is used to save the image in the file.


4 Answers

Check if the array is writable with

>>> img.flags   C_CONTIGUOUS : True   F_CONTIGUOUS : False   OWNDATA : True   WRITEABLE : False   ALIGNED : True   UPDATEIFCOPY : False 

If WRITEABLEis false, change it with

img.setflags(write=1) 
like image 101
user2314737 Avatar answered Sep 19 '22 05:09

user2314737


Since numpy version 1.16.0 the following doesn't work anymore:

img = np.asarray(Image.open(filename)) img.setflags(write=1) 

The problem is that now OWNDATA is set to False and you can't set WRITEABLE flag to True. Therefore you should simply do the following:

img = np.array(Image.open(filename)) 

This will make a copy of array when casting it from Pillow object to numpy array. However I tested time performance in numpy 1.16.0 and haven't found any noticable difference between both methods.

like image 39
AleksMat Avatar answered Sep 22 '22 05:09

AleksMat


In this case, I think you are trying to edit the image provided to you by another user and he/she made it uneditable that's why you are getting this error. For your case, you may try to make a copy of the given file and do changes on that file by using .copy().

     img_copy = img.copy()
     prArray = [np.asarray(img_copy)[:, :, 0] for img_copy in problem_images]

And more importantly, I do not think that most of us want to make changes to our original image, that's why I always use .copy() and recommend you to do the same.

like image 21
Avneesh Upadhayay Avatar answered Sep 20 '22 05:09

Avneesh Upadhayay


ValueError: cannot set WRITEABLE flag to True of this array array.setflags(write=1) 

Skip the statement using copy the array using np.copy()

like image 22
keyan wilson Avatar answered Sep 20 '22 05:09

keyan wilson