文章目錄
操作平臺: win10,python37, jupyter
(1)導入包
import numpy as np
import scipy as sp
(2)查看版本
sp.__version__
'1.4.1'
1、登月圖片消噪
- scipy 和numpy類似的高端的科學計算庫
- 傅里葉變換:
- 物理世界中,所有東西,無論形態如何都是由基本粒子組成
- 數學世界中,所有公式,數據,無論形態如何,都是由基本的方程組成,正弦波
- 音樂,譜,數據,非常多歌曲------------->基本譜調組成
- 時域-------------->頻域
- 人看到數據樣子----------->真實樣子,基本樣子
- 時域是現象,頻域是本質,將數據由表及裏,來進行分析
- scipy.fftpack模塊用來計算快速傅里葉變換
- 速度比傳統傅里葉變換更快,是對之前算法的改進
- 圖片是二維數據,注意使用fftpack的二維轉變方法
# fft2處理二維數據;ifft2 inverse 反轉
from scipy.fftpack import fft2,ifft2
import matplotlib.pyplot as plt
%matplotlib inline
1.1、導入圖片
cmap = plt.cm.gray
展示時對應的圖片顏色,plt.cm.Blues
,plt.cm.Reds
- 登月不平滑:
- ‘噪聲’------>白色圓環
- 數據不平滑---->不協調----->波動比較大
- 傅里葉變換,時域----->頻域(波動)
- 將波動大的數據過濾掉,保留下的數據自然,平滑
- 傅里葉變化,高等算法,處理數據
moon = plt.imread('./moonlanding.png')
plt.figure(figsize=(12,9))
plt.imshow(moon,cmap = plt.cm.gray)
plt.show()
1.2、查看圖片信息
moon.shape #結果爲(474, 630)
moon
array([[0.04705882, 0. , 0.23921569, ..., 0. , 0.00392157,
0.53333336],
[0. , 0. , 0.6784314 , ..., 0.10196079, 0.2901961 ,
0. ],
[0.72156864, 0.10980392, 0.6039216 , ..., 0. , 0.21568628,
1. ],
...,
[0.00392157, 0. , 1. , ..., 1. , 1. ,
0.95686275],
[0. , 0. , 0.15686275, ..., 0. , 0. ,
0.3529412 ],
[1. , 0.52156866, 0.04705882, ..., 0. , 0. ,
1. ]], dtype=float32)
1.3、進行傅里葉變換
moon_fft = fft2(moon)
moon_fft.shape #結果爲(474, 630),形狀沒有變化
moon_fft
array([[126598.46 -0.j , -4608.579 -1892.4691j ,
-322.0927 -20.277735j, ..., -906.1584 +1539.3083j ,
-322.0927 +20.277735j, -4608.579 +1892.4691j ],
[ -9421.1 +5242.114j , 5224.017 -3171.743j ,
1607.9927 +1269.4243j , ..., -677.345 -936.16174j ,
354.62457-1003.8347j , 1965.366 -2188.0593j ],
[ -2928.3508 +7280.916j , -1116.4069 +1338.3181j ,
-474.20056 +385.40207j , ..., 239.77225 -977.2128j ,
1582.9283 -261.9535j , 2641.927 -292.0936j ],
...,
[ 1850.5717 -2451.1785j , -781.0807 +13.744507j,
377.90704 +12.66983j , ..., -1526.7867 +1271.2621j ,
-2705.5718 -3488.5286j , 1897.4039 -2281.9092j ],
[ -2928.3508 -7280.916j , 2641.927 +292.0936j ,
1582.9283 +261.9535j , ..., -2208.43 +81.80743j ,
-474.20056 -385.40207j , -1116.4069 -1338.3181j ],
[ -9421.1 -5242.114j , 1965.366 +2188.0593j ,
354.62457+1003.8347j , ..., 1190.5853 -1431.9934j ,
1607.9927 -1269.4243j , 5224.017 +3171.743j ]],
dtype=complex64)
1.4、計算平均值並過濾大的值
(1)計算所有數據波動頻率平均值
np.abs(moon_fft).mean()
51.193375
(2)大於10倍平均值波動,波動比較大,過濾掉
cond = np.abs(moon_fft) > 500
cond
array([[ True, True, False, ..., True, False, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[ True, True, False, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True]])
(3)過濾重新賦值,超過500的變成常量0
moon_fft[cond] = 0
1.5、反轉變換
(1)將頻域變爲時域
# 將頻域--------->時域(肉眼可見的圖片)
moon_result = ifft2(moon_fft)
moon_result
array([[-0.21588416-2.06498307e-09j, 0.08547959-2.22494068e-09j,
-0.1734157 -6.48814069e-09j, ..., 0.00313994+2.01924011e-09j,
-0.12628847+1.93838989e-09j, -0.12006476-1.46896051e-09j],
...,
[-0.06233133-9.71054970e-09j, 0.06238186-7.02620895e-09j,
-0.05904225-1.34424294e-09j, ..., -0.05108551-1.63348766e-08j,
-0.01733965+1.31372992e-08j, -0.04830755+2.72279710e-09j]],
dtype=complex64)
(2)去掉虛數
moon2 = np.real(moon_result)
moon2
array([[-0.21588416, 0.08547959, -0.1734157 , ..., 0.00313994,
-0.12628847, -0.12006476],
[-0.07464704, 0.02630263, -0.05795978, ..., -0.10645279,
-0.10607976, -0.06213437],
...,
[-0.02365951, -0.21761245, -0.04112263, ..., -0.03240316,
-0.03881304, 0.18942524],
[-0.06233133, 0.06238186, -0.05904225, ..., -0.05108551,
-0.01733965, -0.04830755]], dtype=float32)
1.6、顯示該圖片
plt.figure(figsize=(12,9))
plt.imshow(moon2, cmap = plt.cm.gray)
1.7、把圖片變白
(1)絕對值
moon3 = np.abs(moon2)
moon3
array([[0.21588416, 0.08547959, 0.1734157 , ..., 0.00313994, 0.12628847,
0.12006476],
[0.07464704, 0.02630263, 0.05795978, ..., 0.10645279, 0.10607976,
0.06213437],
[0.01300091, 0.04392406, 0.03069698, ..., 0.09355523, 0.09281518,
0.0542772 ],
...,
[0.00554967, 0.06839291, 0.11348298, ..., 0.05521009, 0.02254211,
0.17004329],
[0.02365951, 0.21761245, 0.04112263, ..., 0.03240316, 0.03881304,
0.18942524],
[0.06233133, 0.06238186, 0.05904225, ..., 0.05108551, 0.01733965,
0.04830755]], dtype=float32)
(2)數值增大
- 數值越大,圖片亮度越高
moon4 = (moon3*255).astype(np.uint8) #數值變大並轉換類型
moon4
array([[55, 21, 44, ..., 0, 32, 30],
[19, 6, 14, ..., 27, 27, 15],
[ 3, 11, 7, ..., 23, 23, 13],
...,
[ 1, 17, 28, ..., 14, 5, 43],
[ 6, 55, 10, ..., 8, 9, 48],
[15, 15, 15, ..., 13, 4, 12]], dtype=uint8)
(3)繪製圖片
plt.figure(figsize=(12,9))
plt.imshow(moon4 + 100,cmap = plt.cm.gray)
2、數值積分,求解圓周率
- 求解圓周率
- integrate 對函數(1 - x2)0.5進行積分
- X2 + Y2 = 1,半徑是1
- pi×r**2,只要求得面積—>pi
2.1、首先畫一個圓
# X**2 + Y**2 = 1
# Y = (1 - X**2)**0.5
c = lambda x : (1-x**2)**0.5
x = np.linspace(-1,1,100)
y = c(x)
plt.figure(figsize=(5,5))
plt.plot(x,y)
plt.plot(x,-y)
2.2、求圓的面積
- 圓的面積等於:
s = pi * r ** 2
- 圓周率等於:
pi = s / (r**2)
- 假設我們不知道圓周率,就可以使用積分的方式求上面個半圓的面積,然後乘以2,得到整個圓的面積。
- 求積分
- 使用scipy.integrate進行積分,調用quad()方法
from scipy import integrate
# 半圓面積,圓周率一半
integrate.quad(c,-1,1)
(1.5707963267948983, 1.0002354500215915e-09) #(結果,誤差)
整個圓的面積:
1.5707963267948983 * 2
3.1415926535897967
當年祖沖之把 pi 精確到 3.1415926,我們的結果完全正確!
3、Scipy文件輸入/輸出
- 隨機生成數組,使用scipy中的io.savemat()保存
- 文件格式是.mat,標準的二進制文件
from scipy import io
3.1、使用io.savemat保存數據
#將上面的moon2寫入moon.mat
io.savemat('moon.mat',mdict = {'moon':moon2})
3.2、使用io.loadmat()讀取數據
io.loadmat('./moon.mat')
{'__header__': b'MATLAB 5.0 MAT-file Platform: nt, Created on: Mon Apr 15 10:45:32 2019',
'__version__': '1.0',
'__globals__': [],
'moon': array([[-0.2158841 , 0.08547963, -0.17341562, ..., 0.00313992,
-0.1262884 , -0.12006474],
[-0.07464715, 0.02630262, -0.05795981, ..., -0.10645279,
-0.10607974, -0.06213436],
[ 0.01300102, -0.04392404, -0.03069701, ..., -0.09355526,
-0.09281505, 0.0542773 ],
...,
[ 0.00554965, -0.06839301, -0.11348293, ..., 0.05521014,
-0.02254207, 0.17004317],
[-0.0236596 , -0.21761242, -0.04112267, ..., -0.03240317,
-0.03881308, 0.18942517],
[-0.06233123, 0.06238206, -0.05904231, ..., -0.05108529,
-0.01733968, -0.04830741]], dtype=float32)}
3.3、讀寫圖片
- 讀寫圖片使用scipy中misc.imread()/imsave()
備註: 我上面用的的版本 1.4.1
出現了錯誤,AttributeError: module 'scipy.misc' has no attribute 'imread'
,於是我就降低了版本爲 1.2.1
,才運行成功的!
- 卸載以前的版本
pip uninstall scipy
- 安裝指定版本
pip install scipy==1.2.1
from scipy import misc
cat = misc.imread('./cat.jpg')
cat
array([[[231, 186, 131],
[232, 187, 132],
[233, 188, 133],
...,
[ 99, 54, 51],
[ 91, 47, 48],
[ 83, 41, 42]],
...,
[188, 98, 64],
[188, 95, 62],
[188, 95, 62]]], dtype=uint8)
(1)展示圖片:
plt.imshow(cat)
(2)旋轉60°
cat2 = misc.imrotate(cat,60) #旋轉60度
plt.imshow(cat2)
(3)大小變換
''' size : int, float or tuple
* int - Percentage of current size.
* float - Fraction of current size.
* tuple - Size of the output image (height, width).'''
cat3 = misc.imresize(cat, 0.1) #10, 50, (100,100)
plt.imshow(cat3)
(4)濾波操作
# 濾波操作
''' ftype : str
The filter that has to be applied. Legal values are:
'blur', 'contour', 'detail', 'edge_enhance', 'edge_enhance_more',
'emboss', 'find_edges', 'smooth', 'smooth_more', 'sharpen'.'''
cat4 = misc.imfilter(cat,'smooth')
plt.imshow(cat4)
3.4、圖片處理
- 使用scipy.misc.face(gray=True)獲取圖片,使用ndimage移動座標、旋轉圖片、切割圖片、縮放圖片
(1)導包,讀取圖片顯示圖片
from scipy import ndimage
# scipy自帶的一張圖片,練習
# 使用任何圖片都可以
face = misc.face()
plt.imshow(face)
(2)shift移動座標
# 0 純黑,255純白
face2 = ndimage.shift(face,shift = [0,-500,0],cval = 255)
plt.imshow(face2)
(3)照鏡子
face2 = ndimage.shift(face,shift = [0,-500,0],mode = 'mirror') # mode = {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}
plt.imshow(face2)
(4)rotate旋轉圖片
face3 = ndimage.rotate(face,angle = 60)
plt.imshow(face3)
(5)zoom縮放圖片
face4 = ndimage.zoom(face,zoom = [0.5,0.5,1/3],mode = 'mirror')
plt.imshow(face4.reshape(384,512),cmap = plt.cm.gray) #1/3爲黑白圖片,必須要降維二維才能顯示
(6)透明度
face4 = ndimage.zoom(face,zoom = [0.5,0.5,4/3],mode = 'mirror')
face4.shape #結果爲(384, 512, 4) #grb+透明
plt.imshow(face4,cmap = plt.cm.gray)
3.5、圖片進行過濾
- 添加噪聲,對噪聲圖片使用ndimage中的高斯濾波、中值濾波、signal中維納濾波進行處理,使圖片變清楚。
(1)高斯濾波sigma:高斯核的標準偏差
# 高斯分佈,正太分佈,概率不一樣
# misc.imfilter(moon,'smooth')
moon5 = ndimage.gaussian_filter(moon,sigma = 3)
plt.figure(figsize=(12,9))
plt.imshow(moon5,cmap = plt.cm.gray)
(2)中值濾波
- 中值濾波參數size:給出在每個元素上從輸入數組中取出的形狀位置,定義過濾器功能的輸入
moon6 = ndimage.median_filter(moon,size=5)
plt.figure(figsize=(12,9))
plt.imshow(moon6,cmap = plt.cm.gray)
4、scipy矩陣
- matrix,scipy將矩陣進行了封裝,對象matrix
- sparse稀鬆矩陣:大部分是0,小部分是非零數據
優點:節省內存
from scipy import matrix
4.1、創建矩陣
(1)舉證A
A = matrix(np.random.randint(0,10,size = (4,5)))
A
matrix([[5, 8, 8, 4, 6],
[3, 7, 5, 9, 5],
[1, 2, 1, 4, 0],
[8, 8, 1, 3, 7]])
(2)矩陣B
B = matrix(np.random.randint(0,10,size= (5,4)))
B
matrix([[3, 6, 5, 5],
[3, 0, 6, 2],
[5, 7, 2, 0],
[4, 8, 4, 0],
[3, 5, 8, 9]])
(3)乘積運算
A.dot(B)
matrix([[113, 148, 153, 95],
[106, 150, 143, 74],
[ 30, 45, 35, 9],
[ 86, 114, 158, 119]])
(4)創建一個10000 * 10000的矩陣
S = np.random.randint(0,100,size = (10000,10000))
S
array([[46, 19, 63, ..., 81, 92, 48],
[90, 35, 48, ..., 37, 23, 90],
[25, 42, 38, ..., 99, 25, 7],
...,
[76, 16, 30, ..., 82, 62, 83],
[39, 98, 94, ..., 61, 1, 6],
[62, 7, 99, ..., 47, 54, 91]])
4.2、保存到本地
(1)保存數據
np.save('./S.npy',S)
文件大小:
(2)填充替換值
S[S < 98] = 0 #用0填充小於98的數據
S
array([[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 0, 0, ..., 99, 0, 0],
...,
[ 0, 0, 0, ..., 0, 0, 0],
[ 0, 98, 0, ..., 0, 0, 0],
[ 0, 0, 99, ..., 0, 0, 0]])
(3)重新保存數據
np.save('S2.npy',S)
文件結果的大小並沒有被改變
(4)文件大小計算
10000 * 10000 * 32 / 8 / 1024 / 1024
381.4697265625
4.3、稀鬆矩陣
(1)轉爲稀鬆矩陣
# 稀鬆矩陣,大部分是0,小部分是非零數據
from scipy import sparse
S1 = sparse.csc_matrix(S)
print (S1)
(44, 0) 99
(51, 0) 99
(102, 0) 99
(156, 0) 99
: :
(9721, 9999) 98
(9801, 9999) 99
(9845, 9999) 99
(9945, 9999) 99
(2)保存數據
sparse.save_npz('./sparse.npz',S1)
- 幾乎把它的大小降了100倍