web-dev-qa-db-de.com

np-Arrays sind unveränderlich - "Zuweisungsziel ist schreibgeschützt"

FD ** - Ich bin ein Python-Newb sowie ein Stack-Overflow-Newb, wie Sie sehen können. Ich habe die Frage anhand von Kommentaren bearbeitet.

Mein Ziel ist es, eine Reihe von PNG-Dateien zu lesen, Bilder mit Image.open ('Dateiname') zu erstellen und diese in einfache 2D-Arrays mit nur 1s und 0s zu konvertieren. Das PNG hat das Format RGBA mit meist nur 255 und 0 als Werten. In den Bildern sind die Kanten oft Graustufenwerte, die ich im 2D-Array vermeiden möchte. 

Ich habe das 2D-Array mit np.asarray (Image) aus einem Bild erstellt und dabei nur den 'roten' Kanal erhalten. In jedem der 2d-Bildfelder möchte ich den Zellenwert = 1 festlegen, wenn der aktuelle Wert nicht Null ist.

Ich schleife also in das 2d-Array und überprüfe den Zellenwert und versuche, ihn auf 1 zu setzen.

Es gibt einen Fehler, der angibt, dass das Array schreibgeschützt ist. Ich habe mehrere Stack-Overflow-Threads durchgelesen und besprochen, dass np-Arrays unveränderlich sind und es noch immer unklar ist. Ich benutze PIL und Numpy

Danke @ user2314737. Ich werde versuchen, diese Flagge zu setzen. @ Eric, danke auch für deine Kommentare. 

from PIL import Image
import numpy as np

Der relevante 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

Der Fehler "Zuweisungsziel ist schreibgeschützt" befindet sich in der letzten Zeile.

Vielen Dank an alle für die Hilfe. 

Prüfen Sie, ob das Array mit beschreibbar ist

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

Wenn WRITEABLEfalse ist, ändern Sie es mit

img.setflags(write=1)
41
user2314737

Seit numpy Version 1.16.0 funktioniert Folgendes nicht mehr:

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

Das Problem ist, dass jetzt OWNDATA auf False gesetzt ist und Sie das WRITEABLE-Flag nicht auf True setzen können. Deshalb sollten Sie einfach Folgendes tun:

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

Wenn ich mich nicht irre, erstellt dies eine Kopie des Arrays, wenn es von Pillow object in numpy-Array umgewandelt wird. Ich habe jedoch die Zeitleistung in numpy1.16.0 getestet und habe keinen merklichen Unterschied zwischen beiden Methoden gefunden.

3
AleksMat

In diesem Fall versuchen Sie vermutlich, das Bild zu bearbeiten, das Ihnen ein anderer Benutzer zur Verfügung gestellt hat, und er/sie hat es unbearbeitbar gemacht. Aus diesem Grund wird dieser Fehler angezeigt. In Ihrem Fall können Sie versuchen, eine Kopie der angegebenen Datei zu erstellen und Änderungen an dieser Datei mithilfe von .copy() vorzunehmen.

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

Und was noch wichtiger ist: Ich glaube nicht, dass die meisten von uns Änderungen an ihrem Originalbild vornehmen möchten. Deshalb verwende ich immer .copy() und empfehle Ihnen, dasselbe zu tun.

0

Sie haben keinen Zugriff auf die Quelle des Bildes. Sie müssen es lediglich in ein anderes Array kopieren, und jetzt können Sie eine Zuweisung vornehmen.

0
eslam mofreh