2016-12-06 8 views
0

Ich möchte ein Bild im Format passt auf eine kleinere Dimension. Zum Beispiel möchte ich mein 100x100-Pixel-Bild zu einem 58x58-Pixel-Bild vergrößern. Die Werte des Arrays sind Intensitäts- oder Flusswerte. Ich möchte, dass die Gesamtintensität des Bildes nach der Transformation erhalten bleibt. Dies funktioniert nicht mit skimage resize. Mein Gesamtwert verringert sich je nachdem, welchen Faktor ich heraufskaliere oder verkleinere. Ich habe unten den Code gezeigt, den ich bisher versucht habe.Skimage Resize ändert die Gesamtsumme der Array

import numpy as np 
from skimage.transform import resize 


image=fits.open(directory+file1) 
cutout=image[0].data 
out = resize(cutout, (58,58), order=1, preserve_range=True) 
print(np.sum(out),np.sum(cutout)) 

Meine Ausgabe ist:

0.074657436655 0.22187 (I want these two values to be equal) 

Wenn ich es auf das gleiche Maß-Skala:

out = resize(cutout, (100,100), order=1, preserve_range=True) 
print(np.sum(out),np.sum(cutout)) 

Meine Ausgabe ist sehr nah, was ich will:

0.221869631852 0.22187 

Ich habe das gleiche Problem, wenn ich versuche, zu erhöhen ase auch die Bildgröße.

out = resize(cutout, (200,200), order=1, preserve_range=True) 
print(np.sum(out),np.sum(cutout)) 

Ausgang:

0.887316320731 0.22187 

Ich würde gerne wissen, ob es eine Abhilfe für dieses Problem ist.

EDIT 1: meine Gesamtsumme konserviert erhöhen oder die Größe meines Bildes zu verringern, dann

Ich habe erkannt, dass, wenn ich mein Bild durch das Quadrat der Skala, von denen ich möchte multiplizieren.

Zum Beispiel:

x=58 
out = resize(cutout, (x,x), order=1, preserve_range=True) 
test=out*(100/x)**2 
print(np.sum(test),np.sum(cutout)) 

Meine Ausgabe ist ganz in der Nähe zu dem, was ich will, aber etwas höher:

0.221930548915 0.22187 

Ich habe versucht, diese mit unterschiedlichen Abmessungen und es funktioniert mit Ausnahme wirklich kleine Werte. Kann jemand erklären, warum diese Beziehung wahr ist oder ist das nur ein statistischer Zufall?

+0

warum renormieren einfach nicht die Intensitäten nach der Skalierung? – maxymoo

+0

Sollte ich meine Intensität als das Quadrat meines Skalierungsfaktors normalisieren? Wenn dies der Fall ist, können Sie mir sagen, warum diese Beziehung wahr ist? – Vishnu

+0

Vielleicht möchten Sie einen Blick auf: http://scikit-image.org/docs/dev/api/skimage.transform.html#skimage.transform.downscale_local_mean –

Antwort

3

Wenn Sie ein Bild behandeln I = Width x Height wo N = Width x Height als Satz von Pixeln mit Intensitäten im Bereich von [0,1], es ist völlig normal, dass nach dem Bild zu M = newWidth x newWeight die Summe der Intensitäten unterscheidet sich vollständig von vor Ändern der Größe.

Angenommen, ein Bild I mit N Pixeln hat gleichmäßig verteilte Intensitäten im Bereich [0,1]. Dann wird die Summe der Intensitäten ungefähr 0.5 * N sein. Wenn Sie skimage resize verwenden, wird das Bild auf eine niedrigere (oder größere) Größe von interpolating verkleinert. Interpolieren akkumuliert keine Werte (wie Sie zu erwarten scheinen), sondern Durchschnitt Werte in einer Nachbarschaft, um den Wert jedes der Pixel im neuen Bild vorherzusagen. Daher ändert sich der Intensitätsbereich des Bildes nicht, die Werte sind , modifiziert, und daher wird die Summe der Intensitäten des neuen in der Größe angepassten Bildes ungefähr 0.5 * M sein. Wenn M != N dann wird die Summe der Intensitäten sehr unterschiedlich sein.

Was können Sie dieses Problem zu lösen zu tun ist:

  1. Re-Skala Ihre neuen Daten proportional zu ihrer Größe:

    >>> y, x = (57, 58) 
    >>> out = resize(data, (y,x), order=1, preserve_range=True) 
    >>> out = out * (data.shape[0]/float(y)) * (data.shape[1]/float(x)) 
    

    , der analog zu, was Sie vorschlagen, aber für jede Größe Bild (nicht nur quadratische Bilder). Dies kompensiert jedoch jedes Pixel mit einem konstanten Faktor out[i,j] *= X, wobei X für jedes Pixel in dem Bild gleich ist und nicht alle Pixel mit dem gleichen Gewicht interpoliert werden, so dass kleine künstliche Artefakte hinzugefügt werden.

  2. Ich denke, es ist am besten, die Gesamtsumme des Bildes (die von der Anzahl der Pixel im Bild abhängt) mit der durchschnittlichen Intensität im Bild zu ersetzen (die nicht auf die Anzahl der Pixel angewiesen ist)

    >>> meanI = np.sum(I)/float(I.size) # Exactly the same as np.mean(I) or I.mean() 
    >>> meanInew = np.sum(out)/float(out.size) 
    >>> np.isclose(meanI, meanInew) # True 
    
+0

Vielen Dank für den Link und Ihre Antwort. Ich verstehe es jetzt, es wurde sehr gut erklärt. – Vishnu

Verwandte Themen