solid op• 資料種類:image2d × image2d → image2d
• 呼叫: import fullseye as fs; fs.ledger.strain_from_displacement(u: 'Any', v: 'Any', window: 'int', method: 'str', spacing: 'float' = 1.0) -> 'tuple[np.ndarray, np.ndarray, np.ndarray]'(要直接呼叫實作,import dic; dic.strain_from_displacement(u: 'Any', v: 'Any', window: 'int', method: 'str', spacing: 'float' = 1.0) -> 'tuple[np.ndarray, np.ndarray, np.ndarray]';從台帳取用則 opspiv.get("strain_from_displacement"))
• 經台帳呼叫的回傳值: fullseye.ledger.strain_from_displacement(...) 只回傳宣告的 out 型別 image2d 的值(底層函式還會回傳輔助資訊)。需要被捨棄的部分時,請用 fullseye.ledger.strain_from_displacement.raw(...),或直接呼叫 dic.strain_from_displacement。
由位移場求應變場。回傳 (exx, eyy, exy)。
參數(window 與 method 沒有預設值。理由見下)
u x 方向(行)的位移場 [px]。2 維。
v y 方向(列)的位移場 [px]。與 u 同形。
window 局部最小平方窗口的邊長。單位是網格節點數(不是像素)。
奇數。
method "infinitesimal" 或 "green"。其他擲出例外。
spacing 節點間隔 [px]。全像素的稠密場為 1.0(預設)。
若是 piv_cross_correlate 的網格則為 info["step"]。
★ 從 pivops 傳入時 —— 分量順序弄錯會悄悄出錯 flow2d 是 (dy, dx) 的順序。正確寫法::
flow, info = piv_cross_correlate(a, b, window=32, overlap=0.75)
exx, eyy, exy = strain_from_displacement(
flow[1], flow[0], 9, "green", spacing=info["step"])
把 flow[0] 傳給 u 會使 x 與 y 互換,不擲出例外而回傳看似合理的另一個答案。只有直接傳入 3 維陣列時才能附上修正方法加以拒絕,因此對此做了檢查。
定義以 window x window 的平面擬合求出 ux = ∂u/∂x 等,
• "infinitesimal"(微小應變、工程應變) exx = ux, eyy = vy, exy = ½(uy + vx)
• "green"(Green-Lagrange) exx = ux + ½(ux² + vx²), eyy = vy + ½(uy² + vy²), exy = ½(uy + vx + ux·uy + vx·vy)
★★ 為什麼 method 不設預設值 —— 剛體轉動造成的假象設試片只是轉動了 θ,材料連 1 微米也沒有伸長。真實應變為 0。把嚴格的剛體轉動位移場 u = (cosθ-1)x - sinθ·y, v = sinθ·x + (cosθ-1)y 不經過影像直接輸入的實測(單位 µε = 1e-6):
θ [度] cosθ-1 infinitesimal piv_velocity_gradient green
0.5 -38.1 -38.1 -38.1 5.3e-14
1.0 -152.3 -152.3 -152.3 9.3e-14
2.0 -609.2 -609.2 -609.2 2.0e-13
5.0 -3805.3 -3805.3 -3805.3 6.5e-13
2 度時 -609 µε,是鋼的降伏應變(約 2000 µε)的 3 成。 Green-Lagrange 中 exx = (cosθ-1) + ½((cosθ-1)² + sin²θ) = 0 在代數上嚴格成立,因此降到 1e-13。既有的 piv_velocity_gradient 回傳與微小應變相同的值(= 帶著同樣的假象),piv_strain_rate 在 2 度時回傳 +1218 µε (2|cosθ-1|) —— 對於流體的線性化轉動 u=-ωy, v=ωx,這個量為 0,但在有限轉動下不為 0。
反過來,在材料試驗報告、標準、與應變計的對照中,微小應變是標準,若默默回傳 Green-Lagrange,數字就對不上。哪個正確會隨場景而反轉。所以讓使用者選擇。
★ 但並不是「用 green 就安全」 —— 估計誤差會原樣通過 Green 的修正項 ½(ux²+vx²) 由估計的梯度構成,因此梯度估計不好,修正也不好。實測(解析散斑 256²、剛體轉動、MARGIN 40 內側的平均 ± 離散,單位 µε):
θ [度] cosθ-1 | piv+LS w=9 微小 green | lk+LS w=31 微小 green
2.0 -609.2 | -42.9 ± 428 564.7 ± 429 | -698.8 ± 2122 -84.4 ± 2132
5.0 -3805.3 | 364.9 ± 9532 3843.4 ± 9638 | -1372.9 ±22909 2759.6 ±25685
lk 的 2 度與教科書一致(-699 ≒ -609 的假象 → 用 green 減到 -84)。但 piv 的 2 度連微小應變都只回傳 -42.9 —— 因為轉動的子區使相關變鈍,梯度估計本身在 ±500 µε 範圍內晃動,在此之上再加 +609 µε 的 Green 修正,反而變成 +565 µε。5 度以上時兩種估計器的離散都超過 1e4 µε,平均值沒有意義。 關於定義的討論,只有在梯度能以那種精度量出時才起作用。
★ window 就是空間解析度本身從同一個 piv 位移場讀回均勻應變的實測(µε):
真值 piv_velocity_gradient w=3 w=5 w=9
100 100.4 ± 21.8 100.4 ± 16.0 100.3 ± 6.4 100.3 ± 1.7
500 501.8 ± 107.2 502.0 ± 78.9 501.4 ± 31.3 501.2 ± 8.6
2000 1996.3 ± 342.0 1996.6 ± 259.5 1994.8 ± 99.3 1995.6 ± 25.9
20000 19768.8 ± 2909.9 19768.9 ± 2210.5 19742.7 ± 790.9 19754.1 ± 209.6
平均全都相同。只有離散隨 w 縮小,最多縮小到 13.9 分之一。 代價是 w=9 把 9 個節點(step=8 時為 72 px)視為平坦,因此在缺口尖端這類有曲率的應變場中會低估峰值。對稱窗口的最小平方對 1 次應變場嚴格回傳,但對彎曲的場會變鈍。若設預設值,數字就會建立在你不記得選過的權衡之上。
★ NaN 的處理 —— 不以 0 填補 u 或 v 中有 NaN 時,包含該點的 window x window 擬合無法定義。含 NaN 的窗口的輸出全部設為 NaN (把 u/v 兩者的缺測合併成 1 個遮罩,套用到 3 個分量)。若把 NaN 視為 0,量不到的點會作為「位移 0 的點」影響擬合,在周圍造出看似真實的虛假應變梯度。
fail-closed
• u / v 不是 2 維、形狀不同、小於 4x4。
• 把 (2, h, w) 的 flow2d 整個傳給了 u(附上修正方法拒絕)。
• window 為偶數、小於 3、比場還大。
• spacing 非正、非有限。
• method 不是 "infinitesimal" / "green"。
• 省略 window 與 method 的呼叫會得到 TypeError (因為沒有設預設值,直接在 Python 的引數機制中失敗)。
• 範例資料目錄(下載 URL / 授權) —— 2-D 用 skimage.data(BSD/公有領域)加合成圖,3-D 給出真實資料源(Stanford/PDS 等)的下載 URL。
• 運算子來歷與參考文獻 —— 該運算子族所依據的研究/方法出處。
• 演算法的正典(作者、年份)與用途見上面的族使用指南。
• poc_dic_strain — py -3.11 examples/poc_dic_strain.py
image2d 作為輸入)piv_cross_correlate · piv_multipass · piv_deform_pass · correlation_quality · speckle_quality
solid)correlation_quality · speckle_quality
*Provenance: dic.py — PIV 運算子登記表。本條目由 tools/opdocs.py md 自動產生(請勿手動編輯)。*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.