wake-up-neo.net

Numpy Resize / Rescale Image

Ich möchte ein Bild aufnehmen und den Maßstab des Bildes ändern, während es ein numpy Array ist.

Zum Beispiel habe ich dieses Bild einer Coca-Cola-Flasche: Flasche-1

Was sich in einer Reihe von Formen (528, 203, 3) niederschlägt und ich möchte die Größe dieses zweiten Bildes ändern: Flasche-2

Welches hat eine Form von (140, 54, 3).

Wie ändere ich die Größe des Bildes in eine bestimmte Form, ohne das Originalbild zu verändern? Andere Antworten schlagen vor, jede zweite oder dritte Zeile zu streichen, aber ich möchte das Bild im Grunde so verkleinern, wie Sie es mit einem Bildeditor tun würden, aber in python Code. Gibt es Bibliotheken, die dies in Numpy/SciPy durchführen?

48
Brian Hamill

Ja, Sie können opencv (dies ist eine Bibliothek, die für die Bildverarbeitung und die Bildverarbeitung verwendet wird) installieren und die Funktion cv2.resize verwenden. Und zum Beispiel verwenden:

_import cv2
import numpy as np

img = cv2.imread('your_image.jpg')
res = cv2.resize(img, dsize=(54, 140), interpolation=cv2.INTER_CUBIC)_

Hier ist img also ein numpy-Array, das das Originalbild enthält, während res ein numpy-Array ist, das das skalierte Bild enthält. Ein wichtiger Aspekt ist der Parameter interpolation: Es gibt verschiedene Möglichkeiten, die Größe eines Bildes zu ändern. Zumal Sie das Bild verkleinern und die Größe des Originalbildes nicht ein Vielfaches der Größe des verkleinerten Bildes ist. Mögliche Interpolationsschemata sind:

  • _INTER_NEAREST_ - eine Interpolation zum nächsten Nachbarn
  • _INTER_LINEAR_ - eine bilineare Interpolation (standardmäßig verwendet)
  • _INTER_AREA_ - Neuabtasten unter Verwendung der Pixelflächenrelation. Es kann eine bevorzugte Methode zur Bilddezimierung sein, da es moiréfreie Ergebnisse liefert. Wenn das Bild jedoch gezoomt wird, ähnelt es der Methode _INTER_NEAREST_.
  • _INTER_CUBIC_ - eine bikubische Interpolation über die Nachbarschaft von 4x4 Pixeln
  • _INTER_LANCZOS4_ - eine Lanczos-Interpolation über eine Nachbarschaft von 8 x 8 Pixeln

Wie bei den meisten Optionen gibt es keine "beste" Option in dem Sinne, dass es für jedes Größenänderungsschema Szenarien gibt, in denen eine Strategie einer anderen vorgezogen werden kann.

66

Es ist zwar möglich, numpy alleine zu verwenden, die Operation ist jedoch nicht integriert. Das heißt, Sie können scikit-image (das auf Numpy basiert) verwenden, um diese Art der Bildbearbeitung durchzuführen.

Die Dokumentation zur Neuskalierung von Scikit-Bildern ist hier .

Beispielsweise könnten Sie mit Ihrem Bild Folgendes tun:

from skimage.transform import resize
bottle_resized = resize(bottle, (140, 54), anti_aliasing=True)

Dies erledigt für Sie Dinge wie Interpolation, Anti-Aliasing usw.

40
jakevdp

Die imresize() -Methode von SciPy war eine andere Methode zur Größenänderung, wird jedoch ab SciPy 1.3.0 entfernt. SciPy bezieht sich auf PIL Bildgrößenänderungsmethode: Image.resize(size, resample=0)

size - Die angeforderte Größe in Pixel als 2-Tupel: (width, height).
resample - Ein optionaler Resampling-Filter. Dies kann PIL.Image.NEAREST (Nächsten Nachbarn verwenden), PIL.Image.BILINEAR (lineare Interpolation), PIL.Image.BICUBIC (kubische Spline-Interpolation) oder PIL.Image.LANCZOS (ein qualitativ hochwertiger Downsampling-Filter) sein ). Wird das Feld weggelassen oder hat das Bild den Modus „1“ oder „P“, wird PIL.Image.NEAREST eingestellt.

Link hier: https://pillow.readthedocs.io/de/3.1.x/reference/Image.html#PIL.Image.Image.resize

4
cemsazara

Für Leute, die von Google hierher kommen und nach einer schnellen Möglichkeit suchen, Bilder in numpy Arrays für die Verwendung in Anwendungen für maschinelles Lernen herunterzusampeln, ist hier eine superschnelle Methode (angepasst von hier ). Diese Methode funktioniert nur, wenn die Eingabedimensionen ein Vielfaches der Ausgabedimensionen sind.

In den folgenden Beispielen wird ein Downsampling von 128 x 128 auf 64 x 64 durchgeführt (dies kann leicht geändert werden).

Letzte Bestellung der Kanäle

# large image is shape (128, 128, 3)
# small image is shape (64, 64, 3)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((output_size, bin_size, 
                                   output_size, bin_size, 3)).max(3).max(1)

Kanäle zuerst bestellen

# large image is shape (3, 128, 128)
# small image is shape (3, 64, 64)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((3, output_size, bin_size, 
                                      output_size, bin_size)).max(4).max(2)

Ändern Sie für Graustufenbilder einfach den 3 in einen 1 wie folgt:

Kanäle zuerst bestellen

# large image is shape (1, 128, 128)
# small image is shape (1, 64, 64)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((1, output_size, bin_size,
                                      output_size, bin_size)).max(4).max(2)

Diese Methode verwendet das Äquivalent von maximalem Pooling. Dies ist der schnellste Weg, den ich gefunden habe.

4
Waylon Flinn
import cv2
import numpy as np

image_read = cv2.imread('filename.jpg',0) 
original_image = np.asarray(image_read)
width , height = 452,452
resize_image = np.zeros(shape=(width,height))

for W in range(width):
    for H in range(height):
        new_width = int( W * original_image.shape[0] / width )
        new_height = int( H * original_image.shape[1] / height )
        resize_image[W][H] = original_image[new_width][new_height]

print("Resized image size : " , resize_image.shape)

cv2.imshow(resize_image)
cv2.waitKey(0)
0
M. Farzalizadeh