如何不调整尺寸、不改颜色查看.fits图像并还原真实色彩与尺寸?
Got it, let's work through this problem together. When converting FITS files to images and comparing against their corresponding GIFs, color and size mismatches are really common—here's how you can pull out the true original dimensions and match the correct color palette using APLPY and a few extra checks:
FITS files store their native dimensions in the header, so the first step is to confirm that you're not accidentally scaling or cropping the data when visualizing.
First, check the raw dimensions directly from the FITS header:
from astropy.io import fits # Replace with your file path details rloc = "/path/to/your/files/" rname = "synop_Ml_0.2104" rext = ".fits" hdul = fits.open(rloc + rname + rext) print(f"Original FITS image dimensions (rows, columns): {hdul[0].data.shape}") hdul.close()
Then, when using APLPY, disable automatic scaling and force the figure to use the native size:
- Use
autoscale=Falseto avoid stretching the data range (which can warp both size and color) - Set the figure size explicitly to match the FITS data's shape (note: FITS uses (rows, columns), so we flip it for matplotlib's (width, height))
Most FITS files for single-color images store grayscale data, while GIFs apply a custom colormap to make it look colored. To match the GIF's true colors, you need to either:
- Identify the exact colormap used for the GIF, or
- Extract the GIF's palette directly and convert it to a matplotlib-compatible colormap
Option A: Use a Known Colormap
If you know the colormap the GIF uses (like astronomical favorites plasma, viridis, or a custom one), plug it directly into your APLPY code. Here's a revised version of your function:
def from_fits_to_image(color_scheme, rloc, rname='synop_Ml_0.2104', rext='.fits', cmap=None): from astropy.io import fits import aplpy import matplotlib.pyplot as plt # Load FITS data and get native dimensions hdul = fits.open(rloc + rname + rext) data = hdul[0].data original_rows, original_cols = data.shape hdul.close() # Initialize figure with the FITS file fig = aplpy.FITSFigure(rloc + rname + rext) # Use the target colormap, no autoscaling to preserve original data range target_cmap = cmap if cmap else color_scheme fig.show_colorscale( cmap=target_cmap, stretch='linear', # Match the GIF's stretch type (could be 'log' too) autoscale=False, vmin=data.min(), vmax=data.max() ) # Set figure size to match native FITS dimensions (adjust dpi if needed) fig.figure.set_size_inches(original_cols / 100, original_rows / 100) # Save or display the corrected image fig.save(rloc + rname + '_corrected.png') fig.show()
Option B: Extract the GIF's Palette Directly
If you don't know the colormap, pull it from the GIF itself using PIL:
from PIL import Image import numpy as np from matplotlib.colors import ListedColormap # Load the GIF and extract its palette gif_img = Image.open(rloc + rname + '.gif') palette = gif_img.getpalette() # Convert palette to a matplotlib colormap (scale values to 0-1) palette_array = np.array(palette).reshape(-1, 3) / 255.0 custom_cmap = ListedColormap(palette_array) # Now pass this custom_cmap to your function from_fits_to_image("unused", rloc, rname, rext, cmap=custom_cmap)
Double-check that your corrected image matches the GIF's dimensions by comparing both:
# Get GIF dimensions print(f"GIF dimensions (width, height): {gif_img.size}") # Compare to your corrected image's size corrected_img = Image.open(rloc + rname + '_corrected.png') print(f"Corrected FITS image dimensions: {corrected_img.size}")
By explicitly preserving the native FITS dimensions and replicating the GIF's color palette, you should get an image that matches the reference GIF closely. Remember that GIFs sometimes apply subtle contrast adjustments, so you might need to tweak the stretch parameter (try 'log' if 'linear' doesn't match) to get the exact look right.
内容的提问来源于stack exchange,提问作者user7345804

