You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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)

当前问题:缩放因子未实际生效,每帧保存的仍是原始图像。已确认缩放因子读取正常,但亮度调整未生效,推测问题出在缩放计算或保存环节。

项目目标:模拟恒星亮度随时间变化,预期恒星区域随时间变亮/变暗。


解决思路

核心问题分析

  1. 未累积修改:每处理一颗恒星时,都是直接基于原始图像squareImg重新计算,而非基于上一颗恒星修改后的图像。最后finalFrame只会保留最后一颗恒星的修改(若最后一颗缩放因子为1,则完全无变化),前面所有恒星的调整都被覆盖。
  2. 变量覆盖:在恒星循环内每次重新赋值finalFrame,导致之前的修改全部丢失。

修复步骤

  1. 每帧初始化基础图像:在处理每帧的恒星前,复制原始图像作为当前帧的修改基础,避免每次从原图重新计算:

    # 在frame循环内,star循环前添加
    current_frame = squareImg.copy()
    
  2. 逐星累积修改:不再每次生成新的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
    
  3. 保存修改后的帧:最后保存累积了所有恒星修改的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:48:31