在很多应用中,图像强度的变化情况是非常重要的信息。强度的变化可以灰度图像的
和
方向导数
和
进行描述。图像的梯度向量为
。梯度有两个重要属性,一个是梯度的大小:
它描述了图像强度变化的强弱,另一个是梯度的角度:
描述了图像中每个像素点上强度变化最大的方向。我们可以使用离散近似的方式来计算图像的导数。图像导数大多数可以通过卷积简单地实现:
对于
和
,通常选择Priwitt滤波器:
或者Sobel滤波器:
上面两种计算图像导数的方法存在一些缺陷:滤波器的尺度需要随着图像分辨率的变化而变化。为了在图像噪声方面更稳健,以及在任意尺度上计算导数,我们可以使用高斯导数滤波器:
其中,
和
表示
在
和
方向上的导数,
为标准差为
的高斯函数。
样例演示
代码语言:javascript复制from scipy.ndimage import filters
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
class ScipyFilter:
def __init__(self, path: str):
self.img = np.array(Image.open(path))
self.grayImg = np.array(Image.open(path).convert('L'))
self.Ix = np.zeros(self.grayImg.shape)
self.Iy = np.zeros(self.grayImg.shape)
self.manitude = np.zeros(self.grayImg.shape)
def cal_derivatives_sobel(self):
"""
使用sobel滤波器计算导数
:return:
"""
filters.sobel(self.grayImg, 1, self.Ix)
filters.sobel(self.grayImg, 0, self.Iy)
self.manitude = np.sqrt(self.Ix**2 self.Iy**2)
def cal_derivatives_prewitt(self):
"""
使用prewitt滤波器计算导数
:return:
"""
filters.prewitt(self.grayImg, 1, self.Ix)
filters.prewitt(self.grayImg, 0, self.Iy)
self.manitude = np.sqrt(self.Ix**2 self.Iy**2)
def cal_derivatives_gaussian(self, sigma):
"""
计算图像高斯导数
:param img: 图像数据
:param sigma: 标准差
:return:
"""
filters.gaussian_filter(self.grayImg, (sigma, sigma), (0, 1), self.Ix)
filters.gaussian_filter(self.grayImg, (sigma, sigma), (1, 0), self.Iy)
def plot(self):
# 绘图
plt.figure()
plt.gray()
plt.subplot(221).set_title("original img")
plt.imshow(self.grayImg)
plt.axis('off')
plt.subplot(222).set_title('x-directional derivative')
plt.imshow(self.Ix)
plt.axis('off')
plt.subplot(223).set_title('y-directional derivative')
plt.imshow(self.Iy)
plt.axis('off')
plt.subplot(224).set_title("gradient magnitude")
plt.imshow(self.manitude)
plt.axis('off')
plt.show()
if __name__ == '__main__':
img_path = "./imgs/3.jpg"
sc = ScipyFilter(img_path)
sc.cal_derivatives_sobel()
sc.plot()
sc.cal_derivatives_prewitt()
sc.plot()
sc.cal_derivatives_gaussian(3)
sc.plot()
sc.cal_derivatives_gaussian(5)
sc.plot()
结果演示
sobel滤波
prewitt滤波
gaussian滤波,标准差设置为3
gaussian滤波,标准差设置为5
在图像中,正导数显示为亮的像素,负导数显示为暗的像素。灰色区域表示导数的值接近零。
图像高斯模糊
代码语言:javascript复制from PIL import Image
import numpy as np
from scipy.ndimage import filters
img = Image.open(r"girl.jpg").convert('L')
img = np.array(img)
img2 = filters.gaussian_filter(img, 2)
img3 = filters.gaussian_filter(img, 5)
img4 = filters.gaussian_filter(img, 10)
结果演示