Skalierung#

Die Bildskalierung ist eine intelligente Methode zur Vorverarbeitung von Bilddaten, idealerweise nach der Entfernung von Rauschen und Hintergrund. Sie ermöglicht es, die Bildgröße so weit zu reduzieren, dass die wissenschaftliche Fragestellung noch beantwortet werden kann, während gleichzeitig Speicherbeschränkungen berücksichtigt werden. Wenn der Computer beispielsweise über Out-of-Memory-Fehler klagt, ist die Skalierung eines Bildes auf eine kleinere Größe die erste Methode der Wahl, um mit einem Projekt fortzufahren. Darüber hinaus gibt es viele Segmentierungsalgorithmen und quantitative Messmethoden, die die Isotropie von Pixeln/Voxeln als Voraussetzung haben: Voxel müssen in allen Richtungen die gleiche Größe haben, andernfalls können die Ergebnisse solcher Algorithmen irreführend oder sogar falsch sein.

import pyclesperanto_prototype as cle
import matplotlib.pyplot as plt
from skimage.io import imread

Um die Skalierung zu demonstrieren, verwenden wir ein zugeschnittenes und neu abgetastetes Bilddatum aus der Broad Bio Image Challenge: Ljosa V, Sokolnicki KL, Carpenter AE (2012). Annotated high-throughput microscopy image sets for validation. Nature Methods 9(7):637 / doi. PMID: 22743765 PMCID: PMC3627348. Verfügbar unter http://dx.doi.org/10.1038/nmeth.2083

input_image = imread("../../data/BMP4blastocystC3-cropped_resampled_8bit.tif")

# voxel size is not equal in all directions; 
# the voxels are anisotropic.
voxel_size_x = 0.202
voxel_size_y = 0.202
voxel_size_z = 1

Bei der Visualisierung von Projektionen dieses Datensatzes entlang der drei Achsen sehen Sie, dass die Voxel nicht isotrop sind.

def show(image_to_show, labels=False):
    """
    This function generates three projections: in X-, Y- and Z-direction and shows them.
    """
    projection_x = cle.maximum_x_projection(image_to_show)
    projection_y = cle.maximum_y_projection(image_to_show)
    projection_z = cle.maximum_z_projection(image_to_show)

    fig, axs = plt.subplots(1, 3, figsize=(10, 10))
    cle.imshow(projection_x, plot=axs[0], labels=labels)
    cle.imshow(projection_y, plot=axs[1], labels=labels)
    cle.imshow(projection_z, plot=axs[2], labels=labels)
    axs[0].set_title("ZY plane")
    axs[1].set_title("XZ plane")
    axs[2].set_title("XY plane")
    plt.show()

show(input_image)
../_images/7f1987918237ea9ff23fbb7d380ebf47a8288bf1a5b045ebc1e76a12908496a1.png

Skalierung mit der Voxelgröße#

Der einfachste Weg, dieses Problem zu beheben, ist, den Datensatz mit seiner Voxelgröße zu skalieren. Per Definition führt dies zu einem Datensatz, bei dem die Voxel isotrop sind und in allen Richtungen voxel_size = 1 (in unserem Fall Mikrometer) haben.

scale_factor_x = voxel_size_x
scale_factor_y = voxel_size_y
scale_factor_z = voxel_size_z

resampled = cle.scale(input_image, 
                      factor_x=scale_factor_x, 
                      factor_y=scale_factor_y, 
                      factor_z=scale_factor_z, 
                      linear_interpolation=True,
                      auto_size=True)

show(resampled)
../_images/014a3011f5f5842dab8a613a773abc67e8bd866b03e0690462bb220450bac968.png

Der neu abgetastete Stapel hat jetzt weniger Voxel in X und Y, was bei der genauen Segmentierung der Objekte problematisch sein könnte. Wir können dies deutlich sehen, wenn wir die Form der ursprünglichen Daten und des neu abgetasteten Bildes ausgeben. Dies ist die Größe des Bildstapels in Tiefe-Höhe-Breite (Z-Y-X).

input_image.shape
(86, 396, 393)
resampled.shape
(86, 80, 79)

Eine mögliche Lösung besteht darin, einen zoom_factor einzuführen. Er ermöglicht es, die Größe des neu abgetasteten Bildes anzupassen:

zoom_factor = 2

scale_factor_x = voxel_size_x * zoom_factor
scale_factor_y = voxel_size_y * zoom_factor
scale_factor_z = voxel_size_z * zoom_factor

resampled_zoomed = cle.scale(input_image, 
                      factor_x=scale_factor_x, 
                      factor_y=scale_factor_y, 
                      factor_z=scale_factor_z, 
                      linear_interpolation=True,
                      auto_size=True)

show(resampled_zoomed)
../_images/b59cf3d9905ea9e1d84814d9adf0aab31adcacbe80c2ea303caad4fdcfd3765e.png
resampled_zoomed.shape
(172, 160, 159)

Beim Zoomen/Skalieren von 3D-Bildern sollten Sie die Speicherbegrenzungen im Auge behalten. Sie können die Größe der Bilder im Kasten rechts in der folgenden Ansicht ablesen. Das Zoomen eines Bildes um den Faktor 2, wie im obigen Beispiel, erhöht die Bildgröße eines 3D-Stapels um den Faktor 8 (2x2x2).

resampled
cle._ image
shape(86, 80, 79)
dtypefloat32
size2.1 MB
min0.0
max255.0
resampled_zoomed
cle._ image
shape(172, 160, 159)
dtypefloat32
size16.7 MB
min0.045749664
max255.0

Übung#

Erhöhen Sie den Zoom-Faktor und führen Sie den obigen Code erneut aus. Bei welchem Zoom-Faktor stürzt das Programm ab? Wie groß wäre das Bild, das generiert würde, wenn es nicht abstürzen würde? Wie viel Speicher hat Ihre Grafikkarte?