2017-02-23 2 views
0

Ich versuche gerade, ein Farbdiagramm einer bestimmten Datenserie von Bildern mit Python zu erstellen. Nachdem ich eine Software namens Powderday benutzt habe, habe ich in der Datei "merger.070.new.rtout.image", die ich in Zeile 18 meines Codes aufgerufen habe, eine Reihe von ungefähr 35 Bildern gespeichert, die jeweils Flussinformationen enthalten eine bestimmte Wellenlänge einer bestimmten Galaxienverschmelzung. Ich möchte jedes dieser Bilder durchlaufen und ein endgültiges Bild erzeugen, das im Wesentlichen jedes dieser Bilder summiert, so dass ich anstelle mehrerer einzelner Wellenlängenbilder eine Reihe von Wellenlängen in einem Bild habe.Hinzufügen jedes Pixels in einer Reihe von AxesImages

Dazu möchte ich jedes Bild durchlaufen, speichern Sie die Wellenlängenkarte in einem endgültigen Bild, und fügen Sie weitere Bilder zu diesem endgültigen hinzufügen. Das einzige Problem ist, dass ich jedes Mal ein AxesImage bekomme, wenn ich die Single-Wavelength-Bilder finde, die, soweit ich weiß, keine Funktion haben, einfach mit einem anderen Bild zu verschmelzen. Ich habe bisher online gefunden, dass die beste Lösung darin besteht, aus dem Image ein numpy Array zu erstellen, aber ich konnte auch nicht herausfinden, ob die Funktion get_image von matplotlib.image einen AxesImage-Parameter akzeptiert, um daraus ein solches zu machen Array. Mein Code ist unten.

Die wichtigen Zeilen sind: 42 - 45, wo ich versuche, finalImg zu initialisieren, damit ich es innerhalb der Schleife "iterieren" kann; 47 - 61 wo ich durch jedes Bild iteriere.

Auch eine Randbemerkung: die B_Johnson und B_thruput Dateien, die ich einlese, enthalten Information über welche Wellenlängen ich in meiner .image Datei sowie die entsprechenden Durchsätze habe. Dies liegt daran, dass ich den Fluss, den ich bei jeder Wellenlänge finde, mit seinem Durchsatz multiplizieren möchte, um einen tatsächlichen realen Filter korrekt zu simulieren.

Hoffe, diese Informationen bietet einen guten Hintergrund für das Problem! Ich bin immer noch sehr neu in Python. Was ist der beste Weg, all diese Bilder zusammenzufassen?

import numpy as np 
import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt 
import matplotlib.image as mpimg 
from hyperion.model import ModelOutput 
from astropy.cosmology import Planck13 
import astropy.units as u 


# ------------------------ 
# modifiable header 
# ------------------------ 

filters = np.loadtxt('B_Johnson.txt') 
thru = np.loadtxt('B_thruput.txt', dtype='double') 

Leitung 18 unten:

m = ModelOutput('/home/sss274/Work/Outputs/diskMerger/70/merger.070new.rtout.image') 
redshift=2 
image_width = 200 #kpc 

# ------------------------ 


distance = Planck13.luminosity_distance(redshift).cgs.value 


# Extract the image for the first inclination, and scale to 300pc. We 
# have to specify group=1 as there is no image in group 0. 
image = m.get_image(distance=distance, units='mJy') 

# Open figure and create axes 
fig = plt.figure() 

ax = fig.add_subplot(111) 

#calculate image width in kpc 
w = image.x_max * u.cm 
w = w.to(u.kpc) 

Leitung 42 unten:

cax = ax.imshow(image.val[0,:,:,(np.argmin(np.abs(3600 - image.wav)))]*0, 
       cmap = plt.cm.spectral, origin='lower', extent=[-w.value, w.value, -w.value, w.value]) 

finalImg = mpimg.imread(cax) 

Zeilen 47 bis 61 in der Schleife:

for idx, fil in enumerate(filters): 
    wav = fil 

    #find nearest wavelength 
    iwav = np.argmin(np.abs(wav - image.wav)) 

    #find the throughput to multiply found flux by throughput 
    throughput = thru[idx] 

    #plot the beast 

    cax = ax.imshow((image.val[0,:, :, iwav])*throughput, 
        cmap = plt.cm.spectral, origin='lower', extent=[-w.value, w.value, -w.value, w.value]) 

    finalImg += mpimg.imread(cax) 

    plt.xlim([-image_width,image_width]) 
    plt.ylim([-image_width,image_width]) 


# Finalize the plot 
ax.tick_params(axis='both', which='major', labelsize=10) 
ax.set_xlabel('x kpc') 
ax.set_ylabel('y kpc') 

plt.colorbar(cax,label='Flux (mJy)',format='%.0e') 

fig.savefig('pd_image_bj.png', bbox_inches='tight',dpi=150) 

Antwort

1

Erstens kann man nicht eine Last Matplotlib AxesImage in ein NumPy-Array.

Ich bin nicht in Ihrem Bereich, sondern auf der Grundlage der Hyperion documentation für ModelOutput.get_image() Ich glaube get_image() kehrt Bilddaten als NumPy Array in der folgenden Zeile aus dem Code:

image = m.get_image(distance=distance, units='mJy') 

Blick auf type(image) dies zu überprüfen. Sie sollten numpy.ndarray sehen, wenn ich richtig liege.

Wenn das der Fall ist, dann ist finalImg = mpimg.imread(cax) überflüssig ... Sie haben Ihre Bilder bereits als NumPy Array in der image Variable geladen.

Wenn Sie nun Ihre Daten als separate Kanäle in einem einzelnen NDarray-Objekt laden möchten, sind Sie fertig unter get_image(). Drucken image.ndim sollte 3 zeigen (Sie haben ein dreidimensionales Bild-Array) mit img.shape von (y_axis_length, x_axis_length, number_of_channels).

Basierend auf wie Sie Ihre Frage formuliert, aber ich denke, dass Sie diese Kanäle in einen einzigen Intensitätswert für jedes Pixel kombinieren möchten, indem Sie die Summe der Intensitäten in jedem Kanal nehmen. Diese Operation würde ein zweidimensionales Graustufenbild der Form (y_axis_length, x_axis_length) ergeben. Um zu sehen, was ich meine, beachten Sie bitte die folgenden Beispiel habe ich für Sie erstellt:

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.cbook import get_sample_data 

# load example image file 
image_file = get_sample_data("grace_hopper.png", asfileobj=True) 

# read example image file to NumPy array 
image_array = plt.imread(image_file) 

# show `image_array` as color (RGB) image 
fig = plt.figure() 
plt.imshow(image_array) 
plt.tight_layout() 
plt.axis('off') # turns off x and y-axis ticks 
plt.show() 

fig

# since the image is color (RGB), slice into individual channels 
# to illustrate adding image arrays 
c1 = image_array[:, :, 0] 
c2 = image_array[:, :, 1] 
c3 = image_array[:, :, 2] 

# define empty array with same shape as one image slice 
# this will become the final image result 
new_array = np.zeros_like(c1) 

# visualize empty array 
fig0 = plt.figure() 
plt.imshow(new_array, cmap='gray') 
plt.tight_layout() 
plt.axis('off') 
plt.show() 

fig0

# visualize distinct image slices (RGB image has three color channels) 
# one at a time to illustrate differences between images 
fig1, ax = plt.subplots(nrows=1, ncols=3) 
for img, a in zip([c1, c2, c3], ax): 
    a.imshow(img, cmap='gray') 
    a.axis('off') 

    # iteratively add image slices to `new_array` 
    # while we are iterating over the slices 
    new_array += img 

plt.tight_layout() 
plt.show() 

fig1

# visualize end result of iteratively adding image slices to `new_array` 
fig2 = plt.figure() 
plt.imshow(new_array, cmap='gray') 
plt.axis('off') 
plt.tight_layout() 
plt.show() 

fig2

+0

Vielen Dank! Wäre es möglich, ein leeres Array ohne Farbinformationen zu erstellen? Oder würde ich es nur mit meinem ersten Bild außerhalb der for-Schleife initialisieren und innerhalb der Schleife hinzufügen? –

+0

Macht nichts! Ich könnte np.empty_like verwenden, habe es gefunden. –

+0

Kein Problem! Yep, np.empty_like initialisiert ein leeres Array für dich. Ich habe in diesem Beispiel np.zeros_like verwendet, das ein mit Nullen gefülltes Array zurückgibt. – Brian

Verwandte Themen