簡體   English   中英

Python - 給定 function 的值,查找二維高斯的 x 和 y 值

[英]Python - Find x and y values of a 2D gaussian given a value for the function

我有一個二維高斯 function f(x,y) 我知道x₀的峰值g₀出現時的值y₀和 y₀。 但是后來我想找到f(xₑ, yₑ) = g₀ / e¹處的xₑyₑ值。 我知道有多種解決方案,但至少有一個就足夠了。

到目前為止我有

def f(x, y, g0,x0,y0,sigma_x,sigma_y,offset):
    return offset + g0* np.exp(-(((x-x0)**(2)/(2*sigma_x**(2))) + ((y-y0)**(2)/(2*sigma_y**(2)))))

所有作為參數的變量都是已知的,因為它們是從曲線擬合中提取的。

我知道在x中取導數並設置f() = 0並在y中類似地給出(x,y)的可解線性系統,但這似乎是手動實現的過大殺傷力,必須有一些庫或工具在那里那可以做我想達到的目標嗎?

有無數種可能性(或者在關於g0的值的特殊情況下可能有 1 種微不足道或沒有)。 可以使用直接方法在常數時間內分析計算解。 無需近似或迭代方法即可找到給定 function 的根。它只是純數學。

高斯 kernel 具有有趣的對稱性 其中之一是當峰值轉換為(0,0)時旋轉的不變性。 另一個是二維高斯曲面的一維截面是高斯曲線。

讓我們暫時忽略offset :它並沒有真正改變問題(它只是一個 Z 軸平移)並為分辨率添加了額外的無用術語。

問題的幾何解是一個橢圓,所以解(xe, ye)遵循圓錐表達式(xe-x0)² / a² + (ye-y0)² / b² = 1 如果sigma_x = sigma_y ,則解決方案更簡單:這是一個表達式為(xe-x0)² + (ye-y0)² = r 請注意, abr取決於搜索值和 kernel 參數(例如sigma_x )。 更改sigma_xsigma_y就像拉伸空間一樣,因此解決方案類似。 改變x0y0就像平移空間,所以解決方案也是如此。

事實上,我們可以解決x0=0y0=0sigma_x=1sigma_y=1的更簡單情況的問題。 然后我們可以應用平移,然后使用變換矩陣進行線性變換。 一個基本的乘法 4x4 矩陣可以做到這一點。 解決更簡單的情況要容易得多,因為要考慮的參數更少。 實際上, g0offset也可以部分舍棄f ,因為它在表達式的兩邊,只需要求解線性方程offset + g0 * h(xe,ye) = g0 / e so h(x,y) = 1 / e - offset / g0其中h(xe, ye) = exp(-(xe² + ye²)/2) 假設我們暫時忘記平移和線性變換,問題可以很容易地解決:

h(xe, ye) = 1 / e - offset / g0
exp(-(xe² + ye²)/2) = 1 / e - offset / g0
-(xe² + ye²)/2 = ln(1 / e - offset / g0)
xe² + ye² = -2 * ln(1 / e - offset / g0)

而已! 我們得到了我們的圓表達式,其中半徑r-2*ln(1 / e - offset / g0) 請注意,表達式中的ln基本上是自然對數。

現在我們可以嘗試找到 4x4 矩陣系數,或者實際上嘗試直接求解完整的表達式,這終於沒有那么困難了。

offset + g0 * exp(-((x-x0)²/(2*sigma_x²) + (y-y0)²/(2*sigma_y²))) = g0 / e
exp(-((x-x0)²/(2*sigma_x²) + (y-y0)²/(2*sigma_y²))) = 1 / e - offset / g0
-((x-x0)²/(2*sigma_x²) + (y-y0)²/(2*sigma_y²)) = ln(1 / e - offset / g0)
((x-x0)²/sigma_x² + (y-y0)²/sigma_y²)/2 = -ln(1 / e - offset / g0)
(x-x0)²/sigma_x² + (y-y0)²/sigma_y² = -2 * ln(1 / e - offset / g0)

而已! 我們得到了圓錐表達式,其中r = -2 * ln(1 / e - offset / g0)是常數, a = sigma_xb = sigma_y是上述表達式中的未知參數。 可以使用a = sigma_x/sqrt(r)b = sigma_y/sqrt(r)對其進行歸一化,因此右側為 1,與上面的表達式完全吻合,但這只是一些數學細節。

您可以輕松找到橢圓的一個點,因為您知道橢圓的中心(x0, y0)並且在直線y=y0和上述二次曲線的交點處至少有 1 個點。 讓我們找到它:

(x-x0)²/sigma_x² + (y0-y0)²/sigma_y² = -2 * ln(1 / e - offset / g0)
(x-x0)²/sigma_x² = -2 * ln(1 / e - offset / g0)
(x-x0)² = -2 * ln(1 / e - offset / g0) * sigma_x²
x = sqrt(-2 * ln(1 / e - offset / g0) * sigma_x²) + x0

請注意,有兩種解決方案 ( -sqrt(...) + x0 ),但您只需要其中一種。 我希望我在計算中沒有犯任何錯誤(至少細節應該足以輕松找到它)並且解決方案在您的情況下不是一個復雜的數字。 這個解決方案的好處是計算速度非常非常快

最終的解決方案是:
(xe, ye) = (sqrt(-2*ln(1/e-offset/g0)*sigma_x²)+x0, y0)

暫無
暫無

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

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