【opencv-python】均值滤波、中值滤波、高斯滤波、图像锐化的代码实现

  • 线性滤波、滤波核的基本概念
    • 数字图像处理线性滤波:
      输出图像fo(x,y)= T[ fi(x,y) ],T是线性算子,即:输出图像上每个像素点的值都是由输入图像各像素点值加权求和的结果。
      非线性滤波的算子中包含了取绝对值、置零等非线性运算。
      线性滤波器的原始数据与滤波结果是一种算术运算,即用加减乘除等运算实现,如均值滤波器(模板内像素灰度值的平均值)、高斯滤波器(高斯加权平均值)等。由于线性滤波器是算术运算,有固定的模板,因此滤波器的转移函数是可以确定并且是唯一的(转移函数即模板的傅里叶变换)。
      非线性滤波器的原始数据与滤波结果是一种逻辑关系,即用逻辑运算实现,如最大值滤波器、最小值滤波器、中值滤波器等,是通过比较一定邻域内的灰度值大小来实现的,没有固定的模板,因而也就没有特定的转移函数(因为没有模板作傅里叶变换),另外,膨胀和腐蚀也是通过最大值、最小值滤波器实现的。
      线性滤波:方框滤波 均值滤波 高斯滤波
      非线性滤波: 中值滤波 双边滤波
    • 核其实是一组权重,决定了如何利用某一个点周围的像素点来计算新的像素点,核也被称为卷积矩阵,对一个区域的像素做调和或者卷积运算,通常基于核的滤波器被称为卷积滤波器。
  • 均值、中值、最大值最小值、高斯、双边滤波的概念
    • 均值滤波器可以归为低通滤波器,是一种线性滤波器,其输出为邻域模板内的像素的简单平均值,主要用于图像的模糊和降噪。
      均值滤波器的概念非常的直观,使用滤波器窗口内的像素的平均灰度值代替图像中的像素值,这样的结果就是降低图像中的“尖锐”变化。这就造成,均值滤波器可以降低噪声的同时,也会模糊图像的边缘。均值滤波器的处理结果是过滤掉图像中的“不相关”细节,其中“不相关”细节指的是:与滤波器模板尺寸相比较小的像素区域。
      均值滤波其实就是对目标像素及周边像素取平均值后再填回目标像素来实现滤波目的的方法,当滤波核的大小是3 × 3 3\times 33×3时,则取其自身和周围8个像素值的均值来代替当前像素值。
      均值滤波也可以看成滤波核的值均为 1 的滤波。
      优点:算法简单,计算速度快;
      缺点:降低噪声的同时使图像产生模糊,特别是景物的边缘和细节部分。
    • 中值滤波器 Median Filter
      中值滤波器是一种常用的非线性滤波器,其基本原理是选择待处理像素的一个邻域中各像素值的中值来代替待处理的像素,其主要功能是像素的灰度值与周围像素比较接近,从而消除孤立的噪声点,所以中值滤波器能够很好的消除椒盐噪声。不仅如此,中值滤波器在消除噪声的同时,还能有效的保护图像的边界信息,不会对图像造成很大的模糊(相比于均值滤波器)。
      中值滤波器的效果受滤波窗口尺寸的影响较大,在消除噪声和保护图像的细节存在着矛盾:滤波窗口较小,则能很好的保护图像中的某些细节,但对噪声的过滤效果就不是很好;反之,窗口尺寸较大有较好的噪声过滤效果,但是会对图像造成一定的模糊。另外,根据中值滤波器原理,如果在滤波窗口内的噪声点的个数大于整个窗口内像素的个数,则中值滤波就不能很好的
      过滤掉噪声。
    • 高斯滤波器是一种线性滤波器,能够有效的抑制噪声,平滑图像。其作用原理和均值滤波器类似,都是取滤波器窗口内的像素的均值作为输出。其窗口模板的系数和均值滤波器不同,均值
      滤波器的模板系数都是相同的为1;而高斯滤波器的模板系数,则随着距离模板中心的增大而系数减小。所以,高斯滤波器相比于均值滤波器对图像个模糊程度较小。
      高斯滤波器模板的生成最重要的参数就是高斯分布的标准差σ。标准差代表着数据的离散程度,如果σ较小,那么生成的模板的中心系数较大,而周围的系数较小,这样对图像的平滑效果就不是很明显;反之,σ较大,则生成的模板的各个系数相差就不是很大,比较类似均值模板,对图像的平滑效果比较明显。
      σ越大,分布越分散,各部分比重差别不大,于是生成的模板各元素值差别不大,类似于平均模板;σ越小,分布越集中,中间部分所占比重远远高于其他部分,反映到高斯模板上就是中心元素值远远大于其他元素值,于是自然而然就相当于中间值得点运算。
      原理
      高斯滤波是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。其滤波核的值由如下公式得到(用当前点与中心点的欧式距离的平方代替下面的
      在这里插入图片描述

实现
在高斯滤波中,对每一个元素而言,则用它周围邻域和自身的加权求和代替它自身的值,假设滤波核是3 × 3,a5为当前元素,它周围8联通的像素值分别是a1、a2、a3、a4、a6、a7、a8、a9,它对应的权值分别是w1、w2、w3、w4、w5、w6、w7、w8,w9,则有
在这里插入图片描述
在这里插入图片描述

  • 双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。
    双边滤波器之所以能够做到在平滑去噪的同时还能够很好的保存边缘(Edge Preserve),是由于其滤波器的核由两个函数生成:
    • 一个函数由像素欧式距离决定滤波器模板的系数
    • 另一个函数由像素的灰度差值决定滤波器的系数在这里插入图片描述
  • 通过滤波实现图像锐化、边缘提取的计算思路
    • 图像的锐化和边缘检测很像,首先找到边缘,然后把边缘加到原来的图像上面,这样就强化了图像的边缘。也就是在边缘检测滤波器的基础上,再在中心的位置加1,这样滤波后的图像就会和原始的图像具有同样的亮度了,但是会更加锐利。锐化滤波器实际上就是计算当前点和周围点的差别,然后将这个差别加到原来的位置上。
    • 图像锐化是针对常见的图像模糊、边缘不清晰所采用的的处理方法,与平滑滤波相反,它 能够减弱或者消除图像中低频率分量,但不影响高频率分量,可使图像反差增加,加强图像的轮廓,是图像变得比较清晰。主要的目的:突出灰度的过度部分。
      利用二阶微分算子拉普拉斯算子进行图像的锐化,常见的拉普拉斯算子有[0 -1 0;-1 4 -1;0 -1 0] 和 [-1 -1 -1;-1 8 -1;-1 -1 -1],本次使用的 3X3 模板是 [-1 -1 -1;-1 8 -1;-1-1 -1]。首先取出计算的像素点 3X3 范围内的所有的点,之后进行按模板的参数加权求和,最后再加上原图像的灰度值,可以得到锐化后的像素点灰度值
      在这里插入图片描述
      在这里插入图片描述
import time

import cv2
import numpy as np

"""均值滤波、中值滤波、高斯滤波、图像锐化"""
'''
均值滤波的实现
path:图像路径
ksize:卷积核大小
'''


def Mean_blur(path, ksize):
    time_start = time.time()
    '''读取图像'''
    image = cv2.imread(path, 1)
    '''resize'''
    height = 400
    width = int(400 * image.shape[0] / image.shape[1])
    image = cv2.resize(image, (height, width))
    mean_img = np.copy(image)  # 创建输出图像
    '''计算均值滤波后的图像'''
    # 没有计算边缘像素点数小于卷积核大小的部分
    # 所占部分很小所以可以忽略
    kernel = np.ones((ksize, ksize))  # 创建卷积核
    for h in range(0, mean_img.shape[0] - ksize + 1):
        for w in range(0, mean_img.shape[1] - ksize + 1):
            for c in range(mean_img.shape[2]):
                mean_img[h, w, c] = np.sum(kernel * mean_img[h:h + ksize, w:w + ksize, c]) // (ksize * ksize)
    # 计时
    time_end = time.time()
    print(time_end - time_start, 's')
    '''show'''
    cv2.imshow('image', np.hstack((image, mean_img)))
    cv2.waitKey(0)


'''
中值滤波的实现
path:图像路径
ksize:卷积核大小
'''


def Median_blur(path, ksize):
    time_start = time.time()
    '''读取图像'''
    image = cv2.imread(path, 1)
    '''resize'''
    height = 400
    width = int(400 * image.shape[0] / image.shape[1])
    image = cv2.resize(image, (height, width))
    '''计算中值滤波后的图像'''
    median_img = np.copy(image)  # 创建输出图像
    # 没有计算边缘像素点数小于卷积核大小的部分
    # 所占部分很小所以可以忽略
    for h in range(0, median_img.shape[0] - ksize + 1):
        for w in range(0, median_img.shape[1] - ksize + 1):
            for c in range(median_img.shape[2]):
                median_img[h, w, c] = np.median(median_img[h:h + ksize, w:w + ksize, c])
    time_end = time.time()
    print(time_end - time_start, 's')  # 计时
    '''show'''
    cv2.imshow('image', np.hstack((image, median_img)))
    cv2.waitKey(0)


'''
高斯滤波
卷积核:1 2 8
'''


def Gaussian_blur(path):
    time_start = time.time()
    '''读取图像'''
    image = cv2.imread(path, 1)
    '''resize'''
    height = 400
    width = int(400 * image.shape[0] / image.shape[1])
    image = cv2.resize(image, (height, width))
    gaussian_img = np.copy(image)  # 创建输出图像
    '''高斯滤波'''
    kernel = np.array([
        [1, 2, 1],
        [2, 4, 2],
        [1, 2, 1]
    ])
    ksize = 3
    for h in range(0, gaussian_img.shape[0] - ksize + 1):
        for w in range(0, gaussian_img.shape[1] - ksize + 1):
            for c in range(gaussian_img.shape[2]):
                gaussian_img[h, w, c] = np.sum(kernel * gaussian_img[h:h + ksize, w:w + ksize, c]) // 16
    # 计时器
    time_end = time.time()
    print(time_end - time_start, 's')
    '''show'''
    cv2.imshow('image', np.hstack((image, gaussian_img)))
    cv2.waitKey(0)


'''
图像锐化的实现
path:图像路径
ksize:卷积核大小
'''


def Sharpen(path):
    time_start = time.time()
    '''读取图像'''
    image = cv2.imread(path, 1)
    '''resize'''
    height = 400
    width = int(400 * image.shape[1] / image.shape[0])
    image = cv2.resize(image, (width, height))
    kernel = np.array([
        [0, -1, 0],
        [-1, 5, -1],
        [0, -1, 0]
    ])
    ksize = 3
    sharpen_ing = np.copy(image)  # 创建输出图像
    H, W, C = sharpen_ing.shape
    # 没有计算边缘像素点数小于卷积核大小的部分
    # 所占部分很小所以可以忽略
    for h in range(0, H - ksize + 1):
        for w in range(0, W - ksize + 1):
            for c in range(0, 3):
                sharpen_ing[h, w, c] = np.sum(kernel * sharpen_ing[h:h + ksize, w:w + ksize, c])
    time_end = time.time()
    print(time_end - time_start, 's')  # 计时器
    '''show'''
    cv2.imshow('image', np.hstack((image, sharpen_ing)))
    cv2.waitKey(0)


# Mean_blur("imgs/woman.jpg", 5)
# Median_blur("imgs/woman.jpg", 3)
Gaussian_blur("imgs/woman.jpg")
# Sharpen("imgs/img_4.png")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值