簡體   English   中英

從 2d numpy 數組中提取旋轉的 1d 輪廓的結果不一致

[英]Inconsistent results from extracting rotated 1d profiles from 2d numpy array

我有一個代表圖像的 2D numpy 數組(見下文)。 頻段 3 的中央 PSF:http://wise2.ipac.caltech.edu/docs/release/allsky/expsup/sec4_4c.html#rchisqind

圖像中的橢圓形對象從垂直 y 軸旋轉角度theta 在我的代碼中,我想測量物體在各個位置的 FWHM(包括通過將最大化的位置,角度為theta的半長軸)。

為此,我使用了來自這兩個問題的技術(以給定的角度提取線,然后使用 UnivariateSpline 計算給定 1d 輪廓的 FWHM): 如何從 numpy 數組中提取任意線值? 找到峰的半峰全寬

但是,我注意到我的結果不一致。 如果我從整個圖像(這是一個 (641, 641) 數組)中以給定角度提取輪廓,我得到的 FWHM 結果與從 (100,100) 子圖像中以相同角度獲取輪廓的結果不同對象居中的位置。 我意識到由於該方法涉及插值,因此我可能會沿配置文件獲得不同的值。 但我需要的是一種可靠且一致的方法來計算這些 FWHM,以及它最大化的角度(因為現在它給了我一個不同的子圖像和整個圖像的角度)。 這是我的代碼:

import numpy as np
from scipy.interpolate import UnivariateSpline

def profiles(image, theta):
    max_y, max_x = np.where(image==1) #the image has been normalized so that the highest intensity point=1
    max_y, max_x = max_y[0], max_x[0]

    subimage = image[max_y-50:max_y+50, max_x-50:max_x+50] # now the maximum is exactly centered at (50, 50)

    # Set up to extract profiles (do two legs to ensure it passes through centroid)
    x_maj_1, y_maj_1 = 50-50*np.tan(theta), 0
    mid_x, mid_y = 50, 50
    x_maj_2, y_maj_2 = 50+50*np.tan(theta), 99

    # Form axes
    length_maj = int(round(np.hypot(x_maj_2-x_maj_1, y_maj_2-y_maj_1)))
    x1, y1 = np.linspace(x_maj_1, mid_x, length_maj//2), np.linspace(y_maj_1, mid_y, length_maj//2)
    x2, y2 = np.linspace(mid_x, x_maj_2, length_maj//2)[1:], np.linspace(mid_y, y_maj_2, length_maj//2)[1:]

    # Concatenate legs
    x_maj = np.concatenate((x1, x2), axis=0)
    y_maj = np.concatenate((y1, y2), axis=0)

    # Get profile
    z_maj = subimage[y_maj.astype(np.int), x_maj.astype(np.int)]
    return z_maj

def interpolate_width(axis):
    half_max = 1/2
    x = np.arange(0, len(axis))
    spline = UnivariateSpline(x, axis-half_max, s=0)
    r1, r2 = spline.roots()
    return r2-r1 #FWHM in pixel units

現在,要找到 FWHM 最大化時與 y 軸的角度:

thetas = np.arange(0, 45, 0.5)
widths = []
for theta in thetas:
    theta = np.deg2rad(theta)
    z = profiles(image, theta)
    width = interpolate_width(z)
    widths.append(width)

fwhm_maj = max(widths)
angle_arg = np.array(widths).argmax()
angle_max = thetas[angle_arg]
print('Maximized FWHM and associated position angle:', fwhm_maj, angle_max)

輸出: Maximized FWHM and associated position angle: 20.899 14.5

從我鏈接的網站上的信息來看,圖像的像素尺度是0.275弧秒。 因此乘以它,FWHM 應在 14.5 度的位置角處達到最大值,其值約為 5.75 弧秒。 但是,網站上的表 1 清楚地表明,距 y 軸的最大位置角僅為 6 度,並且長軸的 FWHM 為 7.36 弧秒。 所以這里一定有問題。

如果我再次運行此代碼但在整個圖像而不是子圖像上運行,則角度和 FWHM 會得到完全不同的結果。 有誰知道我如何找到更一致(和准確)的方法? 謝謝!

不是 100% 確定,但您似乎將線坐標對齊到像素網格,這對我來說很不准確。 此外,“倒置信箱”(白條)可能會混淆您的程序? 也許使用適當的 2D 插值和剪輯圖像會更安全,如下所示:

import numpy as np
from scipy import ndimage, interpolate, optimize

img = ndimage.io.imread('VJQwQ.png')
# b&w
img = img[..., 0]
# cut "white letterbox"
img = img[:, np.where(np.any(img!=255, axis=0))[0]]

# setup interpolator for off grid pixel values
x, y = img.shape
x, y = (np.arange(z) - (z-1)/2 for z in (x, y))
intr = interpolate.RectBivariateSpline(x, y, img, kx=3, ky=3)
s = np.arange(-50, 51)

# setup line sections
# for simplicity we assume the peak is in the center
def at_angle(phi):
    def f(s, shift=0):
        x, y = np.cos(phi)*s, np.sin(phi)*s
        return intr(x, y, grid=False) - shift
    return f

# example
phi = np.pi/3
f = at_angle(phi)
mx = f(0)
left = optimize.brentq(f, -50, 0, (mx/2,))
right = optimize.brentq(f, 0, 50, (mx/2,))

# plot it
from matplotlib import pylab
pylab.plot(s, f(s))
pylab.plot([left, left], [0, mx])
pylab.plot([right, right], [0, mx])
pylab.plot([-50, 50], [mx/2, mx/2])
pylab.savefig('tst.png')

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM