圖像中的傅立葉變換(一)
關於傅立葉變換,知乎上已經有一篇很好的教程,因此,這篇文章不打算細講傅立葉的物理含義,只是想從圖像的角度談一談傅立葉變換的本質和作用。
本文假設讀者已經熟知歐拉公式:
\[
e^{j\pi x}=\cos{\pi x}+j\sin{\pi x}
\]
並且知道高數課本中給出的傅立葉變換公式:
\[
f(x) ~ \frac{a_0}{2}+\sum_{n=1}^{\infty}{[a_n \cos{nx}+b_n\sin{nx}]}
\]
其中 \(a_n=\frac{1}{\pi}\int_{-\pi}^{\pi}{f(x)\cos{nx}}dx\),\(b_n=\frac{1}{\pi}\int_{-\pi}^{\pi}{f(x)\sin{nx}}dx\)
當然,線性代數也還是要懂一些的。
圖像的表示
傅立葉變換本質上是把信號從時空域變換到頻率域。但在圖像裏面,這個本質又說明什麽呢?
為了搞清楚這一點,我們先回顧一下,什麽是圖像。
通常來說,我們看到的計算機裏的圖像是一個二維矩陣:
比如,上面這個只有四個像素點的圖片,就是一個這樣的矩陣(不要在意數值大小,你可以把它們歸一化到常用的 0~255 區間,但本質上它們表達的信息是一樣的):
\[
\begin{bmatrix}
0.4 & 0.6 \0.8 & 0.2
\end{bmatrix}
\]
假設圖像是 \(f(x)\),這個 \(f(x)\) 就是我們常說的信號。這個信號表面上看是一個矩陣,其實它是由幾個最基本的向量的線性組合產生的:
\[
f(x)=0.4 \times \begin{bmatrix}1 & 0 \\ 0 & 0 \end{bmatrix}+0.6 \times \begin{bmatrix}0 & 1 \\ 0 & 0 \end{bmatrix}+0.8 \times \begin{bmatrix}0 & 0 \\ 1 & 0 \end{bmatrix}+0.2 \times \begin{bmatrix}0 & 0 \\ 0 & 1 \end{bmatrix}
\]
如果看到這裏你有一種恍然大悟的感覺,那你差不多快摸清傅立葉的套路了。
其實,從線性代數的角度出發去思考問題,你會發現,圖像這種信息是由一些最基本的元素組合而成的。這些元素在線性代數中被稱為基向量,它們構成的集合稱為基底。選擇不同的基底,信息就可以有多種不同的表示。例如上圖中,我們選擇的是最常見的基底:
\[
\{\begin{bmatrix}1 & 0 \\ 0 & 0 \end{bmatrix} , \begin{bmatrix}0 & 1 \\ 0 & 0 \end{bmatrix} , \begin{bmatrix}0 & 0 \\ 1 & 0 \end{bmatrix}, \begin{bmatrix}0 & 0 \\ 0 & 1 \end{bmatrix}\}
\]
在這組基底下,圖片就表示為:\(\begin{bmatrix} 0.4 & 0.6 \\ 0.8 & 0.2 \end{bmatrix}\)。
如果換成另外一組基底,就會得到另一種表示。甚至,在計算機視覺中,我們常常會提取圖像的語義信息,把圖像轉換到其他一些高維空間。但不管怎樣,它們本質上都是從某一個特殊的角度來表示圖像這一信息,只是不同的基底下,表示出來的特征有所不同,有些適合肉眼觀看,有些適合計算機識別。
那傅立葉變換是想幹嘛?其實就是換了另一種基底(正/余弦函數)來表示圖像。傅立葉變換之所以重要,是因為它所采用的基底具有一些非常好的性質,可以方便我們對圖像進行處理。
傅立葉變換
這一節中,我們就來看看,如何把圖像用傅立葉的基底表示出來,也就是我們常說的圖像的傅立葉變換。
首先,要明確,在一組基底下,信息的表示是什麽。回到上一節的例子,\(f(x)=\begin{bmatrix} 0.4 & 0.6 \\ 0.8 & 0.2 \end{bmatrix}\),有沒有發現,在特定基底下,信息是用這些基底線性組合的權重來表示的。只要我們有了這些權重信息,就可以用基底向量的線性組合把信息恢復出來。
因此,對於傅立葉變換而言,我們要求的其實就是基底的權重。
那傅立葉變換的基底是什麽呢?如果你看過前面說的那篇教程,你會發現,傅立葉是用無窮多個三角函數的疊加來逼近原來的信號。因此,對於傅立葉變換而言,它的基底其實就是這些三角函數,而我們要求的則是這些函數的線性組合參數。
回到最開始的傅立葉公式:
\[
f(x) ~ \frac{a_0}{2}+\sum_{n=1}^{\infty}{[a_n \cos{nx}+b_n\sin{nx}]}
\]
有沒有看到,這個公式已經揭示了這些三角函數的系數,也就是我們要求的線性組合參數。公式前面的 \(a_0\) 是可以統一進去的。下面,我們就從它出發,看看如何推導出統一的參數表示。
(??以下是公式重災區,恐懼者可直接跳到結論部分)
首先,我們考慮更一般的情況,即函數 \(f(x)\) 的周期是 \(T\)(上面這個公式的周期是 \(2\pi\)),然後將 \(f(x)\) 表示成另一種形式:
\[
f(x)=a_0+\sum_{n=1}^\infty {[a_n\cos{\frac{2n\pi x}{T}}+b_n \sin{\frac{2n\pi x}{T}}]}
\]
其中,\(a_0=\frac{1}{T}\int_0^T{f(x)dx}\),\(a_n=\frac{2}{T}\int_{0}^T{f(x)\cos{\frac{2n\pi x}{T}dx}}\),\(b_n=\frac{2}{T}\int_0^T{f(x)\sin{\frac{2n\pi x}{T}dx}}\)。
註意,這個表示和之前的公式沒有本質區別。
接下來,對 \(f(x)\) 進行一系列操作:
\[
\begin{eqnarray}
f(x)&=&a_0+\sum_{n=1}^\infty {[a_n\cos{\frac{2n\pi x}{T}}+b_n \sin{\frac{2n\pi x}{T}}]} \&=&a_0+\sum_{n=1}^{\infty}{[a_n\cos{\omega_nx+b_n\sin{\omega_nx}}]} \\
&=&a_0+\sum_{n=1}^\infty{[a_n(\frac{e^{j\omega_n x}+e^{-j\omega_n x}}{2})+b_n(\frac{e^{j\omega_n x}-e^{-j\omega_n x}}{2j})]} \&=&a_0+\sum_{n=1}^\infty{(\frac{a_n-jb_n}{2})e^{j\omega_n x}+\sum_{n=1}^\infty{(\frac{a_n+jb_n}{2})e^{-j\omega_nx}}}
\end{eqnarray}
\]
其中,\(\omega_n=\frac{2n\pi}{T}\)。
下一步,繼續化簡括號裏的東西:
\[
\begin{eqnarray}
\frac{a_n-jb_n}{2}&=&\frac{1}{2}[\frac{2}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}f(x)\cos{\omega_n x\ dx-j\frac{2}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}f(x)\sin{\omega_nx\ dx}}] \&=&\frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}f(x)[\cos{\omega_n x-j\sin{\omega_n x}}]\ dx \&=&\frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}{f(x)e^{-j\omega_n x}}\ dx \&=&c_n
\end{eqnarray}
\]
其中,\(c_n=\frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}{f(x)e^{-j\omega_n x}}\ dx\)。
用上面的結果化簡公式右邊的內容:
\[
\begin{eqnarray}
\sum_{n=1}^\infty{(\frac{a_n+jb_n}{2})e^{-j\omega_n x}}&=&\sum_{n=-\infty}^{-1}{(\frac{a_{-n}+jb_{-n}}{2})e^{-j\omega_{-n}x}} \&=&\sum_{n=-\infty}^{-1}{(\frac{a_n-jb_n}{2})e^{j\omega_n x}} \&=&\sum_{n=-\infty}^{-1}{(\frac{a_n-jb_n}{2})e^{j\omega_n x}} \&=&\sum_{n=-\infty}^{-1}{c_n e^{j\omega_n x}}
\end{eqnarray}
\]
這樣一來,我們就得到一個統一的表達式:
\[
\begin{eqnarray}
f(x)&=&a_0+\sum_{n-1}^{\infty}{(\frac{a_n-jb_n}{2})e^{j\omega_n x}+\sum_{n=1}^{\infty}{(\frac{a_n+jb_n}{2})e^{-j\omega_n x}}} \&=&c_0+\sum_{n=1}^{\infty}{c_ne^{j\omega_n x}+\sum_{n=-\infty}^{-1}c_n e^{j\omega_n x}} \&=&\sum_{n=-\infty}^{\infty}{c_ne^{j\omega_n x}}
\end{eqnarray}
\]
碼了這麽多公式後,我們終於得到了一個關於三角函數的線性組合的形式。再經過傅立葉變換後,函數 \(f(x)\) 就變成了一個向量的形式:\({[\dots, c_{-n}, \dots, c_0, c_1, c_2, \dots, c_n, \dots]}\)。這裏的 \(c_n\) 就是我們通常說的傅立葉變換,而公式中的 \(e^{j\omega_nx}\) 就是傅立葉變換的基底。
接下來,我們想知道,對於一張圖片而言,這個 \(c_n\) 該怎麽求。
我們先考慮一維的情況(你可以想象成一個寬度為 \(N\),高度為 1 的圖片)。在公式中,\(c_n=\frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}{f(x)e^{-j\omega_n x}}\ dx\),這是對連續函數而言的,但計算機中的圖像信號是離散的,因此,我們要把積分符號換成求和符號。另外,周期用圖像的寬度代替。這樣,我們就得到圖像中的傅立葉變換:\(c_n=\frac{1}{N}\sum_{x=0}^{N-1}f(x)e^{-j\omega_n x}\)。
然後,有同學會問,這樣的 \(c_n\) 有多少個呢?在我們前面推導的公式中,\(c_n\) 有無窮多個,這時符合傅立葉的前提假設的:無窮多個三角函數的疊加才能構成原來的信號。但是,計算機只能表示有窮的信息,因此,我們需要進行采樣。好在,實際情況中,當 \(n\) 的值越來越大時,\(c_n\) 的值會漸漸趨於 0,因為圖片中的高頻分量往往比較小,所以這一部分高頻的三角函數的系數 \(c_n\) 的值也會很小(公式中,頻率 \(\omega_n=\frac{2n\pi}{N}\),\(n\) 越大也就表明頻率越大)。實際操作中,我們會取 \(N\) 個 \(c_n\),其中 \(N\) 就是圖像信號的周期。因此,我們最終得到圖像中的傅立葉變換:
\[
F(u)=\frac{1}{N}\sum_{x=0}^{N-1}f(x)e^{-j2\pi ux/N} , \ \ u=0,1,...,N-1
\]
公式中的 \(f(x)\) 指的就是圖片中 x 位置的像素值,這也說明,傅立葉變換是綜合計算圖像像素的整體灰度變化後得到的。如果圖像中高頻信息比較大(即圖像灰度變化很劇烈),則對於頻率高的基底向量(\(u\) 的值比較大),其對應的權重 \(F(u)\) 的值也會比較大,反之亦然。
傅立葉逆變換
所謂傅立葉逆變換,就是在得到一堆傅立葉變換的參數 \(F(u)\) 後,如何反推回去,得到空間域的圖像。
其實非常簡單,前面說了,傅立葉變換就是把時空域下的圖像信號 \(f(x)\) 重新用頻率域的基底來表示。現在,頻率域基底向量的系數 \(F(u,v)\) 已經有了,把它們組合起來就可以得到原來的信號:\(f(x)=\sum_{n=-\infty}^{\infty}{c_ne^{j\omega_n x}}\)。因此,傅立葉逆變換就是把傅立葉基底向量的系數再累加起來:
\[
f(x)=\sum_{u=0}^{N-1}F(u)e^{j2\pi ux/N}, \ \ x=0,1,...,N-1
\]
二維傅立葉
二維傅立葉其實就是在一維的基礎上,繼續向另一個方向擴展而已,相當於一個二重積分:
\[
\begin{eqnarray}
F(u, v)&=&\frac{1}{MN}\sum_{x=0}^{M-1}\sum_{y=0}^{N-1}f(x, y)e^{-j2\pi ux/M}e^{-j2\pi vy/N} \\end{eqnarray}
\]
傅立葉逆變換:
\[
f(x,y)=\sum_{u=0}^{M-1}\sum_{v=0}^{N-1}F(u,v)e^{j2\pi ux/M}e^{j2\pi vy/N}
\]
參考
- 傅裏葉分析之掐死教程
圖像中的傅立葉變換(一)