OpenCV快速入門:圖像分析——傅里葉變換、積分圖像

文章目錄

  • 前言
  • 一、傅里葉變換
    • 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=0M?1?y=0N?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 是通過對傅里葉變換的結果進行處理而得到的圖像,表示了圖像在頻域中的幅度信息。
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()

Convolution

1.2.4 cv2.mulSpectrums 函數解析

cv2.mulSpectrums 是OpenCV中用于執行兩個傅里葉頻譜的逐元素相乘的函數。以下是對該函數的參數和功能的簡要說明:
參數:

  • a: 第一個輸入數組,是一個傅里葉變換的頻譜(復數數組)。
  • b: 第二個輸入數組,與第一個數組的大小和類型相同,同樣是一個傅里葉變換的頻譜(復數數組)。
  • flags: 操作標志,目前支持的唯一標志是 cv2.DFT_ROWS,用于指示每行都是獨立的1D傅里葉頻譜。如果不使用該標志,可以將其設為 0
  • c: 輸出數組,用于存儲兩個輸入數組逐元素相乘的結果。如果未提供,函數會創建一個具有相同類型和大小的數組。
  • conjB: 可選標志,用于指示是否在相乘之前對第二個輸入數組進行共軛。如果設為 True,則進行共軛。

功能:

  • 逐元素相乘: 對兩個傅里葉頻譜進行逐元素相乘,即將它們的實部和虛部分別相乘。
  • 可選的行操作: 如果設置了 cv2.DFT_ROWS 標志,將每一行視為獨立的1D傅里葉頻譜進行相乘。
  • 可選的共軛操作: 如果設置了 conjBTrue,將對第二個輸入數組進行共軛操作。

使用示例:

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=0N?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=0N?1?j=0M?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()

DCT Transform
上述代碼演示了如何使用 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=0N?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=0M?1?v=0N?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()

Inverse Fourier Transform
這段代碼主要執行了以下操作:

  1. 讀取名為 ‘tulips.jpg’ 的圖像,并將其轉換為灰度圖像。
  2. 對圖像進行傅里葉變換,將時域信號轉換為頻域信號。這涉及到使用 cv2.dft 函數來計算傅里葉變換,并通過 np.fft.fftshift 將頻譜中的低頻部分移到中心。
  3. 定義兩個掩模(mask):
    • mask: 中間部分為1,周圍為0,用于保留圖像中心的頻率信息。
    • reversed_mask: 與 mask 相反,中間部分為0,周圍為1,用于保留圖像邊緣的頻率信息。
  4. 將定義的掩模與傅里葉變換后的圖像相乘,以保留或排除中間頻率部分。
  5. 計算兩個不同掩模條件下的頻譜圖像,并對其進行對數變換,以增強顯示。
  6. 對通過掩模保留的頻域信號進行逆傅里葉變換,將頻域信號轉換回時域。
  7. 將結果標準化到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 Image

integral, integral2, integral3 都是 OpenCV 庫中用于計算圖像的積分圖的函數,它們的功能各有不同:

  1. integral(src[, sum[, sdepth]]): 這個函數計算單一的積分圖像。它接受原始圖像 src 作為輸入,并返回積分圖像sum。積分圖像中的每個元素是原始圖像中對應位置左上角所有像素的累積和。此函數主要用于快速計算圖像區域內的像素和。

  2. integral2(src[, sum[, sqsum[, sdepth[, sqdepth]]]]): 這個函數除了計算標準的積分圖 sum 外,還計算了平方和積分圖sqsum。平方和積分圖用于存儲原始圖像中每個像素值的平方的累積和,這在計算圖像的局部方差和標準差時特別有用。

  3. integral3(src[, sum[, sqsum[, tilted[, sdepth[, sqdepth]]]]]): 這個函數是最全面的,它計算標準積分圖 sum、平方和積分圖 sqsum,以及傾斜積分圖tilted。傾斜積分圖像是一種特殊類型的積分圖像,它考慮了原始圖像沿45度角旋轉的像素累積和,這對于某些類型的特征檢測特別有用。


總結

本文為讀者提供了深入淺出的視角,探索了圖像分析的核心技術。

  1. 首先,通過對離散傅里葉變換的原理、公式和代碼實現的詳細講解,使讀者能夠理解如何將圖像從空間域轉換到頻率域。特別是對 cv2.dft函數的解析,增強了對傅里葉變換在實際應用中的理解。
  2. 接著,文中通過討論傅里葉變換在卷積操作中的應用,及其如何通過cv2.mulSpectrums 函數實現,進一步展示了傅里葉變換在圖像處理中的實用性。
  3. 此外,離散余弦變換的介紹和 cv2.dct 函數的分析為讀者提供了另一種重要的頻域分析工具。
  4. 最后,傅里葉逆變換的部分使讀者能夠從頻率域恢復到空間域,理解整個變換過程的完整性。
  5. 在積分圖像部分,文章詳細討論了積分圖像的原理和代碼實現。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166557.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166557.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166557.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于深度學習的文本分類

通過構建更復雜的深度學習模型可以提高分類的準確性&#xff0c;即分別基于TextCNN、TextRNN和TextRCNN三種算法實現中文文本分類。 項目地址&#xff1a;zz-zik/NLP-Application-and-Practice: 本項目將《自然語言處理與應用實戰》原書中代碼進行了實現&#xff0c;并在此基礎…

Unity使用DOTween實現分段進度條

文章目錄 需求下載安裝 DOTween實現實現效果 需求 用組件進度條&#xff08;Slider&#xff09;&#xff0c;利用分段加載進行以假亂真的進度效果&#xff0c;比如說2秒鐘到達20%的進度&#xff0c;10秒鐘加載20%到50%進度&#xff0c;1分鐘加載50%到90%的進度&#xff0c;30秒…

2023年金融信創行業研究報告

第一章 行業概況 1.1 定義 金融信創是指在金融行業中應用的信息技術&#xff0c;特別是那些涉及到金融IT基礎設施、基礎軟件、應用軟件和信息安全等方面的技術和產品。這一概念源于更廣泛的“信創 (信息技術應用創新)”&#xff0c;即通過中國國產信息技術替換海外信息技術&a…

77 組合問題

給定兩個整數 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 個數的組合。 class Solution { private: vector<vector<int>> result; // 存放符合條件結果的集合 vector<int> path; // 用來存放符合條件結果 void backtracking(int n, int k , int st…

測試在 Oracle 下直接 rm dbf 數據文件并重啟數據庫

創建一個新的表空間并創建新的用戶&#xff0c;指定新表空間為新用戶的默認表空間 create tablespace zzw datafile /oradata/cesdb/zzw01.dbf size 10m;zzw用戶已經創建過&#xff0c;這里修改其默認表空間 alter user zzw quota unlimited on zzw; alter user zzw default …

ELK企業級日志分析平臺——logstash

部署 新建一臺虛擬機elk4部署logstash [rootelk4 ~]# yum install -y jdk-11.0.15_linux-x64_bin.rpm[rootelk4 ~]# yum install -y logstash-7.6.1.rpm 命令方式 [rootelk4 bin]# /usr/share/logstash/bin/logstash -e input { stdin { } } output { stdout {} } elasticsearc…

使用骨傳導耳機會傷耳朵嗎?一文讀懂骨傳導耳機有哪些優點

首先說明&#xff0c;如果是正確的使用骨傳導耳機是不會傷耳朵。 一、骨傳導耳機的傳聲原理是什么&#xff1f; 聲音的傳播需要介質&#xff0c;傳統的耳機是通過空氣來進行傳播&#xff0c;也被稱為“空氣傳導耳機”&#xff0c;而骨傳導耳機最大的特別之處就在于&#xff0…

AcWing 3384:二叉樹遍歷(依先序序列建樹,輸出中序序列) ← DFS

【題目來源】https://www.acwing.com/problem/content/3387/【題目描述】 編寫一個程序&#xff0c;讀入用戶輸入的一串先序遍歷字符串&#xff0c;根據此字符串建立一個二叉樹&#xff08;以指針方式存儲&#xff09;。 例如如下的先序遍歷字符串&#xff1a;abc##de#g##f###&…

錄像機IP地址設置教程:輕松掌握網絡連接方法

隨著科技的發展&#xff0c;現在的錄像機都具備了網絡連接的功能&#xff0c;可以通過設置IP地址實現遠程和監控。但是很多人對于錄像機IP地址的設置方法感到困惑。虎觀代理小二二將在本文詳細介紹錄像機IP地址的設置步驟&#xff0c;幫助您輕松掌握網絡連接方法。 首先&#x…

DFS序和歐拉序的降維打擊

1. DFS 序和時間戳 1.1 DFS 序 定義&#xff1a;樹的每一個節點在深度優先遍歷中進、出棧的時間序列。 如下樹的 dfs 序就是[1,2,8,8,5,5,2,4,3,9,9,3,6,6,4,7,7,1]。 下圖為生成DFS的過程。對于一棵樹進行DFS序&#xff0c;除了進入當前節點時對此節點進行記錄&#xff0c;…

多線程Thread(初階二:Thread類及常??法)

目錄 一、Thread 的常?構造?法 繼承Thread代碼&#xff1a; 實現Runnable接口代碼: 二、Thread 的?個常?屬性 1、id&#xff1a; 2、獲取線程的名字。 3、進程的狀態&#xff1a; 4、在java中設置的優先級&#xff0c; 5、是否后臺線程&#xff0c; 6、是否存活&a…

ubuntu22.04 arrch64版在線安裝node

腳本 #安裝node#下載node、npm國內鏡像&#xff08;推薦&#xff09;# 判斷是否安裝了nodeif type -p node; thenecho "node has been installed."elsemkdir -p /home/zenglg cd /home/zenglgwget https://registry.npmmirror.com/-/binary/node/v10.14.1/node-v10.…

Linux系統編程 day04 文件和目錄操作

Linux系統編程 day04 文件和目錄操作 1. 文件IO1.1 open 函數1.2 close函數1.3 read函數1.4 write函數1.5 lseek函數1.6 errno變量1.7 文件示例1 讀寫文件1.8 文件示例2 文件大小的計算1.9 文件示例3 擴展文件大小1.10 文件示例4 perror函數的使用1.11 阻塞與非阻塞的測試 2. 文…

關于「光學神經網絡」的一切:理論、應用與發展

/目錄/ 一、線性運算的光學實現 1.1. 光學矩陣乘法器 1.2. 光的衍射實現線性運行 1.3. 基于Rayleigh-Sommerfeld方程的實現方法 1.4. 基于傅立葉變換的實現 1.5. 通過光干涉實現線性操作 1.6. 光的散射實現線性運行 1.7. 波分復用&#xff08;WDM&#xff09;實現線性運…

Educoder中MATLAB數值計算與符號計算

第1關&#xff1a;數據處理 a[20 5 7 19 23 14 25 67 23 12]; %%%%%%%%% Begin %%%%%%%% smaxmax(a); sminmin(a); smeanmean(a); smedianmedian(a); ssumsum(a); %%%%%%%%% End %%%%%%%%% m[smax;smin;smean;smedian;ssum]; disp(m); 第2關&#xff1a;多項式計算與數值微積…

脈沖幅度調制信號的功率譜計算

本篇文章是博主在通信等領域學習時&#xff0c;用于個人學習、研究或者欣賞使用&#xff0c;并基于博主對人工智能等領域的一些理解而記錄的學習摘錄和筆記&#xff0c;若有不當和侵權之處&#xff0c;指出后將會立即改正&#xff0c;還望諒解。文章分類在通信領域筆記&#xf…

風口下的危與機:如何抓住生成式AI黃金發展期?

回顧AI的發展歷程&#xff0c;我們見證過幾次重大突破&#xff0c;比如2012年ImageNet大賽的圖像識別&#xff0c;2016年AlphaGo與李世石的圍棋對決&#xff0c;這些進展都為AI的普及應用鋪設了道路。而ChatGPT的出現&#xff0c;真正讓AI作為一個通用的產品&#xff0c;走入大…

Linux | 創建 | 刪除 | 查看 | 基本命名詳解

Linux | 創建 | 刪除 | 查看 | 基本命名詳解 文章目錄 Linux | 創建 | 刪除 | 查看 | 基本命名詳解前言一、安裝Linux1.1 方法一&#xff1a;云服務器方式1.2 方法二&#xff1a;虛擬機方式 二、ls2.2 ll 三、which3.1 ls -ld 四、pwd五、cd5.1 cd .\.5.2 ls -al5.3 重新認識命…

程序員兼職需要收藏的防坑技巧

不管你是剛剛上車的新職員&#xff0c;還是職場經營多年的老手&#xff0c;在零散時間&#xff0c;通過兼職搞一點零花錢&#xff0c;充實一下自己的生活&#xff0c;這是在正常不過的事情&#xff0c;但是很多同學害怕兼職有風險&#xff0c;被騙或者說找不到門路&#xff0c;…

優思學院|質量工程師在汽車行業待遇好嗎?

優思學院認為質量工程師在汽車行業的待遇有可能相對較好的。隨著中國汽車品牌在國內市場的崛起&#xff0c;特別是在電動汽車領域的增長&#xff0c;質量工程師在保障產品質量和安全性方面變得非常重要。由于中國汽車制造商對產品質量的高度重視&#xff0c;質量工程師在制定和…