图像处理:高斯滤波算法

news2024/11/25 6:43:36

目录

前言

概念介绍

基本原理

卷积核的大小

卷积核的形状和权重比

卷积核的归一化

结论

Opencv实现高斯滤波

Python手写实现高斯滤波

参考文章


前言

在此之前,我曾在此篇中推导过图像处理:推导五种滤波算法(均值、中值、高斯、双边、引导)。这在此基础上,我想更深入地研究和推导这些算法,以便为将来处理图像的项目打下基础。

概念介绍

高斯滤波是一种常用的图像处理技术,常用于去噪、平滑和边缘检测等应用中。它是基于高斯函数的概念,由于高斯函数的性质,距离中心像素越远的像素对新值的贡献越小,对图像中的像素进行加权平均处理,使得周围像素的影响比较大,而远离中心像素的影响则较小。因此,高斯滤波可以平滑图像并去除一部分噪声,同时保留图像中的边缘和细节。

具体来说,高斯滤波是通过一个矩阵(卷积核)来实现的。这个矩阵的值是由高斯函数计算出来的,高斯函数在中心点处取得最大值,随着距离的增加而逐渐减小。矩阵的大小和参数的选择取决于需要处理的图像和要达到的效果。

基本原理

这里以一个3x3的卷积核为例,卷积核的值是由高斯函数计算出来的,高斯函数在中心点处取得最大值,随着距离的增加而逐渐减小。通过对每个像素应用卷积核,高斯滤波可以对图像进行平滑处理并去除噪声,同时保留图像的细节和边缘。

如上图所示,高斯函数在中心点处的值最大,离中心点越远的值越小。这意味着对于每个像素,距离中心像素越远的像素对新值的影响越小。这种影响方式使得高斯滤波可以去除图像噪声,同时保留图像细节和边缘。

通过高斯滤波的计算过程,可以得出中心点像素值226被新值164所替代的结果。具体来说,通过一个简单的矩阵点乘计算,将卷积核与图像中的像素矩阵相乘,得出每个像素的新值。

它的计算过程如下所示:

a=40*1+107*2+5*1+198*2+226*8+223*2+37*1+68*2+193*1
b=a*(1/(1*4+2*4+8))
print(b)

卷积核的大小

前面举的例子是以3x3大小的卷积核为例,这里就详细补充一些有关于卷积核的知识。

卷积核的形状和权重比

卷积核的形状通常是一个矩阵,长和宽可以有所不同,但必须是奇数。在高斯滤波中,卷积核的大小通常是3x3、5x5、7x7等。其中,3x3的卷积核是最常用的,它的中心点权重最大,周围点权重逐渐减小。

\frac{1}{256}\begin{bmatrix} 1 & 4 & 6 & 4 &1 \\ 4 & 16 & 24 & 16 & 4\\ 6 & 24& 36 & 24 &6 \\ 4 & 16 & 24 &16 &4 \\ 1& 4 & 6 &4 &1 \end{bmatrix} \frac{1}{159}\begin{bmatrix} 2& 9& 5& 9 &2 \\ 4& 4& 12& 4 &4 \\ 5& 12& 15& 12 &5 \\ 4& 9& 12& 9& 4\\ 2& 4 & 5 & 4 &2 \end{bmatrix}

同一尺寸的卷积核可以有不同的形式的权重比例,这些权重比例会决定卷积核对图像不同区域的关注程度。在高斯滤波中,卷积核的权重比是根据高斯函数计算得出的。高斯函数是一个钟形曲线,它的中心点权重最大,两侧的权重逐渐减小。

卷积核的归一化

在实际使用过程中,往往需要对卷积核进行归一化,以保证滤波效果的正确性。在高斯滤波中,卷积核的所有权重值都需要缩放到相同的范围内,并且总和为1,以保证卷积操作对图像的影响是平衡的,避免某些权重过大或过小导致滤波结果出现偏差。

结论

卷积核是图像处理中非常重要的概念,它可以通过卷积操作实现滤波、边缘检测等功能。在高斯滤波中,卷积核的大小、权重比例和归一化等因素都会影响滤波效果。因此,需要根据实际情况选择合适的卷积核,并对卷积核进行适当的调整,以满足不同的图像处理需求。

Opencv实现高斯滤波

def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None):

在Opencv中,我们可以使用cv2.GaussianBlur()函数来实现高斯滤波。使用该函数时,需要输入原始图像、卷积核的大小、沿着x轴、y轴方向的高斯核标准差以及边界样式等参数。其中sigmaY和borderType是可选参数,sigmaX是必选参数,但是可以将该参数设置为 0,让函数自己去计算 sigmaX 的具体值。

import cv2
import numpy as np
import pyps.pyzjr.utility as zjr
path = 'Images/Colnoiselena.jpg'

img = cv2.imread(path)
imgGaussianBlur_1=cv2.GaussianBlur(img,(1,1),0,0)
imgGaussianBlur_3=cv2.GaussianBlur(img,(3,3),0,0)
imgGaussianBlur_5=cv2.GaussianBlur(img,(5,5),0,0)
imgGaussianBlur_7=cv2.GaussianBlur(img,(7,7),0,0)

imgStack = zjr.stackImages(0.6, ([imgGaussianBlur_1, imgGaussianBlur_3], [imgGaussianBlur_5, imgGaussianBlur_7]))
cv2.imshow("imges",imgStack)
cv2.waitKey(0)
cv2.destroyAllWindows()

实现效果: 

一般情况下,卷积核大小和高斯核标准差是需要根据实际场景进行调整的。如果需要对图像进行更强的模糊处理,可以增加sigma值和卷积核的大小;如果需要对图像进行较弱的模糊处理,可以减小sigma值和卷积核的大小。

Python手写实现高斯滤波

import cv2
import numpy as np
import pyps.pyzjr.utility as zjr
path = 'Images/Colnoiselena.jpg'
img = cv2.imread(path)

def gaussian_kernel(size, sigma):
    kernel = np.zeros((size, size), dtype=np.float32)
    center = size // 2

    for i in range(size):
        for j in range(size):
            x, y = i - center, j - center
            kernel[i, j] = np.exp(-(x**2 + y**2)/(2*sigma**2))
    kernel /= 2 * np.pi * sigma**2
    kernel /= np.sum(kernel)
    return kernel

def Gaussian_Filtering(img, kernel_size, sigma):
    kernel = gaussian_kernel(kernel_size, sigma)
    height, width, channels = img.shape
    result = np.zeros_like(img, dtype=np.float32)

    pad_size = kernel_size // 2
    img_pad = np.pad(img, [(pad_size, pad_size), (pad_size, pad_size), (0, 0)], mode='constant')
    for c in range(channels):
        for i in range(pad_size, height + pad_size):
            for j in range(pad_size, width + pad_size):
                result[i - pad_size, j - pad_size, c] = np.sum(kernel * img_pad[i - pad_size:i + pad_size + 1, j - pad_size:j + pad_size + 1, c])
    return np.uint8(result)

imgGaussianBlur_1 = Gaussian_Filtering(img, 1, 1.5)
imgGaussianBlur_3 = Gaussian_Filtering(img, 3, 1.5)
imgGaussianBlur_5 = Gaussian_Filtering(img, 5, 1.5)
imgGaussianBlur_7 = Gaussian_Filtering(img, 7, 1.5)
imgStack = zjr.stackImages(0.6, ([imgGaussianBlur_1, imgGaussianBlur_3], [imgGaussianBlur_5, imgGaussianBlur_7]))
cv2.imshow("imges",imgStack)
cv2.waitKey(0)
cv2.destroyAllWindows()

与手写实现均值滤波的情况大致相同,还是计算速度比较慢的情况,不过这里从效果来看,又是相差不大。

下面是这个函数的具体实现过程: 

  • 定义一个高斯核:首先通过 gaussian_kernel() 函数生成一个高斯核,该函数根据输入的 sizesigma 参数生成一个高斯核,其中 size 表示高斯核的大小, sigma 表示高斯核的标准差。

G(x,y)=\frac{1}{2\pi \sigma^{2}}e^{-\frac{x^{2}+y^{2}}{2\sigma ^{2}}}

  • 对图像进行补零:由于高斯滤波是在图像的像素周围应用高斯核,因此需要对图像进行补零处理,以便在图像的边缘区域进行高斯卷积时不会出现越界的情况。这里使用 np.pad() 函数来实现对图像的补零操作,其中只对高和宽两个维度进行填充,通道维度不进行填充。

  • 实现高斯卷积:对于每一个像素,将以它为中心的区域和高斯核进行卷积,这里使用嵌套的三重循环对图像进行遍历,其中 c 表示图像的通道数, ij 表示当前像素的位置。

  • 将卷积结果存储在结果矩阵中:将卷积的结果保存在一个结果矩阵中,该矩阵与原始图像具有相同的大小。最后将该结果矩阵转换为uint8格式并返回。

需要注意的是,在对图像进行高斯滤波时,应该对每一个通道分别进行处理,因此在高斯卷积的循环中需要增加一个针对通道的循环。

参考文章

(13条消息) 图像处理:推导五种滤波算法(均值、中值、高斯、双边、引导)_高斯滤波,均值滤波,中值滤波_夏天是冰红茶的博客-CSDN博客

(19条消息) 高斯滤波(Gauss filtering)_半濠春水的博客-CSDN博客

(6条消息) 高斯滤波及其原理_声希Censh的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/461274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux 命令之 tar -czvf和 tar -xzvf

文章目录 一、概述:二、基础知识 一、概述: tar 用于linux 系统中压缩和解压 二、基础知识 tar常用命令参数说明 tar命令的czvf/xzvf参数分别代表的意义如下: -c 或–create 建立新的备份文件。 -x或–extract或–get 从备份文件中还原文件…

为什么用Selenium做自动化测试

手工测试的问题 手工操作点点点借助的是人脑的反应和聪明,为什么不用手点了呢?手会酸,脑子会累,会占据太多的时间。想一想为什么会学习自动化测试。我们都希望通过工具来解放我们的双手,大脑,眼睛。 为什…

蚂蚁安全科技 Nydus 镜像加速实践

蚂蚁安全科技 Nydus 镜像加速实践 原创 曦栖 金融级分布式架构 文|蚂蚁集团 ZOLOZ 团队 使用全球领先安全科技,为用户和机构提供安全、便捷的安全风控解决方案。 本文 6386 字 阅读 12 分钟 背景简介 ZOLOZ[1]是蚂蚁集团旗下的全球安全风控平台&…

84.qt qml-Sprite精灵、SpriteSequence、ImageParticle使用Sprite精灵动画(三)

在上章我们学习了83.qt qml-初步学习2D粒子影响器(二)_诺谦的博客-CSDN博客 然后还有两个影响器没有学习: 粒子精灵影响器SpriteGoal 粒子组影响器GroupGoal 本章我们便来学习粒子精灵和粒子精灵影响器 ImageParticle通过sprites来设置精灵列表,如下图所示: 所以我们需要…

JVM学习(八):运行时数据区——虚拟机栈(字节码程度深入剖析)

目录 一、概述 1.1 基于栈结构的虚拟机 1.2 栈和堆 二、虚拟机栈(Java Virtual Machine Stack)详述 2.1 虚拟机栈介绍 2.2 虚拟机栈作用 2.3 虚拟机栈特点 三、栈中常见的异常 3.1 StackOverflowError异常 3.2 OutOfMemoryError异常 四、…

OpenGL学习笔记(一)

文章目录 1. 顶点2. 着色器(Shader) 1. 顶点 OpenGL本质是一个状态机,点作为表示图形最基本的元素,如何告诉OpenGL点的基本信息就是我们要做的事情 1.1VertexArray VertexArray是所有顶点的集合,我们可以将VertexBuffer分成很多组&#xff…

Volatile系列(一):Volatile测试案例一可见性

系列文章 Volatile测试案例一可见性 目录​​​​​​​ 前言 测试1 逻辑 代码 结果 测试2 逻辑 代码 结果 结论 原理探讨(可见性) 前言 多线程是 JAVA 并发编程的主要应用,并发环境能大幅提高应用性能,提高 CPU 使用…

基于springboot+mysql+html实现智能停车场管理系统

基于springbootmysqlhtml实现智能停车场管理系统 一、系统介绍1、系统主要功能:2.涉及技术框架:3.本项目所用环境: 二、功能展示三、其它系统四、获取源码 一、系统介绍 1、系统主要功能: 系统管理:角色管理、接口管…

华为OD机试真题(Java),货币单位换算(100%通过+复盘思路)

一、题目描述 记账本上记录了若干条多国货币金额,需要转换成人民币分 (fen),汇总后输出每行记录一条金额,金额带有货币单位,格式为数字单位,可能是单独元,或者单独分,或者元与分的组合要求将这…

解决方案:Zotero实现参考文献中英文混排,将英文文献中的“等”转成“et al.”

Zotero 是一款非常实用且易于使用的参考文献管理工具,可帮助用户收集、整理和引用各种类型的文献,包括图书、期刊文章、网页等。在学术写作中起着重要作用。 但是其在中文世界中,运行起来偶尔会出现问题,这里记录一个问题及其解决…

Nacos安装配置2.0以上版本

一、Nacos使用 1、官网 Nacos Spring 快速开始 Nacos Spring Boot 快速开始 Nacos Spring Cloud 快速开始 Nacos Docker 快速开始 Dubbo 融合 Nacos 成为注册中心 Kubernetes Nacos NacosSync 介绍 2、配置文件 nacos-配置中心官方文档说明 nacos-注册中心官方文档说明 在nacos…

浅谈拉格朗日插值法

浅谈拉格朗日插值法 好像FFT要用到,所以就学习一手 文章目录 浅谈拉格朗日插值法什么是插值拉格朗日插值法 什么是插值 在离散数据的基础上补插连续的函数,使得这条连续函数经过所有离散数据点,这个过程就叫插值。其意义在于: …

缓存和数据库一致性问题

情况一 先更新缓存再更新数据库 先更新缓存 再更新数据库 如果数据库更新失败 那我们缓存也没有意义 而且这个缓存也是需要计算的消耗资源的 所以不可取到 情况二 先更新数据库 后更新缓存 两个线程 线程A更新数据库 但是由于某些原因被阻塞了 也就是A更新后的数值没有被更新到…

Ajax 创建对象

文章目录 AJAX 创建对象创建 XMLHttpRequest 对象XMLHttpRequest 对象创建 XMLHttpRequest 对象 AJAX 创建对象 创建 XMLHttpRequest 对象 XMLHttpRequest 是 AJAX 的基础。 XMLHttpRequest 对象 所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 Acti…

【pyTorch学习笔记③】PyTorch基础·上篇

文章目录 一、PyTorch介绍二、PyTorch的安装1、CPU版本2、GPU版本 三、Numpy与Tensor1.Tensor的创建2.Tensor的变形 相关推荐 一、PyTorch介绍 PyTorch是Facebook发布的一款深度学习框架,继承了Torch灵活、动态的编程环境和用户友好的界面,支持以快速和灵…

kafka使用详解、最佳实践和问题排查

kafka是一个常用的分布式消息中间件,与RabbitMQ对比,特点是可以无限横向扩容,并保持高可靠性、高吞吐量和低延迟,因此比RabbitMQ有更高的市场占有率(网上搜了一下,kafka大约41%,RabbitMQ大约29%…

【网络安全】Metasploit工具

Metasploit Metasploit介绍默认安装目录主要应用文件modules文件内容介绍目录内容 Metasploit使用常用命令信息收集之端口扫描信息收集之c段扫描ms17_010(永恒之蓝) msfvenom生成木马命令入侵win全过程 Metasploit介绍 默认安装目录 /usr/share/metasp…

C语言指针2大问题:指针类型有什么用?指针如何运算?

如题,本篇博客主要解决2个疑点:指针类型的用处,指针如何运算。 1.指针类型 C语言中的指针类型,在X86环境下大小是4个字节,在X64环境下大小是8个字节。既然指针的大小和指针类型无关,那么指针类型究竟有什么…

AI看图说话,MiniGPT-4已经开源

MiniGPT-4 是一个人工智能工具,​最大的飞跃是增加了识图能力,​并且回答准确性也得到显著提高。​它可以识别图片并回答关于图片的问题,​例如图片内容、​颜色等等。 ​此外,​它还可以进行图像对话,​即通过图片和…

MFC之CRect详解

2023年4月25日,周二晚上。 今天查了不少关于CRect类及其相关内容的资料,学到了不少东西,所以我决定写一篇详细的关于CRect类及其相关内容的文章,以记录今天所学。 CRect类 在 MFC 中,CRect 类表示一个矩形区域。它是…