OpenCV_7 滤波

前言

本节简单介绍滤波的概念和OpenCV中主要的滤波API,不涉及相关算法。


一、滤波

1.什么是滤波?

一幅图像通过滤波器得到另一幅图像,同时在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像处理中不可缺少的一项操作。其中滤波器又被称为卷积核,滤波过程被称为卷积。下面这幅图就是一幅图卷积前后的对比,明显变得锐化。

在这里插入图片描述


下面的图片是一个简化的卷积过程:采用一个3x3的卷积核,与图片中的3x3的数据相乘,然后遍历整张图像。经过卷积后图片的尺寸必定会减小(卷积核>1),如想保持原来的大小,要进行对应的处理。

在这里插入图片描述

2.卷积的基本概念

  • 卷积核的大小:

卷积核一般为奇数,3x3, 5x5, 7x7;一方面是增加padding的原因,另一方面是为了保证锚点在中间,防止位置发生偏移

卷积核大小的影响:在深度学习中,卷积核越大,看到的信息(感受野)越多,提取的特征越好,但同时计算量也就越大。

  • 锚点:
    如下图中中心41就称为锚点,简单来说就是正中心,主要为了防止信息偏差。

    在这里插入图片描述

  • 边界扩充:
    边界扩充就是为了解决卷积之后,输出尺寸变小的问题。

    在这里插入图片描述


    计算公式:
    N = ( W − F + 2 P ) / S + 1 N = (W-F+2P)/S+1 N=(WF+2P)/S+1
    N:输出图像大小
    W:源图像大小;F:卷积核大小;P:扩充尺寸
    S:步长大小

  • 步长:卷积核每次移动的长度

低通滤波可以去除噪声或平滑图像
高通滤波可以帮助查找图像的边缘


二、图像卷积

1.图像卷积API

filter2D()
声明:void filter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ddepth:图像卷积之后的位深,-1表示与原图一致
   kernel:卷积核
   anchor:锚点,默认中心点
   delta:每次卷积之后+delta
   borderType:边界的类型

代码案例:

import cv2
import numpy as np 

cat = cv2.imread('./picture/cat.jpg')

kernel = np.ones((5,5), np.float32) / 25 # 平均滤波

dst = cv2.filter2D(cat, -1, kernel)

cv2.imshow('dst', dst)
cv2.imshow('cat', cat)
cv2.waitKey(0)

2.方盒滤波与均值滤波

方盒滤波卷积核:

在这里插入图片描述

参数a的作用:
normalize = true, a= 1 / W x H (平均滤波)
normalize = false, a= 1

boxFilter()
声明:void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ddepth:图像卷积之后的位深,-1表示与原图一致
   ksize:卷积核大小
   anchor:锚点,默认中心点
   normalize:如上
   borderType:边界的类型

blur()
声明:void blur( InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ksize:卷积核大小
   anchor:锚点,默认中心点
   borderType:边界的类型

3.高斯滤波

高通滤波可以帮助查找图像的边缘

在这里插入图片描述


高斯权重:

在这里插入图片描述


从上面两图可以看出,高斯滤波呈现出中间权重高,边缘权重低。

GaussianBlur()
声明:void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ksize:卷积核大小,
   sigmaX:X方向上的高斯核标准差
   sigmaY:Y方向上的高斯核标准差
       如果两个sigma都为零,则根据ksize计算

代码案例:

dst = cv2.GaussianBlur(cat, (5, 5), sigmaX = 1)

主要用来解决高斯噪音。

4.中值滤波

中值滤波对胡椒噪音效果明显

medianBlur()
声明:void medianBlur( InputArray src, OutputArray dst, int ksize );
参数:
   src:需要滤波的图像
   ksize:卷积核大小,整数
代码示例:

dst = cv2.medianBlur(hujiao, 7)

结果展示:

请添加图片描述


经过中值滤波后图像中的黑色噪点去掉了,但是图片的边缘也变得模糊了。

5.双边滤波

可以保留边缘,同时可以对边缘内的区域进行平滑处理。主要的作用是进行美颜。
双边滤波原理:

在这里插入图片描述

bilateralFilter()
声明:void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   d:滤波期间使用的每个像素邻域的直径。如果为非正,它是从sigmaSpace计算的。
   sigmaColor:
   sigmaSpace:

代码案例:

dst = cv2.bilateralFilter(lian, 7, 20, 50)

结果展示:

请添加图片描述


可以明显看出经过滤波后的图片脸部皮肤更光滑,肤色更均匀,同时眉毛,帽子的边缘并没有模糊化。

三、高通滤波

1.Sobel(索贝尔)(高斯)

内部使用高斯滤波首先对图像进行滤波,然后才进行一阶导提取图像边缘,因此对噪音适应性很强。
Sobel和下面的Scharr求边缘线是都只能求一个方向上的边缘,最终要将横轴与纵轴的边缘相加,才能得到完整的边缘图像。

Sobel()
声明:void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ddepth:位深
   dx:等于1,检测Y轴边缘
   dy:等于1,检测X 轴边缘
   ksize:卷积核大小
   scale:缩放

代码案例:

d1 = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize = 5)
d2 = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize = 5)
d = cv2.add(d1, d2)

2.Scharr(沙尔)

Scharr不可以改变大小,他是一个3x3的卷积核,当Sobel的ksize参数设为-1时,就是Scharr。但Scharr可以检测出更细的边缘线。

Sobel()
声明:void Scharr( InputArray src, OutputArray dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ddepth:位深
   dx:等于1,检测Y轴边缘
   dy:等于1,检测X 轴边缘

3.Laplacian(拉普拉斯)

Laplacian可以一次求出图像的完整边缘,但由于内部没有进行降噪,因此对噪声敏感。

Sobel()
声明:void Laplacian( InputArray src, OutputArray dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
参数:
   src:需要滤波的图像
   ddepth:位深
   ksize:卷积核大小

4.Canny

Canny效果好的原因:

  • 使用5x5高斯滤波消除噪声
  • 计算图像梯度方向(0°/45°/90°/135°)
  • 取局部极大值
  • 阈值计算
       当值大于maxval是一定是边缘,小于minval时一定不是边缘,而当处于maxval和minval之间则需要看与之前的边缘是否连续,不连续就不是边缘。

    在这里插入图片描述

Canny()
声明:void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false );
参数:
   image:需要滤波的图像
   threshold1:阈值下限
   threshold2:阈值上限

代码案例:

import cv2
import numpy as np 

img = cv2.imread('./picture/lian.jpeg')
fimg = cv2.GaussianBlur(img, (5, 5), sigmaX = 1)

dst1 = cv2.Laplacian(fimg, cv2.CV_64F)
dst2 = cv2.Canny(img, 50, 150)

cv2.imshow('img', img)
cv2.imshow('Laplacian', dst1)
cv2.imshow('Canny', dst2)
cv2.waitKey(0)

结果展示:

请添加图片描述


上图可以看出:即使Laplacian方法经过滤波处理,但Canny方法的边缘提取效果仍然要好得多。


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340