Подтвердить что ты не робот

Np массивы неизменяемы - "назначение назначения доступно только для чтения"

FD ** - Я новичок в Python, а также переполнение стека newb, как вы можете сказать. Я отредактировал вопрос, основанный на комментариях.

Моя цель - прочитать набор PNG файлов, создать Image с Image.open('filename') и преобразовать их в простые 2D-массивы только с 1 и 0. PNG имеет формат RGBA, в основном только 255 и 0 в качестве значений. Довольно часто в изображениях ребра представляют собой значения шкалы серого, которые я бы хотел избежать в 2D-массиве.

Я создал 2D-массив из изображения, используя np.asarray(Image), получая только "красный" канал. В каждом из массива изображений 2d я хотел бы установить значение ячейки = 1, если текущее значение не равно нулю.

Итак, я петлю в 2d-массив, и я проверяю значение ячейки и пытаюсь установить ее в 1.

Это дает мне ошибку, указывающую, что массив доступен только для чтения. Я прочитал несколько потоков, обсуждая, что np-массивы являются неизменными, и это все еще немного неясно. Я использую PIL и numpy

Спасибо @user2314737. Я попытаюсь установить этот флаг. @Eric, спасибо за ваши комментарии.

from PIL import Image
import numpy as np

Соответствующий код:

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

Ошибка "назначение назначения только для чтения" находится в последней строке.

Спасибо всем за помощь.

4b9b3361

Ответ 1

Проверьте, доступен ли массив для записи с помощью

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

Если WRITEABLE является ложным, измените его на

img.setflags(write=1)

Ответ 2

Начиная с numpy версии 1.16.0 следующее больше не работает:

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

Проблема в том, что теперь для OWNDATA задано значение False а для флага WRITEABLE нельзя установить WRITEABLE True. Поэтому вы должны просто сделать следующее:

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

Если я не ошибаюсь, это сделает копию массива при приведении его из объекта Pillow к массиву numpy. Однако я проверил производительность по времени в numpy 1.16.0 и не обнаружил заметных различий между обоими методами.