数字图像处理-空间滤波


前言

本数字图像处理的学习系列是对课本知识的实现,完成课程相关的实验部分。


题目描述

熟练掌握空域滤波中常见的平滑和锐化滤波器。

基本概念

  1. 了解空域滤波概念与图像平滑和图像锐化两种方法。按数学形态分类:线性(高通、低通、带通)与非线性(中值(优于均值)、最大值、最小值);按处理效果分类:平滑滤波器和锐化滤波器。
  2. 了解平滑滤波的背景、作用以及常用方法。
  3. 了解锐化滤波的背景、作用以及常用方法。

学习目标

  1. 了解图像中的噪声类型:高斯(正态)噪声、椒盐(脉冲)噪声等。
  2. 了解均值滤波、高斯滤波、中值滤波、双边滤波等。
  3. 了解Sobel算子、Scharr算子和拉普拉斯算子等。
  4. 掌握canny边缘检测的原理及应用。

代码实现

"""
    # -*- coding :utf-8 -*-
    # @Time:2022/3/159:17
    # @Author:WEIKETAN
    # @File:Image_smoothing.py
    # @Desc:
"""
import cv2 as cv
import matplotlib
import numpy as np
from matplotlib import pyplot as plt

"""
    前三个方法分别是均值滤波、高斯滤波、中值滤波,都是图像平滑的方法,目的去噪;
    后三种方法分别是scharr算子、sobel算子(一阶微分)、拉普拉斯算子(二阶微分),目的增强边缘;
    
"""

def Meanfiltering():
    """
    cv2读取图片是以BGR形式进行读取的,经过imshow函数会变成RGB形式
    plt读取图片是以RGB形式进行读取的.
    :return:
    """
    # 1. 读取图片
    img = cv.imread("F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\dogsp.jpeg")
    # cv.imshow("img", img)
    # img1 = plt.imread("F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\dog.jpeg")
    # plt.imshow(img1)

    # 2. 均值滤波
    blurImg = cv.blur(img, (5, 5))

    # 3. 图像显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig, axes = plt.subplots(ncols=2, figsize=(10, 8))
    print(np.shape(img))
    axes[0].imshow(img[:, :, ::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(blurImg[:, :, ::-1])
    axes[1].set_title("均值滤波后的结果")
    plt.show()

def Gaussianfiltering():
    # 1. 读取图片
    img = cv.imread("F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\dogsp.jpeg")

    # 2. 高斯滤波
    GaussianBlurImg = cv.GaussianBlur(img, (3,3), 1)

    # 3. 图像显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig, axes = plt.subplots(ncols=2,figsize=(10,8))

    axes[0].imshow(img[:, :, ::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(GaussianBlurImg[:, :, ::-1])
    axes[1].set_title("高斯滤波后的结果")
    plt.show()


def medianfiltering():
    # 1. 读取图片
    img = cv.imread(
        "F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\dogGauss.jpeg")

    # 2. 中值滤波
    medianBlurImg = cv.medianBlur(img, 5)

    # 3. 图像显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig,axes = plt.subplots(ncols=2,figsize=(10,8))
    print(np.shape(img))
    axes[0].imshow(img[:,:,::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(medianBlurImg[:,:,::-1])
    axes[1].set_title("中值滤波后的结果")
    plt.show()

def scharrOperator():
    # 1. 读取图片
    img = cv.imread(
        "F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\deer.jpeg")

    # 2. 计算scharr卷积结果
    """
    scharr参数:
            src: 传入的图像
            ddepth:图像的深度
            dx和dy:指求导的阶数
            ksize: 是scharr算子的大小,即卷积核的大小。 ksize=-1就是利用Scharr进行边缘检测
            scale: 比例常数
            borderType: 图像边界的模式
    """
    x = cv.Sobel(img,cv.CV_16S,1,0,ksize=-1)
    y = cv.Sobel(img,cv.CV_16S,0,1,ksize=-1)

    # 3. 将数据进行转换
    Scale_absX = cv.convertScaleAbs(x)
    Scale_absY = cv.convertScaleAbs(y)

    # 4. 结果合成到一起
    result = cv.addWeighted(Scale_absX,0.5,Scale_absY,0.5,0)

    # 5. 图像显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig,axes = plt.subplots(ncols=2,figsize=(10,8))
    axes[0].imshow(img[:,:,::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(result[:,:,::-1])
    axes[1].set_title("scharr滤波后的结果")
    plt.show()

def sobelOperator():
    # 1. 读取图片
    img = cv.imread(
        "F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\deer.jpeg")

    # 2. 计算Sobel卷积结果
    """
    Sobel参数:
            src: 传入的图像
            ddepth:图像的深度
            dx和dy:指求导的阶数
            ksize: 是Sobel算子的大小,即卷积核的大小 
            scale: 比例常数
            borderType: 图像边界的模式
    """
    x = cv.Sobel(img, cv.CV_16S, 1, 0)
    y = cv.Sobel(img, cv.CV_16S, 0, 1)

    # 3. 将数据进行转换
    Scale_absX = cv.convertScaleAbs(x)
    Scale_absY = cv.convertScaleAbs(y)

    # 4. 结果合成到一起
    result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)

    # 5. 图像显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig,axes = plt.subplots(ncols=2, figsize=(10, 8))
    axes[0].imshow(img[:, :, ::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(result[:, :, ::-1])
    axes[1].set_title("sobel滤波后的结果")
    plt.show()

def LaplaceOperator():
    # 1. 读取图片
    img = cv.imread(
        "F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\deer.jpeg")

    # 2. Laplace转换
    """
    Laplace参数:
            src: 传入的图像
            ddepth:图像的深度
            ksize: 是Sobel算子的大小,即卷积核的大小 
            scale: 比例常数
            borderType: 图像边界的模式
    """
    result = cv.Laplacian(img, cv.CV_16S,3)

    # 3. 数据转换
    Scale_abs = cv.convertScaleAbs(result)

    # 4. 图像显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig,axes = plt.subplots(ncols=2,figsize=(10,8))
    axes[0].imshow(img[:,:,::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(Scale_abs[:,:,::-1])
    axes[1].set_title("Laplacian滤波后的结果")
    plt.show()

def CannyOperator():
    # 1. 读取图片
    img = cv.imread(
        "F:\\Develop_Tools_Python\\Python_WorkSpace\\Notebook_Python_WorkSpace\\IMage_processing\\homeworks\\photo\\deer.jpeg")

    # 2.canny边缘检测
    """
    Canny参数:
            img: 传入的图像
            threshold1:minval,较小的阈值将间断的边缘连接起来
            threshold2: maxval,较大的阈值检测图像中明显的边缘
    """
    lowthreshold = 0
    max_lowthreshold = 100
    result = cv.Canny(img, lowthreshold, max_lowthreshold)

    # 3. 图片显示
    # 设置字体为楷体,解决显示字体乱码问题
    matplotlib.rcParams['font.sans-serif'] = ['KaiTi']
    fig, axes = plt.subplots(ncols=2, figsize=(10, 8))
    axes[0].imshow(img[:, :, ::-1])  # 原图片img是BGR格式,所以需要转换为RGB格式,即对原图片进行左右翻转
    axes[0].set_title("原图")
    axes[1].imshow(result)
    axes[1].set_title("Canny滤波后的结果")
    plt.show()


if __name__ == '__main__':
    # 1、均值滤波
    # Meanfiltering()

    # 2、高斯滤波
    # Gaussianfiltering()

    # 3、中值滤波
    # medianfiltering()

    # 4、scharr算子(sobel的加强版)
    # scharrOperator()

    # 5、sobel算子(一阶微分)
    # sobelOperator()

    # 6、拉普拉斯算子(二阶微分)
    # LaplaceOperator()

    # 7、Canny边缘检测
    CannyOperator()

效果演示

1、均值滤波
在这里插入图片描述
2、 高斯滤波
在这里插入图片描述

3、中值滤波
在这里插入图片描述
4. scharr算子
在这里插入图片描述
5. sobel算子在这里插入图片描述
6. 拉普拉斯算子
在这里插入图片描述
7. canny边缘检测

在这里插入图片描述

总结

  1. cv与plt分别是以BGR格式和RGB格式进行读取图片的
  2. 边缘检测原理:
    基于搜索:利用一阶导数的最大值获取边界
    基于零穿越:利用二阶导数为0获取边界
  3. Sobel算子、laplacian算子、canny算子
  4. 算子之间进行比较在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值