python scipy庫基礎學習(圖片消噪, 求解圓周率, Scipy文件輸入/輸出, scipy矩陣)

操作平臺: 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倍
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章