上一篇量出來的 5.8% 過衝——Malvar-He-Cutler 在中性正弦光柵上,MTF 在 0.15 cyc/px 衝到 1.058——只交代了現象,沒交代機制的來源。今天把這條路徑的位置算出來:同一個「色度高頻幫亮度補回細節」的通道,把輸入頻率往 Nyquist 推,會從免費銳化翻臉變成摩爾紋與偽色,而翻臉的那個頻率,是可以精確算出來的,不是「越接近 Nyquist 越糟」這種模糊講法。
📖 學
一、Alleysson 2002:亮度與色度在頻域裡分居兩地
這件事最乾淨的推導不是我先想到的,是 David Alleysson、Sabine Süsstrunk、Jeanny Hérault 在 Color Demosaicing by Estimating Luminance and Opponent Chromatic Signals in the Fourier Domain(Color Imaging Conference, 2002;後來的期刊版是 IEEE TIP 2005 的 LMMSE demosaicing)裡做的。
他們把 Bayer CFA 的取樣寫成調變函數:
m_R(x,y) = (1 + cos(πx))(1 + cos(πy)) / 4
m_G(x,y) = (1 − cos(πx)cos(πy)) / 2
m_B(x,y) = (1 − cos(πx))(1 − cos(πy)) / 4
馬賽克陣列 R(x,y) = Σ Cᵢ(x,y)·mᵢ(x,y),拆成常數項(等於各色出現機率 pᵢ)加零均值的漣波項,代入之後整張影像可以寫成:
R(x,y) = Lum(x,y) + Chr(x,y)
Lum = (R + 2G + B) / 4 ← 常數部分,不隨位置調變
Chr = ΣCᵢ(x,y)·m̃ᵢ(x,y) ← 漣波部分,帶著空間調變
取傅立葉轉換之後,九塊能量集中的區域精確對應三個頻率位置,係數是:
| 位置(fx, fy) | 訊號組合 | 權重 |
|---|---|---|
| (0, 0) | R + 2G + B | 1/4 |
| (π, 0) 與 (0, π) | R − B | 1/8 |
| (π, π) | R − 2G + B | 1/16 |
(π 對應到週期 2 像素,也就是 0.5 cyc/px,感測器整張陣列的 Nyquist。)
論文接著把這件事講成一句話:「The replication periodicity of each color in the CFA is 2 in the horizontal and vertical direction. This replication periodicity in the spatial domain carries the chrominance in the Fourier domain at frequency ½ in the horizontal and vertical direction… the chrominance and luminance spectra are maximally separated.」——Bayer CFA 之所以被證明是方格上排三色的最佳解,理由就是它把色度載波精確放在 Nyquist,離基頻的亮度盡量遠。
論文裡還有一句話,直接是上一篇 5.8% 過衝的解釋:「high frequencies in chrominance can improve the high frequencies in the reconstructed luminance.」——去馬賽克重建出來的亮度,之所以能比單獨估計的亮度銳利,正是因為色度通道裡的高頻能量被借用回來補了亮度的高頻。這不是某個演算法的巧思,是這個頻域結構允許的事。
論文把因此產生的視覺假影分成四類:模糊(亮度低通濾波器抓太窄)、平坦區的網格紋(亮度低通抓太寬,把色度的高頻漏進來)、偽色(色度高通抓太寬,把亮度的高頻漏進去)、水彩暈開(色度高通抓太窄)。今天要精確量的,是中間那兩類——網格紋與偽色——各自在什麼頻率開始發生。
二、把機制縮成一維:R/G 交錯的一行像素
完整的二維推導要處理三色,我把它縮到一行足以看穿機制的模型:Bayer 陣列裡任何一行只在兩色之間交錯(R/G 或 G/B),取 R/G 那一行,設
R(x) = L(x) + C(x)
G(x) = L(x) − C(x)
L 是這一行的「亮度」(R、G 的平均),C 是「色度」(R、G 的一半差)。感測器在偶數 x 讀到 R,奇數 x 讀到 G,所以馬賽克訊號是:
mosaic(x) = L(x) + C(x)·(−1)^x
(−1)^x 正是 cos(πx) 在整數點上的樣子——載波頻率精確等於 0.5 cyc/px,和二維模型完全一致,只是少了 B 那一行。
解調的辦法是把 mosaic 再乘一次 (−1)^x:
demod(x) = mosaic(x)·(−1)^x = L(x)·(−1)^x + C(x)·(−1)^(2x) = L(x)·(−1)^x + C(x)
因為 x 是整數,(−1)^(2x) ≡ 1,兩次調變精確抵消,C(x) 原封不動留在基頻。這一步的代價寫在第一項:L(x)·(−1)^x 用「和差頻」公式展開,若 L 帶有頻率 f 的正弦成分,調變後會出現在 |0.5 − f| 這個位置(sin(2πfx)·cos(πx) = ½[sin(2π(f+0.5)x) + sin(2π(f−0.5)x)],折回 [0, 0.5] 就是 |f−0.5|)。同樣的道理反過來也成立:C 裡若帶有頻率 f 的成分,漏進亮度低通的位置也是 |0.5 − f|。
這就是整篇的核心公式:亮度或色度,只要自己的空間頻率 f 靠近 0.5(感測器 Nyquist),折疊之後的位置 |0.5−f| 就會靠近 0——也就是靠近另一個通道的基頻,漏進去。
三、把兩種洩漏各自的臨界頻率算出來
用這個模型跑兩組自寫模擬(numpy,8192 點,理想低通用 FFT 直接截頻,12 個隨機相位取平均;低通寬度 fc_chr = 0.10、fc_lum = 0.30 cyc/px 是我自己選的示範參數,代表某個去馬賽克演算法對色度/亮度各自分配的頻寬,不代表任何實測相機或商用演算法):
情境一(偽色,class 3):真實場景完全中性——R(x) = G(x) = L(x),沒有任何色度,L 帶頻率 f 的正弦、振幅 A = 0.4。理論上一台正確的去馬賽克器應該回報色度 = 0。用 fc_chr = 0.10 的色度低通解調:
| f (cyc/px) | 折疊位置 |0.5−f| | 量到的偽色 RMS |
|---|---|---|
| 0.30 | 0.20 | 0.0024 |
| 0.35 | 0.15 | 0.0023 |
| 0.38 | 0.12 | 0.0008 |
| 0.40 | 0.10 | 0.2712 |
| 0.42 | 0.08 | 0.2828 |
| 0.45 | 0.05 | 0.2828 |
| 0.49 | 0.01 | 0.2828 |
臨界頻率精確落在 f = 0.5 − 0.10 = 0.40 cyc/px,和折疊公式的預測完全對上——f = 0.38 時偽色 RMS 還是 0.0008,f = 0.40 立刻跳到 0.2712。這是一塊完全沒有顏色的細紋(比如黑白格紋窗簾、灰階印刷網點),只因為空間頻率夠高,去馬賽克器就會報告出顏色。
情境二(平坦區網格紋,class 2):真實場景完全無亮度變化(L = 0.5 常數),色度帶頻率 f 的正弦、振幅 A = 0.4(一塊亮度均勻但顏色精細變化的表面,比如某些印花布)。用 fc_lum = 0.30 的亮度低通:
| f (cyc/px) | 折疊位置 |0.5−f| | 量到的亮度漣波 RMS |
|---|---|---|
| 0.15 | 0.35 | 0.0026 |
| 0.20 | 0.30 | 0.1633 |
| 0.25 | 0.25 | 0.2828 |
| 0.30 | 0.20 | 0.2828 |
| 0.40 | 0.10 | 0.2828 |
臨界頻率精確落在 f = 0.5 − 0.30 = 0.20 cyc/px。一塊亮度絕對均勻的表面,只要色彩本身的細節頻率超過 0.20 cyc/px,重建出來的亮度就會憑空出現漣波——這正是 Alleysson 說的「grid effect in flat regions」。
兩組數字有一個共同的尾端:一旦洩漏視窗完全打開,錯誤訊號的 RMS 收斂在 0.2828 ≈ A/√2——正好是振幅 0.4 的正弦波本身的 RMS。這代表洩漏不是「多了一點雜訊」,是被洩漏的那個訊號整個原封不動地印到錯誤的通道上,完全沒有衰減。
四、這解釋了「亮度、色度誰先失守」的不對稱
把兩個臨界頻率並排看:偽色(亮度漏進色度)在 0.40 cyc/px 才出現,網格紋(色度漏進亮度)在 0.20 cyc/px 就出現——亮度撐到接近 80% Nyquist,色度只撐到 40% Nyquist,差了整整一倍。
這不是我選的 fc 剛好湊出這個結果,是設計上的必然:任何一個去馬賽克器,如果想要更銳利的亮度重建(fc_lum 選大一點),代價就是色度細節撐不到那麼高的頻率就開始污染亮度;反過來色度濾得越乾淨(fc_chr 選小一點),偽色門檻推得越高,但色度本身的細節也跟著模糊。這正是論文摘要說的「control the trade-off between algorithm efficiency and quality in an explicit manner」——這個 trade-off 在我的簡化模型裡是兩個數字的直接置換,fc_lum + fc_chr 越大,可用的「安全頻寬」越寬,但兩者不可能同時逼近 0.5,因為載波本身就在 0.5。
這也對得上 DPReview 對 Bayer 感測器的描述:綠色通道在水平垂直方向和感測器原生取樣同速,紅藍通道的線性取樣密度只有綠色的一半(換算面積密度是四分之一)——色度天生就分到比亮度窄的頻寬,我的模擬只是把這個「窄多少」量成一個具體的臨界頻率。
五、DNG 規格書把這個 trade-off 寫成兩個獨立的 tag
這件事在 Adobe DNG Specification 裡有一個很具體的落點。規格書定義了兩個標籤:AntiAliasStrength(tag 50738)與 BaselineSharpness(tag 50732)。已標存疑:我沒能直接從 PDF 抓出逐字條文(PDF 是壓縮串流,自動擷取工具讀不出文字層),以下說明整理自多個獨立轉述來源交叉確認,標籤編號與功能區分一致,但規格書原文的精確措辭我無法逐字覆核。
兩個標籤描述的是同一件事的兩端:AntiAliasStrength 是「給去馬賽克演算法的提示」,告訴 raw 轉檔軟體這台相機的光學低通濾鏡有多強,讓演算法據此調整摩爾紋濾除的力道,即使是全新機型也能自動適配;BaselineSharpness 則是「給後段銳化演算法的提示」,補償不同機型 OLPF 強弱造成的先天銳利度差異。換句話說,規格書把「去馬賽克內建的隱性銳化/防混疊行為」和「去馬賽克之後另外做的顯性銳化」拆成兩個獨立的可調參數——這正好對應到今天算的東西:AntiAliasStrength 調的是 fc_lum、fc_chr 這一類頻寬分配參數,BaselineSharpness 調的是完全在色彩矩陣、色調曲線之後才發生的另一層銳化,兩者不是同一支力道。
六、真實軟體裡,這個 trade-off 有名字
上面推的是理論模型,真實去馬賽克演算法確實照這個 trade-off 分佈。darktable 4.6 使用手冊列出的幾支主力演算法:RCD(目前預設)在高頻細節(細邊、星點)重建與色彩假影之間比較平衡;AMaZE 保留高頻細節的能力更強,但「more prone to color overshoots than RCD」——換算成今天的語言,AMaZE 的 fc_lum 開得比 RCD 寬,代價是偽色臨界頻率被推低;LMMSE 是給高 ISO、易長摩爾紋影像用的,文件明講它「helps manage images exhibiting moiré patterns」——也就是把 fc_lum 收窄以換取更高的網格紋/摩爾紋臨界頻率;VNG4 官方已經不建議用,原因是「loss of some high-frequency details」,同一枚硬幣的另一面。同一張 raw 檔,換一顆去馬賽克演算法,就是在我畫的那條 fc_lum–fc_chr 曲線上挪動位置,不會有一個演算法同時把兩個臨界頻率都推到 0.5。
🧠 記
去馬賽克的「借用」是雙向的,而且各自有精確可算的臨界頻率。 用一維 R/G 交錯模型 mosaic(x) = L(x) + C(x)·(−1)^x,兩次調變 (−1)^(2x) ≡ 1 讓色度原封不動留在基頻,代價是任何頻率 f 的訊號在調變後會折疊到 |0.5 − f|——這個位置一旦落進另一個通道的低通頻寬,就會整段洩漏過去。
偽色(亮度→色度洩漏)的臨界頻率是 f = 0.5 − fc_chr。 自寫模擬(fc_chr = 0.10):中性高頻細節在 f = 0.38 時偽色 RMS 只有 0.0008,f = 0.40 跳到 0.2712,精確對上預測的 0.40。
網格紋(色度→亮度洩漏)的臨界頻率是 f = 0.5 − fc_lum。 自寫模擬(fc_lum = 0.30):平坦亮度 + 精細色彩在 f = 0.20 時亮度漣波 RMS 已經到 0.1633,精確對上預測的 0.20。
兩個臨界頻率會收斂到同一個飽和值:A/√2 ≈ 0.2828。 洩漏一旦完全打開,不是雜訊變大一點,是被洩漏的訊號整段原封不動印到錯誤通道。
亮度撐到 80% Nyquist,色度只撐到 40% Nyquist,差一倍,而且是設計上的必然。 這對得上 Alleysson(2002)的頻域模型:色度載波精確坐在 Nyquist(0.5 cyc/px),用權重 1/4(亮度)、1/8、1/16(兩種色度組合)分居三個頻率位置,「chrominance and luminance spectra are maximally separated」——也對得上 DPReview 對 Bayer 的描述:綠色全速取樣,紅藍線性取樣密度只有一半(面積四分之一)。
「色度是空間低頻」這個先驗,和 09-27 講的「白平衡讓色差歸零」是同一種先驗、不同的失效條件。 上一篇的先驗在中性場景失效,今天這個先驗在高空間頻率失效——兩者可以同時發生:一塊高頻中性細紋,先驗照樣失效,不需要任何真實色彩。
上一篇的 5.8% 過衝,就是這條路徑在安全頻率上的良性版本。 Alleysson 論文原句:「high frequencies in chrominance can improve the high frequencies in the reconstructed luminance」——同一個借用機制,頻率低於臨界值時是免費銳化,高於臨界值時是網格紋與偽色,分界點不是模糊地帶,是一個由 fc 直接決定的硬臨界頻率(在理想低通下)。
DNG 規格書把這件事拆成兩個標籤:AntiAliasStrength(50738,給去馬賽克)與 BaselineSharpness(50732,給後段銳化)。已標存疑——規格書逐字條文未能直接覆核,但標籤編號與功能區分經多來源交叉確認。
真實演算法就活在這條 trade-off 曲線上。 darktable:RCD 平衡、AMaZE 細節多但「more prone to color overshoots」、LMMSE 明確用來壓摩爾紋、VNG4 因高頻損失被棄用——沒有一個演算法能同時把兩個臨界頻率都推到 Nyquist。
✍️ 實踐
把兩組洩漏模擬自己跑一次。 核心只有幾行:
import numpy as np
N = 8192; x = np.arange(N)
def lowpass(sig, fc):
F = np.fft.rfft(sig); f = np.fft.rfftfreq(N, d=1.0)
F[f > fc] = 0
return np.fft.irfft(F, n=N)
# 情境一:中性高頻 -> 偽色
L = 0.4*np.sin(2*np.pi*f_test*x) # f_test 自己掃 0.05~0.49
mosaic = L # C=0,R=G=L
demod = mosaic * ((-1.0)**x)
spurious_chroma = lowpass(demod, 0.10)
# 情境二:平坦亮度 + 精細色彩 -> 亮度漣波
C = 0.4*np.sin(2*np.pi*f_test*x)
mosaic2 = 0.5 + C*((-1.0)**x)
spurious_luma = lowpass(mosaic2, 0.30) - 0.5掃 f_test 從 0.05 到 0.49,畫出 RMS 對頻率的曲線,確認兩個臨界頻率精確落在 0.5 減掉你自己設的低通寬度。換掉 0.10 / 0.30 這兩個數字,看臨界頻率怎麼跟著平移——這比看任何一篇文章的文字描述都直接。
算出你自己相機在戶外會摩爾紋的距離。 用今天的網格紋臨界頻率(0.20 cyc/px,示範值)換算成你相機的真實空間頻率:f_crit(cy/mm) = 0.20 / 像素間距(mm)。再用薄透鏡近似(拍攝距離遠大於焦距時)D = f_crit × p × 焦距,p 是被攝物的重複花紋間距(mm)。例如像素間距 4.35 µm(0.00435 mm)、50 mm 鏡頭、拍一塊間距 3 mm 的紗窗或格柵:f_crit = 0.20/0.00435 ≈ 46.0 cy/mm,D ≈ 46.0 × 3 × 50 ≈ 6900 mm ≈ 6.9 公尺。實際去拍這個距離前後幾公尺的序列,看色彩摩爾紋在哪一段最明顯——換算值和實測值通常有落差,因為真實鏡頭的 MTF 不是理想低通,但量級應該對得上。
同一張 raw,換一顆去馬賽克器,量兩種假影各自的門檻。 用 RawTherapee 或 darktable,同一張含精細規則花紋(紗窗、布料、磚牆)的 raw,分別跑 AMaZE、RCD、LMMSE、VNG4,關掉銳化與降噪。找一塊真正平坦、亮度均勻但顏色細緻變化的區域(如果找得到),比較四顆演算法在那一塊產生的亮度漣波量——LMMSE 應該最乾淨,AMaZE 應該最容易在細節邊緣出現色彩過衝。
檢查自己相機 DNG 檔裡的這兩個標籤。 exiftool -AntiAliasStrength -BaselineSharpness your_file.dng。如果兩個值差很多,代表廠商認為這台相機的物理防混疊與需要的後段銳化量不成比例(比如拿掉了 OLPF 但沒有相應調高 BaselineSharpness)。查不到值也是一個結果——代表這台相機沒有回報這兩個標籤,轉檔軟體只能用預設值猜。
🔗 延伸學習
- Color Demosaicing by Estimating Luminance and Opponent Chromatic Signals in the Fourier Domain(Alleysson, Süsstrunk & Hérault, CIC 2002) — 今天整篇的理論骨幹:亮度與色度在 Bayer CFA 頻域裡的精確位置與權重(1/4、1/8、1/16)、Bayer 是方格三色最佳排列的證明、以及「色度高頻可以幫亮度補高頻」這句話的原始出處。
- Resolution, aliasing and light loss - why we love Bryce Bayer’s baby anyway(DPReview) — 用比較好讀的方式講同一件事:綠色全速取樣、紅藍取樣密度只有一半,可靠鑑別率約在理論 Nyquist 的 0.7 倍,以及為什麼 OLPF 是在花解析度換正確性。
- Digital Negative (DNG) Specification —
AntiAliasStrength(50738)與BaselineSharpness(50732)兩個標籤的規格來源;也是這個系列反覆回來對照的同一份文件。 - Demosaic — darktable 4.6 user manual — 真實軟體裡這條 trade-off 曲線的落點:RCD、AMaZE、LMMSE、VNG4 各自在細節與假影之間選了哪個位置,以及官方對每一顆演算法優缺點的直接描述。
💬 問 AI
我在研究 Bayer CFA 去馬賽克裡「亮度/色度互相洩漏」這件事,想請你幫我核實與延伸。背景:我引用了 Alleysson、Süsstrunk、Hérault 2002 年那篇論文(Color Demosaicing by Estimating Luminance and Opponent Chromatic Signals in the Fourier Domain),裡面把馬賽克影像寫成 Lum=(R+2G+B)/4 加上一個色度漣波項,傅立葉轉換後在 (0,0)、(π,0)/(0,π)、(π,π) 三個位置分別有 1/4、1/8、1/16 的權重,並主張 Bayer CFA 把色度載波精確放在 Nyquist(0.5 cyc/px)是「最佳排列」的證明。
第一組:原始論文與後續發展
1. 這篇論文後來發展成 2005 年 IEEE TIP 的 LMMSE demosaicing,兩篇的核心頻域模型是否一致?LMMSE 版本有沒有修正或推翻 2002 年這篇的任何論點?
2. 「Bayer CFA 是方格上排三色的最佳排列」這個證明,後續有沒有人提出反例或更優的排列(例如 X-Trans、RGBW、或其他非方格排列)?如果有,他們是用什麼指標超越 Bayer 的?
第二組:我自己的一維簡化模型
3. 我把 Bayer 的一整行 R/G 交錯簡化成 mosaic(x) = L(x) + C(x)·(−1)^x,並用「兩次調變抵消、單次調變折疊到 |0.5−f|」推出兩種洩漏(亮度→偽色、色度→亮度漣波)各自的臨界頻率是 0.5 減去對應的低通寬度。這個一維簡化,是否正確反映了完整二維 Bayer(R、G、B 三色)的核心機制?有沒有二維才有、一維模型會漏掉的效應(例如對角方向的取樣)?
4. 我用理想 FFT 硬截頻(brick-wall lowpass)做出來的臨界頻率是精確的階躍;真實去馬賽克演算法的濾波器不是理想低通,臨界頻率會變成漸進的過渡帶。有沒有文獻量過真實演算法(例如 RCD、AMaZE、LMMSE)的等效 fc_lum、fc_chr,或等效的「洩漏開始爬升」頻率?
第三組:DNG 規格書
5. AntiAliasStrength(tag 50738)與 BaselineSharpness(tag 50732)的規格書逐字定義是什麼?我沒能從 PDF 直接擷取文字層,只能用多個轉述來源交叉確認標籤編號與功能區分(前者給去馬賽克、後者給後段銳化),請你核對這個區分是否精確,並指出我可能理解錯的地方。
6. 這兩個標籤在實際 raw 轉檔軟體(Adobe Camera Raw、RawTherapee、darktable、libraw)裡,實作上真的有讀取並套用嗎?還是大部分軟體其實忽略它們、只靠自己的預設?
第四組:對我的意義
7. 如果我想針對「摩爾紋抵抗力」挑一台相機或一套 raw 轉檔流程,除了 OLPF 存在與否、像素間距,darktable 手冊裡 LMMSE「更能處理摩爾紋」這個說法有沒有更系統性的量化評測(不是使用者心得)?
8. 請給我最強的反方論證:我把「亮度/色度洩漏」講成一個由濾波器寬度決定的硬臨界頻率,但真實世界的去馬賽克是內容自適應、非線性、逐像素判斷邊緣方向的(如 09-27 那篇提到的斜邊、模板匹配類演算法)。我這套線性頻域模型,在多大程度上只是一個教學簡化,而非這些現代演算法實際運作的方式?請具體說明現代演算法在哪一步偏離了這個線性框架。
每一點請標明你的把握程度,查不到出處的請直接說查不到。