一.周期函式
周期函式可以進行傅里葉展開:
f
(
x
)
=
a
0
+
∑
(
a
n
sin
?
(
2
π
n
x
)
+
b
n
cos
?
(
2
π
n
x
)
)
f(x) = a_0 + \sum(a_n\sin(2\pi nx) + b_n\cos(2\pi nx))
f(x)=a0?+∑(an?sin(2πnx)+bn?cos(2πnx))
"""
1.周期函式
"""
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend("TkAgg")
x = np.linspace(0, 2 * np.pi, 10000)
y = np.sin(x * 2) + np.sin(100 * x) * 0.3
plt.plot(x, y)
plt.show()

圖中函式包含有高頻資訊和低頻資訊, 整個大的周期曲線稱為低頻, 小的周期曲線稱為高頻
二.傅里葉變換
2.1 連續資料傅里葉變換
傅?葉變換假設被變換的函式(或稱為信號) x(t)是連續的,并且是非周期的,此時定義?個變換:
X
(
ω
)
=
F
(
x
(
t
)
)
=
∫
?
∞
+
∞
x
(
t
)
e
?
i
ω
t
d
t
X(\omega) = F(x(t)) = \int_{-\infty}^{+\infty}x(t)e^{-i \omega t}dt
X(ω)=F(x(t))=∫?∞+∞?x(t)e?iωtdt
此
時
稱
X
(
ω
)
為
頻
譜
,
此
公
式
將
函
數
x
(
t
)
由
時
間
域
(
時
間
t
為
?
變
量
)
變
換
到
了
頻
率
域
(
以
ω
為
?
變
量
)
此時稱X(\omega) 為頻譜,此公式將函式x(t) 由時間域(時間t為?變數)變換到了頻率域(以\omega為?變數)
此時稱X(ω)為頻譜,此公式將函數x(t)由時間域(時間t為?變量)變換到了頻率域(以ω為?變量)
2.1.1 下面看下對函式 f(x) = sin(2x) + 0.3sin(100x)+ 0.6sin(200x)進行傅里葉變換:
原始影像:
"""
原始函式影像
"""
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend("TkAgg")
x = np.linspace(0, 2 * np.pi, 10000)
y = np.sin(x * 2) + np.sin(100 * x) * 0.3 + np.sin(200 * x) * 0.6
plt.plot(x, y)
plt.show()

此函式包含一個低頻,一個次高頻,一個高頻信號
進行傅里葉變換:
"""
傅里葉變換
"""
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend("TkAgg")
x = np.linspace(0, 2 * np.pi, 10000)
y = np.sin(x * 2) + np.sin(100 * x) * 0.3 + np.sin(200 * x) * 0.6
# 進行傅里葉變換(此時f為頻譜)
f = np.fft.fft(y)
# 傅里葉變換后此時f為復數域域,將之變成實數域
plt.plot(np.abs(f))
plt.show()

放大一下:

我們會發現,在2,100,200的值上,分別得出了低頻,次高頻,高頻的最大值
2.2.連續資料傅里葉反變換與濾波
也可以通過反變換將頻率域的函式反變換為時間域:
x
(
t
)
=
F
?
1
(
X
(
ω
)
)
=
1
2
π
∫
?
∞
+
∞
X
(
ω
)
e
i
ω
t
d
ω
x(t)=F^{-1}(X(\omega)) = \frac{1}{2\pi} \int_{-\infty}^{+\infty}X(\omega)e^{i \omega t}d\omega
x(t)=F?1(X(ω))=2π1?∫?∞+∞?X(ω)eiωtdω
二中的函式存在低頻、次高頻和高頻信號, 如果我們想去掉高頻信號, 或者次高頻或高頻信號的話,可以利用傅里葉反變換
2.2.1 過濾低頻信號
"""
傅里葉反變換
"""
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend("TkAgg")
x = np.linspace(0, 2 * np.pi, 10000)
y = np.sin(x * 2) + np.sin(100 * x) * 0.3 + np.sin(200 * x) * 0.6
# 進行傅里葉變換(此時f為頻譜)
f = np.fft.fft(y)
# 將低頻資訊附近的值設為0(3與-3是根據二中頻譜影像得出)
f[:3] = 0
f[-3:] = 0
# 進行傅里葉的反變換
y = np.fft.ifft(f)
# 取實數域部分
y = np.real(y)
plt.plot(x, y)
plt.show()

可以看到, 此時低頻信號已經被過濾掉了. 這里叫做高通濾波, 相當于傅里葉展開,只保留高階系數
2.2.2 過濾高頻信號
"""
傅里葉反變換
"""
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend("TkAgg")
x = np.linspace(0, 2 * np.pi, 10000)
y = np.sin(x * 2) + np.sin(100 * x) * 0.3 + np.sin(200 * x) * 0.6
# 進行傅里葉變換(此時f為頻譜)
f = np.fft.fft(y)
# 將低頻資訊附近的值設為0(3與-3是根據二中頻譜影像得出)
f[4:250] = 0
f[-250:-4] = 0
# 進行傅里葉的反變換
y = np.fft.ifft(f)
# 取實數域部分
y = np.real(y)
plt.plot(x, y)
plt.show()

此時高頻與次高頻的信號被過濾了, 只剩下低頻信號,叫做低通濾波. 相當于傅里葉展開,只保留低階系數
2.3.離散資料傅里葉反變換與濾波器
在?程實踐中絕?部分使?的均是離散傅?葉變換,即現在計算機處理中所謂的傅?葉變換信號和頻譜都是周期性的,均是離散的,
1.連續傅?葉變換信號和頻譜都是非周期性的;
2.周期信號的頻譜是離散的;
3.離散信號的頻譜是周期性的;
4.離散傅?葉變換(Discrete Fourier Transform,DFT)的信號和頻譜都是周期性的;
離散傅?葉變換計算公式:
X
(
k
)
=
∑
n
=
0
N
?
1
x
(
n
)
e
?
i
2
π
n
N
k
X(k) = \sum_{n=0}^{N-1}x(n)e^{-i\frac{2\pi n}{N}k}
X(k)=n=0∑N?1?x(n)e?iN2πn?k
反變換公式:
x
(
k
)
=
1
N
∑
n
=
0
N
?
1
X
(
n
)
e
i
2
π
n
N
k
x(k) = \frac{1}{N} \sum_{n=0}^{N-1}X(n)e^{i\frac{2\pi n}{N}k}
x(k)=N1?n=0∑N?1?X(n)eiN2πn?k
二.傅里葉變換與卷積
傅?葉變換的另外?個作?就是濾波
假
設
兩
個
信
號
x
1
(
t
)
,
x
2
(
t
)
以
及
其
傅
?
葉
頻
譜
X
1
(
ω
)
,
X
2
(
ω
)
假設兩個信號x_1(t),x_2(t) 以及其傅?葉頻譜X_1(\omega),X_2(\omega)
假設兩個信號x1?(t),x2?(t)以及其傅?葉頻譜X1?(ω),X2?(ω)
兩
個
頻
譜
進
行
相
乘
:
X
3
=
X
1
(
ω
)
X
2
(
ω
)
兩個頻譜進行相乘:X_3=X_1(\omega)X_2(\omega)
兩個頻譜進行相乘:X3?=X1?(ω)X2?(ω)
X
3
為
濾
波
后
的
信
號
,
頻
譜
相
乘
等
于
時
間
閾
上
的
卷
積
(
也
是
折
積
)
X_3為濾波后的信號, 頻譜相乘等于時間閾上的卷積(也是折積)
X3?為濾波后的信號,頻譜相乘等于時間閾上的卷積(也是折積)
等
價
于
:
x
3
(
τ
)
=
x
1
(
t
)
?
x
2
(
t
)
=
=
∫
?
∞
+
∞
x
1
(
τ
)
x
2
(
t
?
τ
)
d
τ
等價于: x_3(\tau)=x_1(t)*x_2(t)== \int_{-\infty}^{+\infty} x_1(\tau)x_2(t-\tau) d \tau
等價于:x3?(τ)=x1?(t)?x2?(t)==∫?∞+∞?x1?(τ)x2?(t?τ)dτ
時
間
域
上
的
卷
積
可
以
代
替
頻
譜
相
乘
方
式
的
濾
波
時間域上的卷積可以代替頻譜相乘方式的濾波
時間域上的卷積可以代替頻譜相乘方式的濾波
時
間
域
卷
積
計
算
即
是
頻
率
域
乘
法
計
算
時間域卷積計算即是頻率域乘法計算
時間域卷積計算即是頻率域乘法計算

進行卷積后得出:
"""
卷積
"""
import matplotlib.pyplot as plt
import numpy as np
plt.switch_backend("TkAgg")
# 設定plt可以寫中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# x1稱為信號, x2稱為濾波器(也稱卷積核心), 卷積也稱為時間域濾波
def conv(x1, x2):
# 根據卷積公式, 將x2翻轉
x2 = x2[::-1]
l1 = len(x1)
l2 = len(x2)
x3 = np.zeros([l1])
for i in range(l1 - l2 + 1):
x3[i] = np.sum(x1[i:i + l2] * x2)
return x3
x1 = np.linspace(-5, 5, 1000)
y1 = np.sin(2 * x1) + 0.2 * np.sin(60 * x1)
# 繪制函式
plt.subplot(121)
plt.plot(x1, y1)
plt.title("濾波前")
# 設定濾波器
g = np.ones([32]) / 32
# 進行卷積計算
y1 = conv(y1, g)
plt.subplot(122)
plt.title("濾波后")
plt.plot(x1, y1)
plt.show()

以上為一維資料處理
三.影像資料處理
影像資料可以看成是二維資料.我們先看一下影像資料是什么樣的:
利用opencv庫進行影像處理.安裝庫:
pip install opencv-python
用我們喜愛的姚明舉下例子 ^ . ^:
import cv2
# 讀取圖片
img = cv2.imread("ym.png")
# 列印影像資訊
print(img.shape, img.dtype)
# 展示圖片
cv2.imshow("img", img)
# 等待輸入字符才會終止程式
cv2.waitKey(0)
列印的圖片資訊和型別:
(574, 766, 3) uint8
其中小括號里的574、766、3分別代表高、寬和顏色的三原色(順序為藍,綠,紅),uint8表示8位的無符號整形, 表示該矩陣中每一個數字都是8位的,
3.1 過濾顏色
import cv2
# 讀取圖片
img = cv2.imread("ym.png")
# 列印影像資訊
print(img.shape, img.dtype)
# 將藍和紅設定為0,只留綠色
img[:, :, 0] *= 0
img[:, :, 2] *= 0
# 展示圖片
cv2.imshow("img", img)
# 等待輸入字符才會終止程式
cv2.waitKey(0)

3.2 影像的卷積

3.2.1 平均模糊
import cv2
import numpy as np
# 濾波器,平均模糊
kernel = np.ones([16, 16]) / (16*16)
img = cv2.imread("ym.png")
# 進行濾波(卷積運算), -1 代表對每一個顏色單獨的進行處理
img = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", img)
cv2.waitKey(0)

3.2.2 邊界濾波
一般影像中可以通過物體的顏色,來區分不同的物體,那么我們在設定濾波器的時候,可以將相同顏色的像素點進行過濾,只保留物體邊緣處顏色不一樣的地方,
提取縱向邊界,可以看到縱向部分更突出了:
import cv2
import numpy as np
# 提取縱向邊界
kernel = np.ones([4, 4])
kernel[:, :2] = -1
"""
[[-1. -1. 1. 1.]
[-1. -1. 1. 1.]
[-1. -1. 1. 1.]
[-1. -1. 1. 1.]]
"""
img = cv2.imread("ym.png")
img = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", img)
cv2.waitKey(0)

提取橫向邊界,可以看到橫向邊界更突出了:
import cv2
import numpy as np
# 提取橫向邊界
kernel = np.ones([4, 4])
kernel[:2, :] = -1
"""
[[-1. -1. -1. -1.]
[-1. -1. -1. -1.]
[ 1. 1. 1. 1.]
[ 1. 1. 1. 1.]]
"""
img = cv2.imread("ym.png")
img = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", img)
cv2.waitKey(0)

3.2.3 更復雜的濾波,例如浮雕濾波
import cv2
import numpy as np
# 浮雕濾波
kernel = np.array([[-2, -1, 0],
[-1, 1, 1],
[0, 1, 2]])
img = cv2.imread("ym.png")
img = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", img)
cv2.waitKey(0)

3.2 視頻處理
我們同樣可以對視頻進行卷積過濾
import cv2
import numpy as np
# 濾波器,平均模糊
kernel = np.ones([16, 16]) / (16*16)
# 讀取攝像的句柄,調去第一個攝像頭
cap = cv2.VideoCapture(0)
# 構建讀取回圈
while True:
ret, img = cap.read()
img = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", img)
# 每隔100ms沒回應則繼續讀取
ret = cv2.waitKey(100)
if ret == 97:
break
cv2.destroyAllWindows()

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/279271.html
標籤:python
