FITS(Flexible Image Transport System)是天文学中常用的数据格式,保存了大量的观测数据。传统软件如 SAOImage DS9 能够直观显示 FITS 图像,但在大规模数据处理和自动化任务中,使用 Python 编程可以实现更加灵活高效的图像处理工作流程。本文示例代码中主要使用了以下工具:
同时,我们在图像上添加彩色圆圈标注目标点,方便后续分析与比对。
在开始之前,请确保安装了以下 Python 包:
pip install numpy matplotlib astropy pillow
这些包分别用于数值计算、图像绘制、FITS 数据处理以及图片后处理。
下面是完整的代码示例,该代码读取 FITS 文件,使用 ZScaleInterval 自动调整亮度区间,并在指定坐标位置添加彩色圆圈标注,最终保存为 PNG 图片:
# -*- coding: utf-8 -*-
# @Author: 胖胖很瘦
# @Date: 2025-03-04 11:36:28
# @LastEditors: 胖胖很瘦
# @LastEditTime: 2025-03-04 15:41:36
import os
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits
from astropy.visualization import ZScaleInterval
deffits_to_png_with_circle(fits_file, output_file, xy_coords, circle_color='red', circle_radius=60):
"""
读取 FITS 文件,将其转换为 PNG/JPG 并在指定坐标绘制彩色圆圈。
参数:
- fits_file: str, FITS 文件路径
- output_file: str, 输出图片文件路径(.png 或 .jpg)
- xy_coords: list of tuples, 需要标注的 (x, y) 坐标列表
- circle_color: str, 圆圈颜色,例如 'red', 'blue'
- circle_radius: int, 圆圈半径(像素)
"""
# 读取 FITS 数据
with fits.open(fits_file) as hdul:
data = hdul[0].data # 获取主扩展的数据
# 计算图像显示的亮度区间
interval = ZScaleInterval()
vmin, vmax = interval.get_limits(data)
# 创建图像
fig, ax = plt.subplots(figsize=(8, 8))
ax.imshow(data, cmap='gray', origin='lower', vmin=vmin, vmax=vmax)
# 在指定坐标添加彩色圆圈
for (x, y) in xy_coords:
circle = plt.Circle((x, y), circle_radius, color=circle_color, fill=False, linewidth=1)
ax.add_patch(circle)
# 去除坐标轴和边框
ax.set_xticks([]) # 移除 X 轴刻度
ax.set_yticks([]) # 移除 Y 轴刻度
ax.set_frame_on(False) # 移除整个边框
# 保存为 PNG 或 JPG(这里采用 dpi=150,可根据需求调整)
plt.savefig(output_file, dpi=150, bbox_inches='tight', pad_inches=-0.1)
plt.close()
# 示例调用
fits_file = "example.fits"
output_file = "output.png"
xy_coords = [(100, 150), (200, 300)]
fits_to_png_with_circle(fits_file, output_file, xy_coords, circle_color='cyan', circle_radius=60)
为了提升整体处理速度和运行效率,我们可以从以下几个方面进行优化:
对于大型 FITS 文件,可以使用 memmap=True
进行内存映射,以加快数据读取速度。
with fits.open(fits_file, memmap=True) as hdul:
data = hdul[0].data
但是有时会出现如下错误:
ValueError: Cannot load a memory-mapped image: BZERO/BSCALE/BLANK header keywords present. Set memmap=False
原因:
某些 FITS 文件包含 BZERO
、BSCALE
或 BLANK
关键字,这会影响数据的内存映射方式,导致无法正常加载。
解决方案:
在遇到该问题时,直接设置 memmap=False
或者不添加memmap
参数, 默认就是False
,即不启用内存映射:
with fits.open(fits_file, memmap=False) as hdul:
data = hdul[0].data
这样可以保证数据正确加载,虽然可能牺牲部分加载速度,但避免了内存映射带来的兼容性问题。
使用 ZScaleInterval
计算 vmin
和 vmax
时,对数据进行下采样(例如采样每隔 4 个像素),可以减少计算量:
vmin, vmax = interval.get_limits(data[::4, ::4])
在 imshow
中设置 interpolation='none'
可关闭插值计算,从而加快渲染速度:
ax.imshow(data, cmap='gray', origin='lower', vmin=vmin, vmax=vmax, interpolation='none')
如果对图像分辨率要求不高,可以适当降低 dpi 参数,从而缩短保存时间。例如:
plt.savefig(output_file, dpi=150, bbox_inches='tight', pad_inches=-0.1)
降低 dpi 后,保存速度会更快,但需权衡分辨率和速度的关系。
SAOImage DS9
brew install --cask saoimageds9
本文详细介绍了如何使用 Python 将 FITS 图像转换为常用格式,并在图像上添加彩色圆圈进行精确标注。同时,我们分享了多种提升处理速度的优化策略,包括内存映射优化、下采样计算、关闭插值以及合理调整 dpi。希望这篇文章能为你在天文图像数据处理方面提供帮助和启发!
欢迎大家留言讨论,分享你的优化经验和心得。关注我们,获取更多天文数据处理与 Python 编程的干货分享!