OpenCV_7 滤波

本文介绍了图像滤波的基本概念,包括卷积、滤波器和锚点等,并详细讲解了OpenCV中的图像卷积API,如filter2D、boxFilter、blur、GaussianBlur、medianBlur和bilateralFilter。此外,还探讨了高通滤波,如Sobel、Scharr、Laplacian和Canny边缘检测方法,展示了它们在图像处理中的应用和效果。
摘要由CSDN通过智能技术生成

前言

本节简单介绍滤波的概念和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方法的边缘提取效果仍然要好得多。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值