it-swarm.com.de

Konvertieren Sie np.array vom Typ float64 in uint8-Skalierungswerte

Ich habe ein bestimmtes np.array data , das ein bestimmtes Graustufenbild darstellt Ich muss SimpleBlobDetector () verwenden, das leider nur 8-Bit-Bilder akzeptiert, also muss ich dieses Bild konvertieren, offensichtlich mit einem Qualitätsverlust .

Ich habe schon versucht:

import numpy as np
import cv2
[...]
data = data / data.max() #normalizes data in range 0 - 255
data = 255 * data
img = data.astype(np.uint8)
cv2.imshow("Window", img)

Aber cv2.imshow gibt das Bild nicht wie erwartet ab, sondern mit merkwürdiger Verzerrung ...

Am Ende muss ich nur ein np.float64 in np.uint8 konvertieren, alle Werte skalieren und den Rest abschneiden, z. 65535 wird zu 255, 65534 wird zu 254 und so weiter.

Vielen Dank.

7
decadenza

Eine bessere Methode zur Normalisierung Ihres Bildes besteht darin, jeden Wert durch den größten Wert des Datentyps zu dividieren. Dies stellt sicher, dass Bilder mit einem kleinen dynamischen Bereich in Ihrem Bild klein bleiben und nicht unbeabsichtigt normalisiert werden, sodass sie grau werden. Wenn Ihr Bild beispielsweise einen dynamischen Bereich von [0-2] hat, würde der Code dies jetzt skalieren, um Intensitäten von [0, 128, 255] zu erhalten. Sie möchten, dass diese nach der Konvertierung in np.uint8 klein bleiben. 

Teilen Sie daher jeden Wert durch den größtmöglichen Wert durch das Bild type, nicht das eigentliche Bild selbst. Sie würden dies dann um 255 skalieren, um das normalisierte Ergebnis zu erhalten. Verwenden Sie numpy.iinfo und geben Sie den Typ (dtype) des Bildes an. Sie erhalten eine Informationsstruktur für diesen Typ. Sie würden dann von dieser Struktur aus auf das Feld max zugreifen, um den Maximalwert zu bestimmen. 

Nehmen Sie mit den oben genannten Änderungen die folgenden Änderungen an Ihrem Code vor:

import numpy as np
import cv2
[...]
info = np.iinfo(data.dtype) # Get the information of the incoming image type
data = data.astype(np.float64) / info.max # normalize the data to 0 - 1
data = 255 * data # Now scale by 255
img = data.astype(np.uint8)
cv2.imshow("Window", img)

Beachten Sie, dass ich das Bild zusätzlich in np.float64 konvertiert habe, falls der eingehende Datentyp dies nicht ist und die Gleitkommazahl bei der Division beibehalten wird.

14
rayryeng

sie können skimage.img_as_ubyte(yourdata) verwenden, um die Array-Bereiche von 0 bis 255 zu numpy machen

from skimage import img_as_ubyte

img = img_as_ubyte(data)
cv2.imshow("Window", img)
0
Ali Farouk