在Python中使用 SciPy 和 NumPy 进行图像处理
在本教程中,我们将使用 NumPy 和 SciPy 等核心科学模块讨论Python中的图像处理。图像由 NumPy ndarray 组成,因此我们可以处理和操作图像,SciPy 提供了子模块 scipy.ndimage,它提供了可以对 NumPy 数组进行操作的函数。
我们将讨论如何打开和写入图像,还将介绍不同的操作和过滤技术。所以在开始之前让我们看看如何安装这两个模块。
安装
Numpy:要安装 numpy,请在终端中键入以下命令。
pip install numpy
SciPy:您也可以使用上述命令安装 SciPy。
pip install scipy
打开和写入图像
SciPy 的 misc 包带有一些预加载的图像。我们将使用这些图像来了解图像处理。 face()函数提供了一张这样的图像。 face()函数将获得浣熊脸的彩色图像。
示例:使用 SciPy 保存图像
Python3
from scipy import misc
import imageio
import matplotlib.pyplot as plt
# reads a raccoon face
face = misc.face()
# save the image
imageio.imsave('raccoon.png', face)
plt.imshow(face)
plt.show()
Python3
from scipy import misc
import imageio
import matplotlib.pyplot as plt
img = imageio.imread('raccoon.png')
print(img.shape)
print(img.dtype)
plt.imshow(img)
plt.show()
Python3
from scipy import misc
import imageio
import matplotlib.pyplot as plt
# reads a raccoon face
face = misc.face()
face.tofile("raccoon.raw")
Python3
import numpy as np
img = np.fromfile('raccoon.raw',
dtype=np.uint8)
print(img.shape)
Python3
from scipy import misc
img = misc.face()
print(img.max())
print(img.min())
print(img.mean())
Python3
from scipy import misc
import matplotlib.pyplot as plt
# for grascaling the image
img = misc.face(gray = True)
x, y = img.shape
# Cropping the image
crop = img[x//3: - x//8, y//3: - y//8]
plt.imshow(crop)
plt.show()
Python3
from scipy import misc
import numpy as np
import matplotlib.pyplot as plt
img = misc.face()
flip = np.flipud(img)
plt.imshow(flip)
plt.show()
Python3
from scipy import misc,ndimage
import matplotlib.pyplot as plt
img = misc.face()
rotate = ndimage.rotate(face, 30)
plt.imshow(rotate)
plt.show()
Python3
from scipy import misc,ndimage
import matplotlib.pyplot as plt
img = misc.face()
blur_G = ndimage.gaussian_filter(img,sigma=7)
plt.imshow(blur_G)
plt.show()
Python3
from scipy import misc, ndimage
import matplotlib.pyplot as plt
img = misc.face(gray=True).astype(float)
blur = ndimage.gaussian_filter(img, 5)
# Showing Blur Image
plt.imshow(blur)
plt.show()
blur_G = ndimage.gaussian_filter(blur, 1)
alpha = 30
sharp = blur+alpha*(blur-blur_G)
# showing sharp images
plt.imshow(sharp)
plt.show()
Python3
from scipy import misc,ndimage
import matplotlib.pyplot as plt
import numpy as np
img=misc.face(gray=True).astype(float)
img=img[40:100,30:100]
noise_img=img+0.9*img.std()*np.random.random(img.shape)
plt.imshow(noise_img)
plt.show()
Python3
denoised = ndimage.gaussian_filter(noise_img, 2.2)
plt.imshow(denoised)
plt.show()
Python3
denoised = ndimage.median_filter(noise_img, 4)
plt.imshow(denoised)
plt.show()
Python3
from scipy import misc, ndimage
import matplotlib.pyplot as plt
import numpy as np
img = np.zeros((300, 300))
img[64:-64, 64:-64] = 1
img = ndimage.rotate(im, 30, mode='constant')
img = ndimage.gaussian_filter(im, 7)
# Original image
plt.imshow(im)
plt.show()
# edge detection
x = ndimage.sobel(im, axis=0, mode='constant')
y = ndimage.sobel(im, axis=1, mode='constant')
Sobel = np.hypot(x, y)
plt.imshow(sob)
plt.show()
输出:
示例:从图像创建 NumPy 数组
在这里,我们将使用 imread()函数读取图像。
Python3
from scipy import misc
import imageio
import matplotlib.pyplot as plt
img = imageio.imread('raccoon.png')
print(img.shape)
print(img.dtype)
plt.imshow(img)
plt.show()
输出:
(768, 1024, 3)
uint8
创建 RAW 填充
RAW 文件是包含来自图像传感器的最少处理数据的文件。我们可以使用 scipy 包的 tofile() 方法创建这个文件。
示例:使用 SciPy 创建 RAW 文件
Python3
from scipy import misc
import imageio
import matplotlib.pyplot as plt
# reads a raccoon face
face = misc.face()
face.tofile("raccoon.raw")
这将在我们当前的工作目录中创建一个 .raw 文件。
打开 RAW 文件
为了打开 .raw 文件,我们需要使用 fromfile() 方法的 NumPy 模块。此函数是读取具有已知数据类型的二进制数据以及解析简单格式化文本的有效方法。
示例:使用 NumPy 从 RAW 文件中读取
Python3
import numpy as np
img = np.fromfile('raccoon.raw',
dtype=np.uint8)
print(img.shape)
输出:
(2359296,)
获取统计信息
我们可以使用 max() 和 min() 函数来获得沿给定轴的最大值和最小值。为了找到平均值,我们可以使用 mean()函数。
示例:获取最小值、最大值和平均值
Python3
from scipy import misc
img = misc.face()
print(img.max())
print(img.min())
print(img.mean())
输出:
255
0
110.16274388631184
裁剪图像
我们知道图像是用矩阵中的数字表示的,所以改变矩阵的值会导致改变原始图像。让我们看看如何使用这个想法来裁剪图像。
示例:裁剪图像
Python3
from scipy import misc
import matplotlib.pyplot as plt
# for grascaling the image
img = misc.face(gray = True)
x, y = img.shape
# Cropping the image
crop = img[x//3: - x//8, y//3: - y//8]
plt.imshow(crop)
plt.show()
输出:
翻转图像
我们可以使用 numpy 模块的 flipud()函数来翻转该图像。此函数在上下方向翻转数组(每列中的条目),形状保留。
示例:使用 Scipy 翻转图像
Python3
from scipy import misc
import numpy as np
import matplotlib.pyplot as plt
img = misc.face()
flip = np.flipud(img)
plt.imshow(flip)
plt.show()
输出:
旋转图像
要旋转图像,我们可以使用 ndarray.rotate()函数。此函数以特定角度旋转图像。
示例:使用 SciPy 和 NumPy 旋转图像
Python3
from scipy import misc,ndimage
import matplotlib.pyplot as plt
img = misc.face()
rotate = ndimage.rotate(face, 30)
plt.imshow(rotate)
plt.show()
输出:
过滤图像
简单来说,图像过滤是一个增强或修改图像的过程,我们可以在其中增加清晰度、增强边缘或模糊图像。在图像过滤中,某些算法应用于给定图像的像素值,该算法确定输出图像的值。让我们看看可以使用 NumPy 和 SciPy 完成的一些图像过滤操作。
模糊图像
模糊图像是降低图像中噪声水平的过程。为此,我们可以使用高斯滤波器或独角兽滤波器。
示例:使用 SciPy 和 NumPy 模糊图像
Python3
from scipy import misc,ndimage
import matplotlib.pyplot as plt
img = misc.face()
blur_G = ndimage.gaussian_filter(img,sigma=7)
plt.imshow(blur_G)
plt.show()
输出:
锐化图像
锐化是指增加黑白明暗区域的对比度,使图像更加清晰,突出图像特征。锐化图像的主要原因有三个:克服相机设备造成的模糊、引起对某些区域的注意以及提高易读性。如果图像中存在模糊文本,则易于阅读。
示例:使用 NumPy 和 SciPy 锐化图像
Python3
from scipy import misc, ndimage
import matplotlib.pyplot as plt
img = misc.face(gray=True).astype(float)
blur = ndimage.gaussian_filter(img, 5)
# Showing Blur Image
plt.imshow(blur)
plt.show()
blur_G = ndimage.gaussian_filter(blur, 1)
alpha = 30
sharp = blur+alpha*(blur-blur_G)
# showing sharp images
plt.imshow(sharp)
plt.show()
输出:
去噪图像
图像去噪是指从噪声图像中重建信号的过程。进行去噪是为了从图像中去除不需要的噪声,以便以更好的形式对其进行分析。首先,让我们创建一个嘈杂的图像——
示例 1:创建嘈杂的图像
Python3
from scipy import misc,ndimage
import matplotlib.pyplot as plt
import numpy as np
img=misc.face(gray=True).astype(float)
img=img[40:100,30:100]
noise_img=img+0.9*img.std()*np.random.random(img.shape)
plt.imshow(noise_img)
plt.show()
输出:
为了平滑边缘和噪声,我们使用高斯滤波器。
Python3
denoised = ndimage.gaussian_filter(noise_img, 2.2)
plt.imshow(denoised)
plt.show()
输出:
我们还可以使用中值滤波器保留边缘。
Python3
denoised = ndimage.median_filter(noise_img, 4)
plt.imshow(denoised)
plt.show()
输出:
边缘检测
图像检测的过程包括检测图像中的边缘。它通过检测亮度的不连续性来工作。对于高强度变化,我们可以使用 Sobel,一个梯度运算符——
示例:使用 SciPy 和 NumPy 进行边缘检测
Python3
from scipy import misc, ndimage
import matplotlib.pyplot as plt
import numpy as np
img = np.zeros((300, 300))
img[64:-64, 64:-64] = 1
img = ndimage.rotate(im, 30, mode='constant')
img = ndimage.gaussian_filter(im, 7)
# Original image
plt.imshow(im)
plt.show()
# edge detection
x = ndimage.sobel(im, axis=0, mode='constant')
y = ndimage.sobel(im, axis=1, mode='constant')
Sobel = np.hypot(x, y)
plt.imshow(sob)
plt.show()
输出: