前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图像求导及模糊

图像求导及模糊

作者头像
范中豪
发布2019-09-30 16:37:49
8890
发布2019-09-30 16:37:49
举报
文章被收录于专栏:CV学习史CV学习史CV学习史

在很多应用中,图像强度的变化情况是非常重要的信息。强度的变化可以灰度图像的

(x)

(y)

方向导数

(I_x)

(I_y)

进行描述。图像的梯度向量为

(nabla I = [I_x, I_y]^T)

。梯度有两个重要属性,一个是梯度的大小:

| \nabla I | = \sqrt{I_x^2+I_y^2}

它描述了图像强度变化的强弱,另一个是梯度的角度:

\alpha = arctan2(I_y, I_x)

描述了图像中每个像素点上强度变化最大的方向。我们可以使用离散近似的方式来计算图像的导数。图像导数大多数可以通过卷积简单地实现:

I_x = I*D_x \ 和\ I_y = I*D_y

对于

(D_x)

(D_y)

,通常选择Priwitt滤波器:

D_x = \left[ \begin{matrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{matrix} \right] 和D_y=\left[ \begin{matrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1 & 1 & 1 \end{matrix} \right]

或者Sobel滤波器:

D_x = \left[ \begin{matrix} -1 & 0 & 1 \\ 2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right] 和D_y=\left[ \begin{matrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right]

上面两种计算图像导数的方法存在一些缺陷:滤波器的尺度需要随着图像分辨率的变化而变化。为了在图像噪声方面更稳健,以及在任意尺度上计算导数,我们可以使用高斯导数滤波器:

I_x = I*G_{\sigma x} 和 I_y = I*G_{\sigma y}

其中,

(G_{sigma x})

(G_{sigma y})

表示

(G_sigma)

(x)

(y)

方向上的导数,

(G_sigma)

为标准差为

(sigma)

的高斯函数。

样例演示

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

在图像中,正导数显示为亮的像素,负导数显示为暗的像素。灰色区域表示导数的值接近零。

图像高斯模糊

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)

结果演示

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档