FITS 图像复制和粘贴,Python
FITS image copy and pasting, Python
所以我有一个 FITS 图像文件。我想裁剪一个特定区域(它是适合图像中的一条直线,我想复制和旋转),将其旋转一个角度,然后创建一个新图像,其中有 12 条这样的直线围成一个圆圈。像一个在 30 度,另一个在 60 度,依此类推。我试过旋转它,但我不知道如何粘贴它并创建新图像。这是在 python.
我正在使用此代码打开适合的图像:
hdul = pyfits.open('img.fits')
img=hdul[0].data
This is the image
更新 1:我已根据您更新后的规范编辑了代码。
您的问题包含三个子问题:
步骤 1) 提取您指定的区域。
步骤2)旋转提取的区域。
第 3 步)将其复制到图像(基本上是另一个 numpy 数组)。
这仍然是一个脏代码。可以根据更多关于输入和特征提取逻辑中预期内容的输入进行改进。到目前为止,特征提取仍然是硬编码的。
import numpy as np
import copy
import math
from scipy import ndimage
from scipy.spatial import distance
import matplotlib.pyplot as plt
from astropy.io import fits
# This is for Step 1.
def extract_roi(fits_image: np.ndarray) -> np.ndarray:
"""Returns the extracted region of interest(ROI) as numpy array.
ROI: Rectangular region around white vertical line. Currently hard-coding
the bounds. They have to be set manually.
Assumption: ROI will be a vertical feature.
"""
ROW_START, ROW_END = 0, 50
COL_START, COL_END = 70, 75
extracted_region = fits_image[ROW_START: ROW_END, COL_START:COL_END]
return extracted_region
def square_pad_roi(roi_image, pivot):
""" Pads the image with zeros and centers is about the pivot.
This eases rotation about a pivot using scipy.
Assumption: Image Top Left: Array (0, 0)
Assumption: Image Bot Right: Array(Rows, Cols)
:param roi_image: The image with the extracted ROI.
:param pivot: [row, col] pivot position to rotate image about.
row, col should be w.r.t. roi_image co-ords.
:return: square padded image centered about the provided pivot.
"""
r, c = roi_image.shape[:2]
piv_row, piv_col = pivot
corners = [[0, 0], [0, c], [r, c], [r, 0]] # [TL, TR, BR, BL]
dist = math.ceil(max([distance.euclidean(x, pivot) for x in corners]))
pad_row = [abs(piv_row - dist), abs(piv_row + dist - r)]
pad_col = [abs(piv_col - dist), abs(piv_col + dist - c)]
return np.pad(roi_image, [pad_row, pad_col], mode='constant',
constant_values=0)
# This is for Step 2.
def rotate_and_scale(image, angle, out_width) -> np.ndarray:
"""Rotates input image about center and scales it.
:param image: ROI image input which has to be rotated.
Expected to be square in shaped and centered about pivot.
:param angle: Angle in degrees to rotate image by.
:param out_width: width in pixels to fit the image into.
:return: rotated and scaled output image.
"""
img = copy.deepcopy(image)
rotated_roi = ndimage.rotate(img, angle, reshape=False)
zoom_scale = out_width / img.shape[0]
return ndimage.zoom(rotated_roi, zoom_scale)
# This is for Step 3.
def modify_output_image(output_image: np.ndarray,
rotated_roi: np.ndarray):
"""Overwrites inplace the rotated ROI image to the output image."""
THRESHOLD = 5
idx = np.where(rotated_roi > THRESHOLD)
output_image[idx] = rotated_roi[idx]
# This is what you should run.
def problem_logic(input_fits_image: np.ndarray, output_width) -> np.ndarray:
"""Takes input FITS image, and returns a modified image based on usecase."""
output_image = np.zeros((output_width, output_width))
extracted_roi = extract_roi(input_fits_image)
pivot = [0, extracted_roi.shape[1] // 2] # change this based on your req.
pivoted_roi = square_pad_roi(extracted_roi, pivot)
# I am assuming below as your rotation logic.
T0TAL_STEPS = 12 # For each hour orientation.
ROTATION_STEP = float(360 / T0TAL_STEPS) # In degrees.
for i in range(T0TAL_STEPS):
rotated_image = rotate_and_scale(pivoted_roi, ROTATION_STEP * i,
output_width)
modify_output_image(output_image, rotated_image)
return output_image
def write_as_fits(image: np.ndarray, path: str):
""" Writes the numpy image to the provided path in fits format"""
hdu = fits.PrimaryHDU(image)
hdu.writeto(path, overwrite=True)
def driver_main():
sample_fits = np.zeros((50, 100))
sample_fits[:, 70:73] = 255
# This creates the rotated ROI.
# Replace sample_fits with your fits image.
output_img = problem_logic(
input_fits_image=sample_fits, output_width=400
)
# This writes it to output file in fits format.
out_path = "sample.fits"
write_as_fits(output_img, out_path)
# This is just to visualize output.
plt.imshow(output_img, cmap='gray')
plt.show()
if __name__ == "__main__":
driver_main()
所以我有一个 FITS 图像文件。我想裁剪一个特定区域(它是适合图像中的一条直线,我想复制和旋转),将其旋转一个角度,然后创建一个新图像,其中有 12 条这样的直线围成一个圆圈。像一个在 30 度,另一个在 60 度,依此类推。我试过旋转它,但我不知道如何粘贴它并创建新图像。这是在 python.
我正在使用此代码打开适合的图像:
hdul = pyfits.open('img.fits')
img=hdul[0].data
This is the image
更新 1:我已根据您更新后的规范编辑了代码。
您的问题包含三个子问题:
步骤 1) 提取您指定的区域。
步骤2)旋转提取的区域。
第 3 步)将其复制到图像(基本上是另一个 numpy 数组)。
这仍然是一个脏代码。可以根据更多关于输入和特征提取逻辑中预期内容的输入进行改进。到目前为止,特征提取仍然是硬编码的。
import numpy as np
import copy
import math
from scipy import ndimage
from scipy.spatial import distance
import matplotlib.pyplot as plt
from astropy.io import fits
# This is for Step 1.
def extract_roi(fits_image: np.ndarray) -> np.ndarray:
"""Returns the extracted region of interest(ROI) as numpy array.
ROI: Rectangular region around white vertical line. Currently hard-coding
the bounds. They have to be set manually.
Assumption: ROI will be a vertical feature.
"""
ROW_START, ROW_END = 0, 50
COL_START, COL_END = 70, 75
extracted_region = fits_image[ROW_START: ROW_END, COL_START:COL_END]
return extracted_region
def square_pad_roi(roi_image, pivot):
""" Pads the image with zeros and centers is about the pivot.
This eases rotation about a pivot using scipy.
Assumption: Image Top Left: Array (0, 0)
Assumption: Image Bot Right: Array(Rows, Cols)
:param roi_image: The image with the extracted ROI.
:param pivot: [row, col] pivot position to rotate image about.
row, col should be w.r.t. roi_image co-ords.
:return: square padded image centered about the provided pivot.
"""
r, c = roi_image.shape[:2]
piv_row, piv_col = pivot
corners = [[0, 0], [0, c], [r, c], [r, 0]] # [TL, TR, BR, BL]
dist = math.ceil(max([distance.euclidean(x, pivot) for x in corners]))
pad_row = [abs(piv_row - dist), abs(piv_row + dist - r)]
pad_col = [abs(piv_col - dist), abs(piv_col + dist - c)]
return np.pad(roi_image, [pad_row, pad_col], mode='constant',
constant_values=0)
# This is for Step 2.
def rotate_and_scale(image, angle, out_width) -> np.ndarray:
"""Rotates input image about center and scales it.
:param image: ROI image input which has to be rotated.
Expected to be square in shaped and centered about pivot.
:param angle: Angle in degrees to rotate image by.
:param out_width: width in pixels to fit the image into.
:return: rotated and scaled output image.
"""
img = copy.deepcopy(image)
rotated_roi = ndimage.rotate(img, angle, reshape=False)
zoom_scale = out_width / img.shape[0]
return ndimage.zoom(rotated_roi, zoom_scale)
# This is for Step 3.
def modify_output_image(output_image: np.ndarray,
rotated_roi: np.ndarray):
"""Overwrites inplace the rotated ROI image to the output image."""
THRESHOLD = 5
idx = np.where(rotated_roi > THRESHOLD)
output_image[idx] = rotated_roi[idx]
# This is what you should run.
def problem_logic(input_fits_image: np.ndarray, output_width) -> np.ndarray:
"""Takes input FITS image, and returns a modified image based on usecase."""
output_image = np.zeros((output_width, output_width))
extracted_roi = extract_roi(input_fits_image)
pivot = [0, extracted_roi.shape[1] // 2] # change this based on your req.
pivoted_roi = square_pad_roi(extracted_roi, pivot)
# I am assuming below as your rotation logic.
T0TAL_STEPS = 12 # For each hour orientation.
ROTATION_STEP = float(360 / T0TAL_STEPS) # In degrees.
for i in range(T0TAL_STEPS):
rotated_image = rotate_and_scale(pivoted_roi, ROTATION_STEP * i,
output_width)
modify_output_image(output_image, rotated_image)
return output_image
def write_as_fits(image: np.ndarray, path: str):
""" Writes the numpy image to the provided path in fits format"""
hdu = fits.PrimaryHDU(image)
hdu.writeto(path, overwrite=True)
def driver_main():
sample_fits = np.zeros((50, 100))
sample_fits[:, 70:73] = 255
# This creates the rotated ROI.
# Replace sample_fits with your fits image.
output_img = problem_logic(
input_fits_image=sample_fits, output_width=400
)
# This writes it to output file in fits format.
out_path = "sample.fits"
write_as_fits(output_img, out_path)
# This is just to visualize output.
plt.imshow(output_img, cmap='gray')
plt.show()
if __name__ == "__main__":
driver_main()