基于Numpy数组的像素值缩放问题:天文模拟恒星亮度未生效
问题描述
我正在构建一个模拟恒星亮度随时间变化的天文系统,图像以Numpy数组形式存储。当前代码如下:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from astropy.io import fits from astropy.utils.data import get_pkg_data_filename import os import csv image_file = get_pkg_data_filename('ngc_3201_V_stack no label (2).fits') image_data = fits.getdata(image_file) squareImg = image_data[79:1844, 183:1948] coord_data = pd.read_csv('test coords.csv', header=0) X = coord_data['Pixel X'].tolist() Y = coord_data['Pixel Y'].tolist() with open('more_stars_test.csv', newline='') as f: reader = csv.reader(f) Scales = list(reader) Scales.pop(0) for lists in Scales: lists.pop(0) # setting output dir outputDir = r'C:\Users\me\Downloads\10_stars_test' os.chdir(outputDir) # hardcoding variables dimension = 1765 radius = 5 print("Output dir: " + outputDir) # loop through each frame for frame in range(0, len(Scales)): # get current frame number frameNum = int(frame) print("Starting " + str(frameNum), end="... ") # scales for each star per frame scales = [float(x) for x in Scales[frame]] print(scales) # loop through each star for star in range(0, len(Scales[0])): # create coordinate grid circulating around each star position a, b = Y[star], X[star] # (y,x) x, y = np.ogrid[-a:dimension - a, -b:dimension - b] # create mask based on those coordinates mask = (x ** 2) + (y ** 2) <= (radius ** 2) invertedMask = np.invert(mask) maskedStar = squareImg * mask starRemoved = squareImg * invertedMask # scale brightness according to scales print(scales[star]) scaledMaskedStar = maskedStar * float(scales[star]) scaledMaskedStar[(1 < scaledMaskedStar) & (scaledMaskedStar <= 120)] = 120 # export final frame with corrected star brightness finalFrame = scaledMaskedStar + starRemoved # save file with all stars corrected print("Saving frame number " + str(frameNum)) fileName = os.path.join(outputDir, f'frame_{frameNum}.png') plt.imsave(fileName, finalFrame, cmap='gray', vmin=78.791, vmax=528.5)
补充说明:
test coords.csv存储各恒星像素坐标,用于生成遮罩(mask)more_stars_test.csv每行对应一帧中所有恒星的亮度缩放因子(scaling factor)
当前问题:缩放因子未实际生效,每帧保存的仍是原始图像。已确认缩放因子读取正常,但亮度调整未生效,推测问题出在缩放计算或保存环节。
项目目标:模拟恒星亮度随时间变化,预期恒星区域随时间变亮/变暗。
解决思路
核心问题分析
- 未累积修改:每处理一颗恒星时,都是直接基于原始图像
squareImg重新计算,而非基于上一颗恒星修改后的图像。最后finalFrame只会保留最后一颗恒星的修改(若最后一颗缩放因子为1,则完全无变化),前面所有恒星的调整都被覆盖。 - 变量覆盖:在恒星循环内每次重新赋值
finalFrame,导致之前的修改全部丢失。
修复步骤
每帧初始化基础图像:在处理每帧的恒星前,复制原始图像作为当前帧的修改基础,避免每次从原图重新计算:
# 在frame循环内,star循环前添加 current_frame = squareImg.copy()逐星累积修改:不再每次生成新的
finalFrame,而是直接在current_frame上修改对应恒星区域的像素值:# 替换原star循环内的代码 for star in range(0, len(Scales[0])): a, b = Y[star], X[star] # (y,x) x, y = np.ogrid[-a:dimension - a, -b:dimension - b] mask = (x ** 2) + (y ** 2) <= (radius ** 2) # 提取当前帧中该恒星区域的像素 star_pixels = current_frame[mask] # 应用缩放因子 scaled_pixels = star_pixels * scales[star] # 应用阈值限制 scaled_pixels[(1 < scaled_pixels) & (scaled_pixels <= 120)] = 120 # 将缩放后的像素放回当前帧 current_frame[mask] = scaled_pixels保存修改后的帧:最后保存累积了所有恒星修改的
current_frame,而非循环内的finalFrame:# 替换原保存代码 print("Saving frame number " + str(frameNum)) fileName = os.path.join(outputDir, f'frame_{frameNum}.png') plt.imsave(fileName, current_frame, cmap='gray', vmin=78.791, vmax=528.5)
额外检查点
- 确认代码缩进正确:所有处理恒星的逻辑必须在
for star循环内部,避免变量作用域错误。 - 验证遮罩(mask)的正确性:可以单独打印某颗恒星的mask区域,检查是否准确覆盖目标恒星位置。
内容的提问来源于stack exchange,提问作者Baba Booey
相关产品推荐
相关产品推荐

