文章目錄
- 前言
- 一、傅里葉變換
- 1.1 離散傅里葉變換
- 1.1.1 離散傅里葉變換原理
- 1.1.2 離散傅里葉變換公式
- 1.1.3 代碼實現
- 1.1.4 cv2.dft 函數解析
- 1.2 傅里葉變換進行卷積
- 1.2.1 傅里葉變換卷積原理
- 1.2.2 傅里葉變換卷積公式
- 1.2.3 代碼實現
- 1.2.4 cv2.mulSpectrums 函數解析
- 1.3 離散余弦變換
- 1.3.1 離散余弦變換原理
- 1.3.2 離散余弦變換公式
- 1.3.3 代碼實現
- 1.3.4 cv2.dct函數解析
- 1.4 傅里葉逆變換
- 1.4.1 傅里葉逆變換原理
- 1.4.2 傅里葉逆變換公式
- 1.4.3 代碼實現
- 二、積分圖像
- 2.1 積分圖像原理
- 2.2 代碼實現
- 總結
前言
在當今數字時代,圖像無處不在,而圖像分析成為解讀、理解和處理這些圖像的關鍵技術之一。本文將介紹圖像分析的基礎知識,并結合OpenCV中的強大功能,深入探討圖像分析的傅里葉變換、積分圖像。
一、傅里葉變換
1.1 離散傅里葉變換
傅里葉變換是一種強大的數學工具,常用于將信號從時域轉換到頻域。在圖像處理領域,離散傅里葉變換是一項重要而常用的技術,它能夠將圖像表示為不同頻率分量的集合,為后續的圖像分析提供了豐富的信息。
1.1.1 離散傅里葉變換原理
離散傅里葉變換(Discrete Fourier Transform,DFT)通過將一個離散序列(如圖像中的像素值)轉換為一組復數,表示原始序列中不同頻率的分量。其原理基于復數的正弦和余弦函數,通過這些函數的組合,可以表示原始信號在頻域中的分布情況。
1.1.2 離散傅里葉變換公式
傅里葉變換的數學表達式如下:
F ( u , v ) = ∑ x = 0 M ? 1 ∑ y = 0 N ? 1 f ( x , y ) ? e ? j 2 π ( u x M + v y N ) F(u, v) = \sum_{x=0}^{M-1} \sum_{y=0}^{N-1} f(x, y) \cdot e^{-j2\pi\left(\frac{ux}{M} + \frac{vy}{N}\right)} F(u,v)=x=0∑M?1?y=0∑N?1?f(x,y)?e?j2π(Mux?+Nvy?)
其中, f ( x , y ) f(x, y) f(x,y) 是輸入圖像的像素值, F ( u , v ) F(u, v) F(u,v) 是變換后的頻域表示, M M M 和 N N N 分別是圖像的寬度和高度, u u u 和 v v v 是頻域中的坐標。
- f ( x , y ) f(x, y) f(x,y): 輸入圖像在時域中的像素值。
- F ( u , v ) F(u, v) F(u,v): 輸出圖像在頻域中的表示。
- e ? j 2 π ( u x M + v y N ) e^{-j2\pi\left(\frac{ux}{M} + \frac{vy}{N}\right)} e?j2π(Mux?+Nvy?): 復指數項,描述了正弦和余弦函數的組合,表示不同頻率分量的貢獻。
1.1.3 代碼實現
在OpenCV中,進行離散傅里葉變換可以使用cv2.dft
函數。以下是一個簡單的例子:
import cv2
import numpy as np# 讀取圖像
img = cv2.imread('tulips.jpg', 0)# 進行傅里葉變換
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)# 將變換后圖像的低頻部分轉移到圖像的中心
dft_shift = np.fft.fftshift(dft)# 計算幅度譜
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
# 將結果標準化到0~255
magnitude_spectrum_normalized = cv2.normalize(magnitude_spectrum, None, 0, 255, cv2.NORM_MINMAX)# 顯示頻譜圖像
cv2.imshow('Magnitude Spectrum', cv2.hconcat([img, np.uint8(magnitude_spectrum_normalized)]))
cv2.waitKey(0)
cv2.destroyAllWindows()
magnitude_spectrum
是通過對傅里葉變換的結果進行處理而得到的圖像,表示了圖像在頻域中的幅度信息。
cv2.magnitude
是OpenCV中用于計算二維向量幅度的函數。在頻域中,圖像被表示為復數,包括實部和虛部。幅度譜是通過計算復數的幅度(模)得到的,其數學定義為:
A ( u , v ) = R ( u , v ) 2 + I ( u , v ) 2 A(u, v) = \sqrt{R(u, v)^2 + I(u, v)^2} A(u,v)=R(u,v)2+I(u,v)2?
其中, A ( u , v ) A(u, v) A(u,v) 是頻域中的幅度譜, R ( u , v ) R(u, v) R(u,v) 和 I ( u , v ) I(u, v) I(u,v) 分別是傅里葉變換結果的實部和虛部。
對于圖像處理而言,cv2.magnitude
的主要作用在于可視化圖像中不同頻率分量的強度。在生成的圖像中,亮度較高的區域表示具有較大幅度的頻率分量,而亮度較低的區域表示幅度較小的頻率分量。
通常,頻譜中心附近的低頻分量會占據亮度較高的區域,而高頻分量則分布在圖像的邊緣。通過觀察 cv2.magnitude
,我們可以了解圖像中哪些頻率分量對圖像的整體特征起到了關鍵作用。這對于識別圖像中的紋理、邊緣等特征是非常有幫助的。
在實際圖像處理中,cv2.magnitude
的應用不僅限于觀察,還可以用于一些頻域濾波操作,如頻域濾波器的設計和應用,以實現圖像增強、去噪等目的。
1.1.4 cv2.dft 函數解析
cv2.dft
方法是 OpenCV 中用于執行一維或二維離散傅里葉變換的函數。該函數支持多種變換類型和操作模式,能夠對輸入的實數或復數數組進行傅里葉變換。以下是對 cv2.dft
方法的簡要說明:
參數:
src
: 輸入圖像,數據類型為浮點型或復數型的 numpy 數組。dst
: 輸出數組,用于存儲變換結果。如果未提供,則函數會創建一個具有相同類型和大小的數組。flags
: 變換標志,控制傅里葉變換的行為。常用的標志包括:
cv2.DFT_COMPLEX_OUTPUT
: 輸出為復數數組,包含實部和虛部。cv2.DFT_SCALE
: 縮放變換的結果,使其適應圖像顯示。cv2.DFT_INVERSE
: 執行逆傅里葉變換,將頻域信號轉換回空域。nonzeroRows
: 用于優化計算的參數,通常可以設置為輸入圖像的行數。
功能:
- 執行離散傅里葉變換(DFT): 將輸入圖像從空域轉換到頻域,得到包含頻率分量的復數數組。
- 可選的縮放: 通過設置
cv2.DFT_SCALE
標志,可以對變換結果進行縮放,以適應圖像顯示。- 逆變換: 如果設置了
cv2.DFT_INVERSE
標志,則執行逆傅里葉變換,將頻域信號轉換回空域。
1.2 傅里葉變換進行卷積
1.2.1 傅里葉變換卷積原理
傅里葉變換在圖像處理中的卷積操作是一種強大而高效的技術。卷積是一種將兩個函數產生第三個函數的數學運算,而傅里葉變換能夠在頻域中簡化卷積運算,提高計算效率。在圖像處理中,這意味著通過傅里葉變換,我們可以用更快的方式對圖像進行濾波和特征提取。
1.2.2 傅里葉變換卷積公式
傅里葉變換的卷積定理表述為:
g ( x , y ) = f ( x , y ) ? h ( x , y ) → 傅里葉頻域 G ( u , v ) = F ( u , v ) ? H ( u , v ) g(x, y) = f(x, y) * h(x, y) \ \xrightarrow{\mathcal{傅里葉頻域}} \ G(u, v) = F(u, v) \cdot H(u, v) g(x,y)=f(x,y)?h(x,y)?傅里葉頻域??G(u,v)=F(u,v)?H(u,v)
其中, g ( x , y ) g(x, y) g(x,y) 是圖像 f ( x , y ) f(x, y) f(x,y) 和濾波器 h ( x , y ) h(x, y) h(x,y) 的卷積結果, G ( u , v ) G(u, v) G(u,v) 是它們在頻域中的對應。符號 ? \cdot ? 表示點乘。
1.2.3 代碼實現
在OpenCV中,可以通過以下簡單的代碼演示傅里葉變換進行卷積的過程:
import cv2
import numpy as np# 讀取圖像
img = cv2.imread('tulips.jpg', 0)# 創建簡單的均值濾波器
kernel = np.ones((5, 5), np.float32) / 25# 在空間域執行卷積
conv_img = cv2.filter2D(img, -1, kernel)# 創建更大的數組 tempA 和 tempB
x_img, y_img = img.shape
x_kel, y_kel = kernel.shapetempA = np.zeros((x_img + x_kel - 1, y_img + y_kel - 1))
tempB = np.zeros((x_img + x_kel - 1, y_img + y_kel - 1))# 將圖像復制到 tempA 的中心位置
tempA[int((x_kel - 1) / 2):int(x_img + (x_kel - 1) / 2),
int((y_kel - 1) / 2):int(y_img + (y_kel - 1) / 2)] = img# 將卷積核復制到 tempB 的中心位置
tempB[int(tempB.shape[0] / 2 - (x_kel - 1) / 2):int(tempB.shape[0] / 2 + (x_kel - 1) / 2 + 1),
int(tempB.shape[1] / 2 - (y_kel - 1) / 2):int(tempB.shape[1] / 2 + (y_kel - 1) / 2 + 1)] = kernel# 在頻率域執行卷積
dft_A = cv2.dft(tempA.astype(np.float32), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_B = cv2.dft(tempB.astype(np.float32), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_c = cv2.mulSpectrums(dft_A, dft_B, 0)img_filtered = cv2.idft(dft_c)
img_filtered = np.fft.ifftshift(img_filtered)
img_filtered = cv2.magnitude(img_filtered[:, :, 0], img_filtered[:, :, 1]) / tempA.sizeimg_filtered = cv2.normalize(img_filtered, None, 0, 255, cv2.NORM_MINMAX)
img_filtered = np.array(img_filtered, dtype="uint8")# 裁剪 img_filtered 以匹配原始圖像的大小
img_filtered = img_filtered[int((x_kel - 1) / 2):int(x_img + (x_kel - 1) / 2),int((y_kel - 1) / 2):int(y_img + (y_kel - 1) / 2)]# 共享的參數
shared_params = {"org": (10, 30),"fontFace": cv2.FONT_HERSHEY_SIMPLEX,"fontScale": 1,"thickness": 2,"color": 255,"lineType": cv2.LINE_AA,
}
# 顯示結果
cv2.putText(img, "Original Image", **shared_params)
cv2.putText(conv_img, "Filtered Image", **shared_params)
cv2.putText(img_filtered, "Fourier Transform", **shared_params)cv2.imshow('Convolution', cv2.hconcat([img, conv_img, img_filtered]))
cv2.waitKey(0)
cv2.destroyAllWindows()
1.2.4 cv2.mulSpectrums 函數解析
cv2.mulSpectrums
是OpenCV中用于執行兩個傅里葉頻譜的逐元素相乘的函數。以下是對該函數的參數和功能的簡要說明:
參數:
a
: 第一個輸入數組,是一個傅里葉變換的頻譜(復數數組)。b
: 第二個輸入數組,與第一個數組的大小和類型相同,同樣是一個傅里葉變換的頻譜(復數數組)。flags
: 操作標志,目前支持的唯一標志是cv2.DFT_ROWS
,用于指示每行都是獨立的1D傅里葉頻譜。如果不使用該標志,可以將其設為0
。c
: 輸出數組,用于存儲兩個輸入數組逐元素相乘的結果。如果未提供,函數會創建一個具有相同類型和大小的數組。conjB
: 可選標志,用于指示是否在相乘之前對第二個輸入數組進行共軛。如果設為True
,則進行共軛。
功能:
- 逐元素相乘: 對兩個傅里葉頻譜進行逐元素相乘,即將它們的實部和虛部分別相乘。
- 可選的行操作: 如果設置了
cv2.DFT_ROWS
標志,將每一行視為獨立的1D傅里葉頻譜進行相乘。 - 可選的共軛操作: 如果設置了
conjB
為True
,將對第二個輸入數組進行共軛操作。
使用示例:
import cv2
import numpy as np# 生成兩個傅里葉頻譜
a = cv2.dft(np.random.rand(4, 4), flags=cv2.DFT_COMPLEX_OUTPUT)
b = cv2.dft(np.random.rand(4, 4), flags=cv2.DFT_COMPLEX_OUTPUT)# 將頻譜進行逐元素相乘
result = cv2.mulSpectrums(a, b, 0)# 打印結果
print(result)
上述代碼演示了如何使用 cv2.mulSpectrums
對兩個傅里葉頻譜進行逐元素相乘。這種操作在圖像處理中的卷積和相關運算中經常使用,可以高效地實現頻域操作。
1.3 離散余弦變換
1.3.1 離散余弦變換原理
離散余弦變換是一種將信號從時域轉換到頻域的方法,廣泛應用于圖像和音頻壓縮等領域。在DCT中,信號被表示為一組余弦函數的線性組合。與傅里葉變換不同,DCT對于實際應用更為友好,因為它在表示圖像中的能量分布時更加集中。
1.3.2 離散余弦變換公式
DCT的一維變換公式為:
F ( u ) = C ( u ) ∑ x = 0 N ? 1 f ( x ) cos ? [ ( 2 x + 1 ) u π 2 N ] F(u) = C(u) \sum_{x=0}^{N-1} f(x) \cos\left[\frac{(2x + 1)u\pi}{2N}\right] F(u)=C(u)x=0∑N?1?f(x)cos[2N(2x+1)uπ?]
其中, F ( u ) F(u) F(u) 是變換后的頻率分量, f ( x ) f(x) f(x) 是輸入信號, C ( u ) C(u) C(u) 是歸一化系數, N N N 是信號的長度, u u u 是頻率索引。
對于二維圖像,DCT變換公式為:
D C T ( u , v ) = C ( u ) C ( v ) ∑ i = 0 N ? 1 ∑ j = 0 M ? 1 f ( i , j ) cos ? ( ( 2 i + 1 ) u π 2 N ) cos ? ( ( 2 j + 1 ) v π 2 M ) DCT(u, v) = C(u)C(v)\sum_{i=0}^{N-1}\sum_{j=0}^{M-1}f(i, j) \cos\left(\frac{(2i+1)u\pi}{2N}\right)\cos\left(\frac{(2j+1)v\pi}{2M}\right) DCT(u,v)=C(u)C(v)i=0∑N?1?j=0∑M?1?f(i,j)cos(2N(2i+1)uπ?)cos(2M(2j+1)vπ?)
其中, f ( i , j ) f(i, j) f(i,j) 是圖像在位置 ( i , j ) (i, j) (i,j) 處的像素值, D C T ( u , v ) DCT(u, v) DCT(u,v) 是變換后的系數, C ( u ) C(u) C(u) 和 C ( v ) C(v) C(v) 是歸一化系數。
在離散余弦變換(DCT)的公式中, C ( u ) C(u) C(u) 是歸一化系數,其取值范圍是與信號長度 N N N 有關的。一般而言,DCT的歸一化系數
C ( u ) C(u) C(u) 可以通過以下公式計算:C ( u ) = { 2 N , u = 0 2 N cos ? ( ( 2 u + 1 ) π 2 N ) , u > 0 C(u) =\begin{cases} \sqrt{\frac{2}{N}}, &u = 0 \\ \sqrt{\frac{2}{N}} \cos\left(\frac{(2u + 1)\pi}{2N}\right), &u > 0 \end{cases} C(u)=? ? ??N2??,N2??cos(2N(2u+1)π?),?u=0u>0?
其中, u u u 是頻率索引, N N N 是信號的長度。
這意味著當 u u u 等于 0 時,歸一化系數 C ( u ) C(u) C(u) 的取值為 2 N \sqrt{\frac{2}{N}} N2??,而當 u u u 大于 0 時,其取值為 2 N \sqrt{\frac{2}{N}} N2?? 與余弦函數的乘積。
要注意的是,不同的DCT變種可能存在稍微不同的歸一化系數計算方式。在實際應用中,可以根據使用的DCT變種進行相應的歸一化系數計算。
1.3.3 代碼實現
在OpenCV中,可以使用 cv2.dct
函數來進行離散余弦變換。以下是一個簡單的示例代碼:
import cv2
import numpy as np# 讀取圖像
image = cv2.imread('tulips.jpg', 0)# 進行離散余弦變換
dct_result = cv2.dct(image.astype(np.float32))
# 使用 np.clip 將數據限制在一個合理的范圍內,避免出現無效值
dct_result = np.clip(dct_result, 1e-10, None) # 1e-10 是一個很小的正數,可以根據實際情況調整
# 計算幅度譜
log_dct_result = 20 * np.log(dct_result)
log_dct_result = np.clip(log_dct_result, 0, 255)# 顯示頻譜圖像
cv2.imshow('DCT Transform', cv2.hconcat([image, np.uint8(log_dct_result)]))
cv2.waitKey(0)
cv2.destroyAllWindows()
上述代碼演示了如何使用 cv2.dct
對圖像進行離散余弦變換,并通過對數尺度來可視化變換后的結果。通過這一變換,圖像在頻域中的能量分布被更好地集中在低頻部分。
1.3.4 cv2.dct函數解析
cv2.dct
是OpenCV中用于執行離散余弦變換(DCT)的函數。以下是對該函數的參數和功能的簡要說明:
參數:
src
: 輸入浮點數組,可以是一維或二維的。表示需要進行離散余弦變換的原始數據。dst
: 輸出數組,用于存儲變換結果。如果未提供,函數會創建一個具有相同類型和大小的數組。flags
: 變換標志,控制變換的模式和方向。可以通過位運算組合不同的標志。主要的標志有:
cv2.DCT_FORWARD
: 執行正向DCT(默認)。cv2.DCT_INVERSE
: 執行反向DCT,將DCT的結果轉換回原始數據。cv2.DCT_ROWS
: 指示對每一行進行1D DCT變換。
功能:
- 一維或二維DCT: 根據輸入數組的維度,執行一維或二維的離散余弦變換。
- 正向或反向變換: 可以選擇執行正向DCT(默認)或反向DCT,根據設置的
flags
。- 行變換: 如果設置了
cv2.DCT_ROWS
標志,將對每一行執行1D DCT變換。
1.4 傅里葉逆變換
在圖像處理中,傅里葉逆變換是傅里葉變換的逆過程,它允許我們從頻域回到時域,即從傅里葉變換的結果重建原始圖像。
1.4.1 傅里葉逆變換原理
傅里葉逆變換用于將圖像從頻域轉回到時域。在頻域中進行圖像處理后,通過傅里葉逆變換,我們可以得到經過處理后的圖像。傅里葉逆變換的過程實際上是對傅里葉變換結果進行反向變換的過程。
1.4.2 傅里葉逆變換公式
傅里葉逆變換的一維形式為:
x ( n ) = 1 N ∑ k = 0 N ? 1 X ( k ) e j 2 π N k n x(n) = \frac{1}{N} \sum_{k=0}^{N-1} X(k) e^{j\frac{2\pi}{N}kn} x(n)=N1?k=0∑N?1?X(k)ejN2π?kn
對于二維圖像,傅里葉逆變換的公式為:
x ( x , y ) = 1 M N ∑ u = 0 M ? 1 ∑ v = 0 N ? 1 X ( u , v ) e j 2 π M u x e j 2 π N v y x(x, y) = \frac{1}{MN} \sum_{u=0}^{M-1}\sum_{v=0}^{N-1} X(u, v) e^{j\frac{2\pi}{M}ux}e^{j\frac{2\pi}{N}vy} x(x,y)=MN1?u=0∑M?1?v=0∑N?1?X(u,v)ejM2π?uxejN2π?vy
其中, X ( u , v ) X(u, v) X(u,v) 是傅里葉變換的結果。
1.4.3 代碼實現
在OpenCV中,可以使用 cv2.idft
函數進行傅里葉逆變換。以下是一個簡單的例子:
import cv2
import numpy as np# 讀取圖像
img = cv2.imread('tulips.jpg', 0)# 進行傅里葉變換
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)# 將變換后圖像的低頻部分轉移到圖像的中心
dft_shift = np.fft.fftshift(dft)# 定義掩模:生成的掩模中間為1周圍為0
center_y, center_x = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得圖像的中心點位置
mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
mask[center_y - 50:center_y + 50, center_x - 50:center_x + 50] = 1
reversed_mask = 1 - mask# 將掩模與傅里葉變化后圖像相乘,保留中間部分
mask_img = dft_shift * mask
# 將掩模與傅里葉變化后圖像相乘,保留中間部分
reversed_mask_img = dft_shift * reversed_mask# 顯示頻譜圖像
magnitude_spectrum = cv2.magnitude(mask_img[:, :, 0], mask_img[:, :, 1])
magnitude_spectrum = np.log(magnitude_spectrum + 1) # 對數變換增強顯示
# 將結果標準化到0~255
magnitude_spectrum_normalized = cv2.normalize(magnitude_spectrum, None, 0, 255, cv2.NORM_MINMAX)
# 進行逆傅里葉變換
idft = cv2.idft(np.fft.ifftshift(mask_img))
idft = cv2.magnitude(idft[:, :, 0], idft[:, :, 1])
# 將結果標準化到0~255
idft_normalized = cv2.normalize(idft, None, 0, 255, cv2.NORM_MINMAX)# 顯示頻譜圖像
reversed_magnitude_spectrum = cv2.magnitude(reversed_mask_img[:, :, 0], reversed_mask_img[:, :, 1])
reversed_magnitude_spectrum = np.log(reversed_magnitude_spectrum + 1) # 對數變換增強顯示
# 將結果標準化到0~255
reversed_magnitude_spectrum_normalized = cv2.normalize(reversed_magnitude_spectrum, None, 0, 255, cv2.NORM_MINMAX)
# 進行逆傅里葉變換
reversed_idft = cv2.idft(np.fft.ifftshift(reversed_mask_img))
reversed_idft = cv2.magnitude(reversed_idft[:, :, 0], reversed_idft[:, :, 1])# 將結果標準化到0~255
reversed_idft_normalized = cv2.normalize(reversed_idft, None, 0, 255, cv2.NORM_MINMAX)# 顯示原始圖像和標準化后的逆傅里葉變換結果
cv2.imshow('Inverse Fourier Transform',cv2.vconcat([cv2.hconcat([mask[:, :, 0] * 255, np.uint8(magnitude_spectrum_normalized), np.uint8(idft_normalized)]),cv2.hconcat([reversed_mask[:, :, 0] * 255, np.uint8(reversed_magnitude_spectrum_normalized),np.uint8(reversed_idft_normalized)])]))
cv2.waitKey(0)
cv2.destroyAllWindows()
這段代碼主要執行了以下操作:
- 讀取名為 ‘tulips.jpg’ 的圖像,并將其轉換為灰度圖像。
- 對圖像進行傅里葉變換,將時域信號轉換為頻域信號。這涉及到使用
cv2.dft
函數來計算傅里葉變換,并通過np.fft.fftshift
將頻譜中的低頻部分移到中心。- 定義兩個掩模(mask):
mask
: 中間部分為1,周圍為0,用于保留圖像中心的頻率信息。reversed_mask
: 與mask
相反,中間部分為0,周圍為1,用于保留圖像邊緣的頻率信息。- 將定義的掩模與傅里葉變換后的圖像相乘,以保留或排除中間頻率部分。
- 計算兩個不同掩模條件下的頻譜圖像,并對其進行對數變換,以增強顯示。
- 對通過掩模保留的頻域信號進行逆傅里葉變換,將頻域信號轉換回時域。
- 將結果標準化到0~255,以便在圖像中正確顯示。
在展示的圖像中,上半部分顯示了通過中心掩模保留的頻率信息,下半部分顯示了通過反向掩模排除的頻率信息。這種操作可以用于圖像的頻域分析和濾波。在實際應用中,傅里葉逆變換常用于圖像重建和修復等任務。
二、積分圖像
2.1 積分圖像原理
積分圖像是一種高效的數據結構,用于快速計算圖像區域的像素和,特別是在進行圖像分析和處理時。
標準求和積分
標準求和積分圖像是最基礎的形式,它計算原始圖像中每個位置及其左上方所有像素的累積和。具體來說,對于圖像中的每個像素位置 (x, y)
,積分圖像 I(x, y)
表示的是原始圖像 O(x', y')
在區域 (0, 0)
到 (x, y)
之間的所有像素和。
計算公式:
I ( x , y ) = ∑ x ′ < x , y ′ < y O ( x ′ , y ′ ) I(x, y) = \sum_{x' < x, y' < y} O(x', y') I(x,y)=x′<x,y′<y∑?O(x′,y′)
平方和積分
平方和積分圖像不僅計算像素的累積和,而且還計算每個像素值的平方的累積和。這對于計算圖像的局部方差和標準差特別有用。
計算公式:
I s q ( x , y ) = ∑ x ′ < x , y ′ < y O ( x ′ , y ′ ) 2 I_{sq}(x, y) = \sum_{x' < x, y' < y} O(x', y')^2 Isq?(x,y)=x′<x,y′<y∑?O(x′,y′)2
傾斜求和積分
傾斜求和積分圖像計算的是圖像中沿著某一角度(通常是45度)的傾斜區域的像素和。這種類型的積分圖像在處理如斜線特征檢測或傾斜矩形區域的和時特別有用。它的核心思想是沿著傾斜方向累積像素值,從而能夠快速計算任意傾斜矩形區域內的像素和。
傾斜求和積分的計算公式稍微復雜一些,涉及到對圖像的斜向遍歷。對于圖像中的每個像素 (x, y)
,傾斜積分圖像 I_t(x, y)
表示的是原始圖像 O(x', y')
在由 (x, y)
點沿著特定傾斜角(如45度)形成的三角形區域內所有像素的和。
計算公式大致可以表示為:
I t ( x , y ) = ∑ x ′ + y ′ < x + y O ( x ′ , y ′ ) I_t(x, y) = \sum_{x' + y' < x + y} O(x', y') It?(x,y)=x′+y′<x+y∑?O(x′,y′)
這個公式意味著對于圖像中的每個點 (x, y)
,我們計算從該點沿著傾斜方向到圖像左上角的所有像素值的累積和。在實際的編程實現中,這通常需要考慮邊界條件和有效的累積方式,以確保計算的準確性和效率。
由于具體的算法實現可能較為復雜,涉及到圖像處理和數組操作的高級技巧,這里不進行詳細的代碼展示。不過,傾斜積分圖像的概念和基本原理是理解其應用的關鍵。
2.2 代碼實現
在OpenCV中,可以使用 cv2.integral3
函數來計算圖像的積分圖像。以下是一個簡單的示例代碼:
import cv2
import numpy as np# 讀取灰度圖像
image = cv2.imread('tulips.jpg', 0)
# 獲取圖像的高度和寬度
height, width = image.shape# 創建一個新的圖像,高度和寬度各增加一
new_height = height + 1
new_width = width + 1
new_image = np.zeros((new_height, new_width), dtype=np.uint8)
# 將原始圖像復制到新圖像中
new_image[:height, :width] = image# 計算積分圖像
# 調用integral3計算積分圖
sum_integral, sqsum_integral, tilted_integral = cv2.integral3(image)def process_integral(img_integral):# 將積分圖像進行歸一化,以便在圖像顯示時保持合適的范圍normalized_img = cv2.normalize(img_integral, None, 0, 255, cv2.NORM_MINMAX)return normalized_imglog_sum_integral = process_integral(sum_integral)
log_sqsum_integral = process_integral(sqsum_integral)
log_tilted_integral = process_integral(tilted_integral)
# 顯示原始圖像和積分圖像
cv2.imshow('Integral Image', cv2.vconcat([cv2.hconcat([new_image, np.uint8(log_sum_integral)]),cv2.hconcat([np.uint8(log_sqsum_integral), np.uint8(log_tilted_integral)])]))
cv2.waitKey(0)
cv2.destroyAllWindows()
integral
, integral2
, integral3
都是 OpenCV 庫中用于計算圖像的積分圖的函數,它們的功能各有不同:
integral(src[, sum[, sdepth]])
: 這個函數計算單一的積分圖像。它接受原始圖像src
作為輸入,并返回積分圖像sum
。積分圖像中的每個元素是原始圖像中對應位置左上角所有像素的累積和。此函數主要用于快速計算圖像區域內的像素和。
integral2(src[, sum[, sqsum[, sdepth[, sqdepth]]]])
: 這個函數除了計算標準的積分圖sum
外,還計算了平方和積分圖sqsum
。平方和積分圖用于存儲原始圖像中每個像素值的平方的累積和,這在計算圖像的局部方差和標準差時特別有用。
integral3(src[, sum[, sqsum[, tilted[, sdepth[, sqdepth]]]]])
: 這個函數是最全面的,它計算標準積分圖sum
、平方和積分圖sqsum
,以及傾斜積分圖tilted
。傾斜積分圖像是一種特殊類型的積分圖像,它考慮了原始圖像沿45度角旋轉的像素累積和,這對于某些類型的特征檢測特別有用。
總結
本文為讀者提供了深入淺出的視角,探索了圖像分析的核心技術。
- 首先,通過對離散傅里葉變換的原理、公式和代碼實現的詳細講解,使讀者能夠理解如何將圖像從空間域轉換到頻率域。特別是對 cv2.dft函數的解析,增強了對傅里葉變換在實際應用中的理解。
- 接著,文中通過討論傅里葉變換在卷積操作中的應用,及其如何通過cv2.mulSpectrums 函數實現,進一步展示了傅里葉變換在圖像處理中的實用性。
- 此外,離散余弦變換的介紹和 cv2.dct 函數的分析為讀者提供了另一種重要的頻域分析工具。
- 最后,傅里葉逆變換的部分使讀者能夠從頻率域恢復到空間域,理解整個變換過程的完整性。
- 在積分圖像部分,文章詳細討論了積分圖像的原理和代碼實現。