当前位置: 首页 > article >正文

OpenCV计算机视觉实战(8)——图像滤波详解

OpenCV计算机视觉实战(8)——图像滤波详解

    • 0. 前言
    • 1. 线性滤波
      • 1.1 均值滤波
      • 1.2 高斯滤波
      • 1.3 拉普拉斯滤波
      • 1.4 Sobel 滤波
    • 2. 非线性滤波
    • 3. 自定义卷积核
    • 小结
    • 系列链接

0. 前言

在本文中,我们将深入探索线性与非线性滤波的算法原理、性能优化及实战技巧,从最基础的均值与高斯滤波,到中值与双边滤波,最后介绍如何灵活运用自定义卷积核。

1. 线性滤波

在图像处理领域,线性滤波是一种常见的图像平滑和增强方法,通过对图像进行局部加权平均,从而达到去噪、平滑、边缘检测等目的。它通过在图像的每个像素周围应用一个滤波器(通常称为卷积核),将邻域像素的加权和作为目标像素的输出。
图像中的每个像素值 I ( x , y ) I(x,y) I(x,y) 都会被周围邻域的像素值加权平均后进行更新。假设有一个大小为 m × n m×n m×n 的滤波器(卷积核) H H H,它作用在输入图像的每个像素上。滤波过程可以表示为:
I ′ ( x , y ) = ∑ i = − k k ∑ ​ j = − l l ​ H ( i , j ) ⋅ I ( x + i , y + j ) I'(x,y)=\sum_{i=−k}^k∑_{​j=−l}^l​H(i,j)⋅I(x+i,y+j) I(x,y)=i=kkj=llH(i,j)I(x+i,y+j)
其中:

  • I ′ ( x , y ) I'(x,y) I(x,y) 是经过滤波后的图像像素值
  • I ( x + i , y + j ) I(x+i,y+j) I(x+i,y+j) 是原始图像的邻域像素值。
  • H ( i , j ) H(i,j) H(i,j) 是滤波器的权重值(通常是对称且以中心为最高权重)
  • k k k l l l 是滤波器的半宽度

1.1 均值滤波

均值滤波是最简单的线性滤波方法,通过计算每个像素的邻域平均值来平滑图像,能有效抑制随机噪声。滤波器通常是一个全 1 的矩阵,大小为 m × n m×n m×n。例如,对于一个 3 × 3 3×3 3×3 的滤波器:
H = 1 9 [ 1 1 1 1 1 1 1 1 1 ] H= \frac 1 9\begin{bmatrix} 1 & 1 &1 \\ 1 & 1 &1 \\1 & 1 &1\end{bmatrix} \quad H=91 111111111
每个像素的新值是它周围 8 个邻域像素和当前像素的平均值。

1.2 高斯滤波

高斯滤波器采用高斯函数作为权重对邻域像素加权平均,中心像素权重最高,远离中心的权重逐渐降低。相比于均值滤波,,其在频域上具有更好的低通特性(快速衰减高频),能够在平滑噪声的同时较好保留图像轮廓信息。OpenCV 在内部对高斯滤波采用了分离卷积优化,将二维卷积拆解为两个一维卷积,减小算法复杂度至 O ( n ) O(n) O(n) 级别,大幅提升大核尺寸时的性能。

例如,对于一个 3 × 3 3×3 3×3 的高斯滤波器:
H = 1 16 [ 1 2 1 2 4 2 1 2 1 ] H= \frac 1 {16}\begin{bmatrix} 1 & 2 &1 \\ 2 & 4 &2 \\1 & 2 &1\end{bmatrix} \quad H=161 121242121
该矩阵的元素是基于高斯分布计算的。核大小 (ksize) 与标准差 (sigma) 的选择直接影响滤波效果:较大的核或 sigma 会增强去噪效果,但也会丢失更多细节;工程中通常结合图像分辨率和噪声强度,在 3×3~7×7 之间调优
接下来,分别调用 cv2.blurcv2.GaussianBlur,通过调整 ksizesigmaX 观察平滑与细节保留的差异:

import cv2img = cv2.imread('1.jpeg')# 均值滤波
mean_blur = cv2.blur(img, ksize=(7, 7))# 高斯滤波
gauss_blur = cv2.GaussianBlur(img, ksize=(7, 7), sigmaX=1.5)cv2.imshow('Original', img)
cv2.imshow('Mean Blur', mean_blur)
cv2.imshow('Gaussian Blur', gauss_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('mean_blur.jpg', mean_blur)
cv2.imwrite('gauss_blur.jpg', gauss_blur)

输出结果

关键代码解析:

  • cv2.blur(src, ksize):均值滤波,对每个像素周围 ksize 窗口内取均值,简单快速但边缘模糊
  • cv2.GaussianBlur(src, ksize, sigmaX):高斯滤波,ksize 必须为奇数,sigmaX 控制高斯分布宽度,可设 0OpenCV 自行计算
  • 在边界处理 (borderType) 上,OpenCV 支持多种模式(如 BORDER_REPLICATE, BORDER_REFLECT 等),可根据噪声类型与目标应用选择最优策略,避免边缘伪影

1.3 拉普拉斯滤波

拉普拉斯滤波用于边缘检测,它通过强调图像的高频成分来突出边缘。通常使用类似于下列的滤波器:
H = [ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] H= \begin{bmatrix} 0 & -1 &0 \\ -1 & 4 &-1 \\0 & -1 &0\end{bmatrix} \quad H= 010141010
拉普拉斯滤波可以帮助突出图像中的边缘细节。

1.4 Sobel 滤波

Sobel 滤波器是一种用于边缘检测的滤波器,通过计算图像中水平方向和垂直方向的梯度来检测边缘。Sobel 滤波器有两个常见版本,一个用于检测水平方向的边缘,另一个用于检测垂直方向的边缘。
水平边缘检测:
H x = [ − 1 0 1 − 2 0 2 − 1 0 1 ] H_x= \begin{bmatrix} -1 & 0 &1 \\ -2 & 0 &2 \\-1 & 0 &1\end{bmatrix} \quad Hx= 121000121
垂直边缘检测:
H y = [ − 1 − 2 − 1 0 0 0 1 2 1 ] H_y= \begin{bmatrix} -1 & -2 &-1 \\0 & 0 &0 \\1 & 2 &1\end{bmatrix} \quad Hy= 101202101

2. 非线性滤波

非线性滤波在图像处理中的应用非常重要,尤其是在去噪、边缘检测以及增强图像细节方面。与线性滤波不同,非线性滤波不会简单地对邻域像素进行加权平均,而是通过其他方式来选择或修改像素值,这使得非线性滤波能够有效地处理一些特定的问题,比如去除椒盐噪声、保留边缘等。常见的非线性滤波方法包括:

  • 中值滤波:是最常见的非线性滤波方法,主要通过将每个像素的值替换为其邻域内所有像素值的中位数来进行图像去噪

    • 应用:特别适合去除椒盐噪声,中值滤波能够有效去除噪声的同时,保持图像的边缘信息
  • 双边滤波:是一种结合空间距离和像素值相似度的非线性滤波方法,它不仅考虑像素的空间位置,还考虑像素的灰度差异,从而保留边缘信息,同时平滑图像

    • 应用:用于去噪的同时保留图像的边缘和细节,特别是在面部图像处理和医学图像处理中使用较多
    • 主要参数包括:d (邻域直径)、sigmaColor (灰度空间标准差)与 sigmaSpace (坐标空间标准差);合理配置可在去噪和边缘保留之间取得平衡
  • 自适应滤波:根据图像局部区域的统计特性动态调整滤波器的参数,自适应滤波器能够在不同的图像区域使用不同的滤波强度。

    • 应用:用于处理具有不均匀噪声的图像
  • 最大值和最小值滤波:

    • 最大值滤波:将每个像素的值替换为邻域内的最大值,通常用于增强图像中明亮的部分
    • 最小值滤波:将每个像素的值替换为邻域内的最小值,通常用于保留阴影部分的细节
    • 应用:适用于特定区域的增强,如边缘检测或提取暗部/亮部特征

接下来,分别调用 cv2.medianBlur(ksize=5)cv2.bilateralFilter(d=9, sigmaColor=75, sigmaSpace=75) 观察对椒盐噪声和细节的不同处理效果:

import cv2img = cv2.imread('1.jpeg')# 中值滤波
median = cv2.medianBlur(img, ksize=5)# 双边滤波
bilateral = cv2.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)cv2.imshow('Median Blur', median)
cv2.imshow('Bilateral Filter', bilateral)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('median_blur.jpg', median)
cv2.imwrite('bilateral.jpg', bilateral)

输出结果
关键代码解析:

  • cv2.medianBlur(src, ksize):对 ksize×ksize 邻域内像素排序并取中值,ksize 必须为奇数
  • cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace):对每个像素计算空间和灰度两个高斯权重加权平均,d≤0 时由 sigmaSpace 推断

3. 自定义卷积核

使用 cv2.filter2 能够自定义任意卷积核,可实现锐化、边缘检测、浮雕、模糊等任意线性滤波效果。
自定义内核时需关注:归一化(核元素之和 ≠1 时可能导致图像亮度漂移)、锚点( anchor 决定核中心对应位置)、深度 (ddepth 决定输出图像的数据类型)、边界模式 (borderType 控制边缘像素如何卷积)。
常用锐化核示例:
H = [ 0 − 1 0 − 1 5 − 1 0 − 1 0 ] H= \begin{bmatrix} 0 & -1 &0 \\-1 & 5 &-1 \\ 0 & -1 &0\end{bmatrix} \quad H= 010151010
可在保留整体亮度的同时强化细节;Sobel 核则用于水平边缘检测,配合 cv2.convertScaleAbs 处理负值。
接下来,定义 2 种核,包括锐化核、Sobel X 核,并分别调用 cv2.filter2D

import cv2
import numpy as npimg = cv2.imread('1.jpeg')# 定义卷积核
sharpen = np.array([[0, -1,  0],[-1, 5, -1],[0, -1,  0]], dtype=np.float32)
sobel_x = np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]], dtype=np.float32)# 应用 filter2D
out_sharpen  = cv2.filter2D(img, ddepth=-1, kernel=sharpen)
out_sobel    = cv2.filter2D(img, ddepth=cv2.CV_16S, kernel=sobel_x)
out_sobel    = cv2.convertScaleAbs(out_sobel)  # 转回 8-bitcv2.imshow('Sharpen', out_sharpen)
cv2.imshow('Sobel X', out_sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('out_sharpen.jpg', out_sharpen)
cv2.imwrite('out_sobel.jpg', out_sobel)

输出结果
关键代码解析:

  • cv2.filter2D(src, ddepth, kernel, anchor=None, delta=0, borderType=cv2.BORDER_DEFAULT):对 src 与自定义 kernel 做二维卷积,ddepth=-1 表示输出与输入同类型;delta 可用于调整偏移
  • cv2.convertScaleAbs(src, alpha=1, beta=0):将带符号卷积结果(如 Sobel )映射到无符号 8-bit,并可通过 alphabeta 调整对比度与亮度

小结

在本节中,我们从线性滤波(均值/高斯)的原理与参数调优入手,紧接着以非线性滤波(中值/双边)为重点,探讨了它们在各自噪声模型下的卓越表现与局限,最后,通过自定义卷积核实践,介绍如何使用 cv2.filter2D 实现锐化、边缘检测等多样效果。

系列链接

OpenCV计算机视觉实战(1)——计算机视觉简介
OpenCV计算机视觉实战(2)——环境搭建与OpenCV简介
OpenCV计算机视觉实战(3)——计算机图像处理基础
OpenCV计算机视觉实战(4)——计算机视觉核心技术全解析
OpenCV计算机视觉实战(5)——图像基础操作全解析
OpenCV计算机视觉实战(6)——经典计算机视觉算法
OpenCV计算机视觉实战(7)——色彩空间详解

相关文章:

OpenCV计算机视觉实战(8)——图像滤波详解

OpenCV计算机视觉实战(8)——图像滤波详解 0. 前言1. 线性滤波1.1 均值滤波1.2 高斯滤波1.3 拉普拉斯滤波1.4 Sobel 滤波 2. 非线性滤波3. 自定义卷积核小结系列链接 0. 前言 在本文中,我们将深入探索线性与非线性滤波的算法原理、性能优化及…...

Docker 前端镜像容器部署指南

1. 编写 Dockerfile 文件 # 使用轻量级的 Nginx Alpine 作为基础镜像 FROM nginx:alpine# 设置工作目录 WORKDIR /usr/share/nginx/html# 删除默认的 Nginx 静态文件 RUN rm -rf ./*# 复制本地 dist 目录下的文件到容器中 COPY ./dist /usr/share/nginx/html# 暴露容器端口 EX…...

OpenAI大模型不听人类指令事件的技术分析与安全影响

OpenAI大模型不听人类指令事件的技术分析与安全影响 OpenAI大模型o3确实存在不遵从人类关闭指令的现象,这一行为已被第三方安全机构验证,但其本质是技术缺陷而非AI意识觉醒。帕利塞德研究所的测试显示,在100次实验中o3有7次成功绕过关闭指令…...

图神经网络实战——图的可视化

图神经网络实战——图的可视化 0. 前言1. networkx2. Gephi相关链接0. 前言 图结构可通过图形化方式直观呈现。节点通常用圆形表示,边则用连接线表示。 然而当节点和边数量增加时,绘制清晰的图形表示可能会变得相当困难,这主要源于节点在二维坐标系中的布局问题。对于包含数…...

自动化安全脚本学习

1.目录扫描器 目标:使用python编写一个自动化目录扫描工具,实现简单信息收集,判断目标网站是否存在常见路径。 import requests #用于发HTTP请求 from concurrent.futures import ThreadPoolExecutor #实现多线程扫描# 扫描目标 target h…...

github公开项目爬取

import requestsdef search_github_repositories(keyword, tokenNone, languageNone, max_results1000):"""通过 GitHub API 搜索仓库,支持分页获取所有结果(最多 1000 条):param keyword: 搜索关键词:param token: GitHub To…...

用豆包写单元测试

用豆包写单元测试, 输入 vue 模板内容,输入 参考vue模板内容写一个单元测试要求用jest.mock实现构造完成,修复bug。npm run test:unit – tests/unit/views/xxx/xxx.spec.js看下 % Stmts 语句覆盖率:执行到的代码语句占总语句的比…...

传输层协议TCP(上)

上一篇https://blog.csdn.net/Small_entreprene/article/details/148143494?fromshareblogdetail&sharetypeblogdetail&sharerId148143494&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link 上文学习了传输层的协议之一UDP,接下来…...

Windows下安装并使用kubectl查看K8S日志

【1】安装kubectl 官网文档:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后得到 kubectl.exe,放到一个目录下,然后配置环境变量。 此时CMD 进入DOS命令窗口 kubectl version【2】配置config文件 其实就是…...

Hive 分区详解:从基础概念到实战应用

一、为什么要分区? 1.将大规模数据按规则(如时间、地域)划分到不同目录,提升数据组织性。 2.通过分区过滤,减少扫描数据量,显著提升查询效率。 3.不同分区可对应不同业务线或权限,增强数据隔…...

Android studio进阶开发(六)--如何用真机通过okhttp连接服务器

我们学过了如何通过okhttp查询网络上已经发布的网页,但我们还需要在做全栈时保证前后端能够交互。 前要课程 okhttp的使用 真机端口连接 安全认证 由于http的安全性较差,在没有安全协议的情况下,使用自己的后端连接会报错,所以…...

如何解决网站服务器的异常问题?

当网站服务器出现异常情况,导致用户无法正常访问网页信息的时候,该如何解决这一问题呢?小编下面就带领大家共同探讨一下这一问题。 企业在面对网站服务器异常时,首先要对服务器硬件设备进行详细的检查,可以使用硬盘检测…...

WeakAuras Lua Script [ICC BOSS 11 - Sindragosa]

WeakAuras Lua Script [ICC BOSS 11 - Sindragosa] 冰冠堡垒Icecrown Citadel 冰龙 辛达苟萨(寒冰信标插件) 左 (绿,黄) 中(蓝,紫) 右(白,橙) lua script&…...

用户界面禁忌——基础原则

文章目录 基本原则1:关注用户及其任务,而不是技术基本原则2:首先考虑功能,然后才是表示基本原则3:与用户对任务的看法保持一致基本原则4:设计要符合常见情况基本原则5:不要分散用户对他们目标的…...

电脑开机后出现bootmgr is conmpressed原因及解决方法

最近有网友问我为什么我电脑开机后出现BOOTMGR is compressed,这个提示意思是:意思是启动管理器被压缩了,即使重启也无法正常进入系统。原因有很多,大部分是引导出现问题,或选错了启动硬盘所导致的,下面我们来详细分析…...

vite配置一个css插件

vite.config.js的plugins执行函数 该例子只是替换一些css,具体内容不重要,主要看形参的运用 // vite-plugin-css.js export default function cssPlugin() {return {name: vite-plugin-css-post, // 插件的名字,Vite 插件必须有名字enforce: post, // 设定插件执…...

React+Taro 微信小程序做一个页面,背景图需贴手机屏幕最上边覆盖展示

话不多说 直接上图 第一步 import { getSystemInfoSync } from tarojs/taro;第二步 render() {const cardBanner getImageUrlByGlobal(member-merge-bg.png);const { safeArea, statusBarHeight } getSystemInfoSync();const NAV_BAR_HEIGHT 44;const navBarHeight NAV…...

Spring框架学习day4--Spring集成Mybatis(IOC)

Spring集成Mybatis1.添加jar包(pom.xml)2.配置sqlSessionFactiory(spring.xml)3.再service类中注入Dao代理接口4.测试类5文件结构 Spring集成Mybatis Spring集成Mybatis其核心是将SqlSessionFactory交由Spring管理,并由 Spring管理…...

太阳系运行模拟程序-html动画

太阳系运行模拟程序-html动画 by AI: <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>交互式太阳系…...

【C++ Qt】容器类(GroupBox、TabWidget)内附思维导图 通俗易懂

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” ✍️绪论​&#xff1a; 本章主要介绍了 Qt 中 QGroupBox 与 QTabWidget 控件。QGroupBox 是带标题的分组框&#xff0c;能容纳其他控件&#xff0c;有标题、对齐方式、是否…...

SOC-ESP32S3部分:18-串口

飞书文档https://x509p6c8to.feishu.cn/wiki/NqrMw6X8Si6sSqkyPbxcFRxGnid UART全称是通用异步接收器/发送器&#xff0c;ESP32-S3 芯片有 3 个 UART 控制器。每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。 串口文档参考&#xf…...

CSS 样式表的四种应用方式及css注释的应用小结

CSS样式表的四种应用方式及注释应用小结 一、样式表应用方式 内联样式&#xff08;行内样式&#xff09; <div style"color: #ff0000; font-size: 16px;">示例文本</div>特点&#xff1a;直接写在HTML标签的style属性中优先级&#xff1a;最高&#xff…...

五、web安全--XSS漏洞(2)--XSS相关payload

XSS 主要是针对网页客户端的一种攻击&#xff0c;那么就要执行 JavaScript 代码&#xff0c;那么无疑需要用到 JavaScript 语言以及在 HTML 中可以解析 JavaScript 代码的标签。 1、标签类 &#xff08;1&#xff09;script <script></script>标签是最直接的 xS…...

AI架构师的新工具箱:ChatGPT、Copilot、AutoML、模型服务平台

AI架构师不仅要懂架构、懂AI服务,还需要具备使用AI工具提升工作效率的能力。新一代AI工具已经成为架构师不可或缺的“工具箱”,帮助他们更高效地进行设计、部署、编码与优化。 以下介绍几类代表性工具,并说明它们在实际架构工作中的应用场景。 一、ChatGPT:生成架构设计文…...

关于智能体接入后端,在Apifox能够传参数给智能体的测试

from flask import Flask, request, jsonify, render_template import requests import json # 用于解析嵌套的 JSON 字符串app Flask(__name__)COZE_BOT_ID 7508736911423963162 COZE_API_KEY pat_cHXqrFzcvtktfmmlp4pjF3O2qmjioQW46uU8UNbUugyvSlFZclklpunc53DbR8ws COZE…...

有铜半孔工艺的制造难点与工艺优化

技术难点剖析 有铜半孔工艺在制造过程中面临多重挑战&#xff0c;主要集中在材料加工精度、孔壁完整性及良率控制三个方面&#xff1a; 铜层翘起与毛刺残留 半孔成型时&#xff0c;铣刀高速切割可能导致孔壁铜层被拉扯&#xff0c;产生翘起或残留铜屑&#xff0c;影响导电性能…...

python分步合并处理excel数据

文章目录 概要整体架构流程技术名词解释技术细节小结概要 客户需求 1. 背景与目标 用户需要将三个包含农业实验数据的Excel表格(AK、AN、AP)合并为一个结构化数据集,用于后续分析。每个表格包含相同类型的字段(如对照组与PSB处理组的样本数、均值、标准差),但需通过字…...

MC0309魔法项链

思路&#xff1a; 以数位贡献的思路来写这题&#xff0c; 统计每一位上为 1 的个数&#xff1a; 对于第 k 位&#xff0c;统计有多少个数在这一位上为 1&#xff0c;记作 cnts[k] 枚举每个数&#xff0c;逐位分析它对整体的贡献&#xff08;即与其它数交互时的和&#xff09;…...

为 Ubuntu 安装的软件创建桌面图标

如何为 Ubuntu 安装的软件创建桌面图标&#xff08;.desktop 启动器&#xff09; 在 Ubuntu 或其他 Linux 发行版中&#xff0c;我们常常通过压缩包&#xff08;如 .tar.gz&#xff09;或官方二进制方式安装软件。这种安装方式虽然灵活方便&#xff0c;但默认并不会将软件添加…...

uni-app 中开发问题汇总

uni-app 中 echarts 中的点击事件失效&#xff1f; 在 main.js 中 设置 window.wx{}&#xff0c;这个方式&#xff0c;如果需要调 wx 中的方法会失效&#xff08;如果默认后续不会调 wx 中的方法推荐使用&#xff09; 降低版本&#xff0c;安装一个低版本的&#xff0c;比如&a…...