欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Scipy之图片降噪

程序员文章站 2022-07-12 22:18:57
...

我们知道,scipy 是基于numpy 的,在这里我们详细探索一下scipy在图片上的应用。scipy.fftpack模块用来计算快速傅里叶变换,其速度比传统傅里叶变换更快,是对之前的算法的改进。我们知道,黑白图片是二维数据,所以在使用时,我们要注意使用fftpack的二维转变方法。

# 登月图片,噪声,白色的圆环,圆环里面和外面图片的背景,圆环就像山峰凸起----圆环处的频率突然变高
# 消除噪声,就将频率高的地方频率降低
import numpy as np

from scipy.fftpack import fft2,ifft2

import matplotlib.pyplot as plt

from PIL import Image
# 第一步:plt读取图片,二维的图片
moon = plt.imread('./moonlanding.png')
display(moon.dtype,moon)
Out[]:
dtype('float32')
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)
#把图片转换成RGB格式的,这样显示出来的信息
#图片是png的,png的颜色代表是从0-1的,要转换成RPG需要乘以255,转换成int8,
np.uint8(moon.reshape(-1)*255)[:100]
Out[]:
array([ 12,   0,  61, 119,   0,   0, 130,  38,   0,  36, 132,   0,   0,
       118,  65,   0,   9, 139,   1,   0, 100,  88,   0,   0, 141,   0,
         0,  79, 108,   0,   0, 137,  21,   0,  54, 124,   0,   0, 128,
        47,   0,  29, 136,   0,   0, 114,  73,   0,   2, 140,   0,   0,
        94,  94,   0,   0, 140,   1,   0,  72, 113,   0,   0, 135,  28,
         0,  47, 128,   0,   0, 124,  54,   0,  19, 135,   0,   0, 106,
        77,   0,   0, 141,   0,   0,  88, 101,   0,   0, 136,   5,   0,
        63, 115,   0,   0, 128,  35,   0,  38, 130], dtype=uint8)
axes = plt.imshow(moon,cmap = 'gray')
fig = axes.get_figure()
fig.set_size_inches(12,9)

读出来的图片是这样的:Scipy之图片降噪
我们可以看到这个图里面有许多的白环,显然我们不想要这些白环(PS:我的妈呀,眼睛都看晕了,密集恐惧症的慎重!)。

#用 fromstring 方法可以从字符串中读取数据并转换为 一维数组,在转换成in8RGB类型的
#.tobytes()用来把图片编码转换成2进制的Unicode
moon2_data = np.fromstring(moon2.tobytes(),np.uint8)
moon2_data[:100]
Out[]:
array([ 12,   0,  61, 119,   0,   0, 130,  38,   0,  36, 132,   0,   0,
       118,  65,   0,   9, 139,   1,   0, 100,  88,   0,   0, 141,   0,
         0,  79, 108,   0,   0, 137,  21,   0,  54, 124,   0,   0, 128,
        47,   0,  29, 136,   0,   0, 114,  73,   0,   2, 140,   0,   0,
        94,  94,   0,   0, 140,   1,   0,  72, 113,   0,   0, 135,  28,
         0,  47, 128,   0,   0, 124,  54,   0,  19, 135,   0,   0, 106,
        77,   0,   0, 141,   0,   0,  88, 101,   0,   0, 136,   5,   0,
        63, 115,   0,   0, 128,  35,   0,  38, 130], dtype=uint8)
# 第二步,进行傅里叶变换
# 使用scipy中快速傅里叶变换对图片进行转换-----频域
moon_fft2 = fft2(moon)
moon_fft2
Out[]:
array([[126598.45      +0.j       ,  -4608.5796 -1892.4688j   ,
          -322.093    -20.27744j  , ...,   -906.1585 +1539.3081j   ,
          -322.093    +20.27744j  ,  -4608.5796 +1892.4688j   ],
       [ -9421.1    +5242.1133j   ,   5224.016  -3171.7434j   ,
          1607.9927 +1269.4243j   , ...,   -677.34503 -936.16174j  ,
           354.6247 -1003.8348j   ,   1965.366  -2188.0593j   ],
       [ -2928.3513 +7280.916j    ,  -1116.4065 +1338.3179j   ,
          -474.20056 +385.40216j  , ...,    239.7723  -977.2129j   ,
          1582.9283  -261.95346j  ,   2641.927   -292.09366j  ],
       ...,
       [  1850.5718 -2451.1787j   ,   -781.0807   +13.744501j ,
           377.90707  +12.6699295j, ...,  -1526.7869 +1271.2621j   ,
         -2705.5718 -3488.529j    ,   1897.404  -2281.9092j   ],
       [ -2928.3513 -7280.916j    ,   2641.927   +292.09366j  ,
          1582.9283  +261.95346j  , ...,  -2208.4302   +81.807434j ,
          -474.20056 -385.40216j  ,  -1116.4065 -1338.3179j   ],
       [ -9421.1    -5242.1133j   ,   1965.366  +2188.0593j   ,
           354.6247 +1003.8348j   , ...,   1190.5856 -1431.9937j   ,
          1607.9927 -1269.4243j   ,   5224.016  +3171.7434j   ]],
      dtype=complex64)
# 第三步,将高频波,滤出
# 比较大的频或者波过滤
# 指定高频波,根据平局值,一般情况比平均值大1到两个数据量级,多试几次
cond = np.abs(moon_fft2) > 1e3+10000
moon_fft2[cond] = 0
# 第四步,将处理之后的数据,进行翻转,变成了图片
# 进行傅里叶翻转
# 进行傅里叶变换
# 傅立叶变换是把时域变为频域
moon_result = ifft2(moon_fft2)
moon_result
# 先求一个绝对值,为什么,因为有白圆环还有黑圆环,谁正谁负并不清楚
cond = np.abs(moon_fft2) > 1e4
moon_fft2[cond] = 0
# 再把频域转变为时域
# ifft2
moon_ifft2 = ifft2(moon_fft2)
moon_ifft2
# 去除复数
result = np.real(moon_result)

plt.figure(figsize=(12,9))
plt.imshow(result,cmap = 'gray')

Scipy之图片降噪
现在我们可以看到,这个图片相较于之前的那张,已经可以看了,而经过很多次的实验,当值取1e4的时候,这个图是最清楚的了,也是博主手动范围内能降噪出来最清楚的一张图了。

相关标签: scipy python