opencv图像处理之常见滤波器
图像平滑
Smoothing, also called blurring, is a simple and frequently used image processing operation.
平滑,也叫模糊.

本质就是把某点的像素值转换为其及其周围像素值的不同权重的叠加.h(k,l)即为卷积核,或者叫滤波器filter.
有几种常见的filter
- Normalized Box Filter
- Gaussian Filter
- Median Filter
- Bilateral Filter
均值滤波

权重矩阵如上.
img2= cv2.blur(img,(5,5))
The call blur(src, dst, ksize, anchor, borderType) is equivalent to boxFilter(src, dst, src.type(), anchor, true, borderType).
https://docs.opencv.org/master/d4/d86/group__imgproc__filter.html#ga8c45db9afe636703801b0b2e440fce37
效果如下:

高斯滤波
即假设某一位置的像素和其邻域像素符合高斯分布.具体的说的话,就是每一位置的像素的权重符合高斯分布.这样的话,给定一个高斯分布,及高斯核的大小,则可以计算出周边n个像素的权重值.

上图展示了一维度的高斯分布图和二维高斯分布的公式. 图像是2维度的.(即行维度和列维度确定一个像素点的位置).
高斯滤波的具体计算过程.可以参考https://blog.csdn.net/zr459927180/article/details/52400641
opencv中获取高斯核心的函数为getGaussianKernel,但是这个获取的一维的高斯核.对图像来说,以3*3邻域而言,我们应该得到一个3*3的权重矩阵.可以如下得到:
kernal_x = cv2.getGaussianKernel(3,-1)
kernal_y = cv2.getGaussianKernel(3,-1)
kernal_filter = np.dot(kernal_x,kernal_y.T)
print(kernal_filter)
输出如下:
[[0.0625 0.125 0.0625]
[0.125 0.25 0.125 ]
[0.0625 0.125 0.0625]]
则中间元素的亮度值经高斯转换后为0.0625 x p(0,0) + 0.125 x p(0,1) + .... + 0.0625 x p(2,2),可以看到权重矩阵相加等于1.
这里,我们举例用了3 x 3的高斯核,实际上并不限定高斯核一定要是正方形.
回到cv的GaussianBlur(),

其参数sigmaX,sigmaY即x,y方向上的高斯分布的标准差.这样就可以求得不同方向上的高斯矩阵,再做矩阵乘法,即得到m x n的权重矩阵.进而求得高斯转换后的图像.
我们知道高斯分布(也叫正态分布)的特点为,标准差越大,分布越分散,标准差越小,分布越集中.所以调大GaussianBlur()中的sigmaX,sigmaY将使得图像中的每个像素更多地参考周边像素,即更为平滑或者说模糊.
参见下图:(这张图选的不好,高斯模糊效果不明显,但还是可以看出图3更模糊一些)

import cv2
import numpy as np
def test():
imgname = "/home/sc/opencv-3.4.3/samples/data/lena.jpg"
img = cv2.imread(imgname)
img2 = img.copy()
#img2 = cv2.blur(img,(5,5))
img2 = cv2.GaussianBlur(img,(5,7),1)
img3 = cv2.GaussianBlur(img,(5,7),100)
kernal_x = cv2.getGaussianKernel(3,0)
kernal_y = cv2.getGaussianKernel(3,0)
kernal_filter = np.dot(kernal_x,kernal_y.T)
print(kernal_filter)
kernal_x = cv2.getGaussianKernel(3,5)
kernal_y = cv2.getGaussianKernel(3,5)
kernal_filter = np.dot(kernal_x,kernal_y.T)
print(kernal_filter)
#return
cv2.imshow("origin",img)
cv2.imshow("dst",img2)
cv2.imshow("dst3",img3)
k=cv2.waitKey()
if k == 27:
cv2.destroyAllWindows()
test()

从getGaussianKernel()的输出可以明显地看出来,标准差调大时,权重矩阵的变换.
中值滤波
即把像素值变为邻域像素值的中位数.

注意,kernal的大小必须为奇数.
import cv2
def test():
imgname = "/home/sc/opencv-3.4.3/samples/data/lena.jpg"
img = cv2.imread(imgname)
dst = cv2.medianBlur(img, 1)
dst2 = cv2.medianBlur(img, 11)
cv2.imshow("origin",img)
cv2.imshow("dst",dst)
cv2.imshow("dst2",dst2)
k=cv2.waitKey()
if k == 27:
cv2.destroyAllWindows()
test()

双边滤波

双边滤波函数是 cv2.bilateralFilter() ,双边滤波能在保持边界清晰的情况下有效的去除噪音。但是这种操作与其他滤波器相比会比较慢.我们已经知道高斯滤波器是求中心点邻近区域像素的高斯加权平均值。这种高斯滤波器只考虑像素之间的空间关系,而不会考虑像素值之间的关系(像素的相似度)。所以这种方法不会考虑一个像素是否位于边界。因此边界也会被模糊掉,而这不是我们想要的。
双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重。空间高斯函数确保只有邻近区域的像素对中心点有影响,灰度值相似性高斯函数确保只有与中心像素灰度值相近的才会被用来做模糊运算。所以这种方法会确保边界不会被模糊掉,因为边界处的灰度值变化比较大.
简单滴说就是,在生成周边像素的权重矩阵时,如果发现旁边的像素值和当前的像素值差异很大,就只给差异很大的那个元素分配很小的权重,这样"大的突变差异就被保留了".
双边滤波的原理可以参考:https://blog.csdn.net/shenziheng1/article/details/50838970
dst = cv2.bilateralFilter(img, 9, 75, 75)
效果图:

可以看到纹理被模糊掉了,但是边界还是很好地保留了.
参考:参考:<https://docs.opencv.org/master/dc/dd3/tutorial_gausian_median_blur_bilateral_filter.html >
https://blog.csdn.net/shenziheng1/article/details/50838970
https://blog.csdn.net/GiffordY/article/details/91891920
opencv图像处理之常见滤波器的更多相关文章
- OpenCV图像处理篇之边缘检测算子
OpenCV图像处理篇之边缘检测算子 转载: http://xiahouzuoxin.github.io/notes/ 3种边缘检测算子 一阶导数的梯度算子 高斯拉普拉斯算子 Canny算子 Open ...
- Python+OpenCV图像处理(一)
Python+OpenCV图像处理(一): 读取,写入和展示图片 调用摄像头拍照 调用摄像头录制视频 1. 读取.写入和展示图片 图像读入:cv2.imread() 使用函数cv2.imread() ...
- Python+OpenCV图像处理(一)——读取显示一张图片
先在此处先声明,后面学习python+opencv图像处理时均参考这位博主的博文https://blog.csdn.net/u011321546/article/category/7495016/2? ...
- 1.5快速上手OpenCV图像处理
在上一节中,已经完成了OPENCV的配置,在本节接触几个Opencv图像处理相关的程序,看看opencv用简洁的代码能够实现哪些有趣的图像效果. 1.第一个程序:图像显示 #include<op ...
- 《OpenCV图像处理编程实例》
<OpenCV图像处理编程实例>例程复现 随书代码下载:http://www.broadview.com.cn/28573 总结+遇到的issue解决: 第一章 初识OpenCV 1.VS ...
- OpenCV图像处理学习笔记-Day1
OpenCV图像处理学习笔记-Day1 目录 OpenCV图像处理学习笔记-Day1 第1课:图像读入.显示和保存 1. 读入图像 2. 显示图像 3. 保存图像 第2课:图像处理入门基础 1. 基本 ...
- OpenCV图像处理学习笔记-Day03
OpenCV图像处理学习笔记-Day03 目录 OpenCV图像处理学习笔记-Day03 第31课:Canny边缘检测原理 第32课:Canny函数及使用 第33课:图像金字塔-理论基础 第34课:p ...
- OpenCV图像处理学习笔记-Day4(完结)
OpenCV图像处理学习笔记-Day4(完结) 第41课:使用OpenCV统计直方图 第42课:绘制OpenCV统计直方图 pass 第43课:使用掩膜的直方图 第44课:掩膜原理及演示 第45课:直 ...
- 基于PI+QT实现OpenCV图像处理操作(基本环境搭建)
这篇博客就是在PI上直接写出来的!cheers!! PI3的性能已经非常强劲,而作为一个能够独立运行的运算单元,使用它来做图像处理,将是非常适合的.为了挖掘机器的最大潜能,我没有采用比较常见的pyth ...
随机推荐
- 学习笔记之Java队列Queue中offer/add函数,poll/remove函数,peek/element函数的区别
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作. LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用. Java中Que ...
- javascript JS CryptoJS DES加解密CBC模式与C#DES加解密相同互通
我们只知道不同的语言解密要相互通用,就需要遵循相同的加密方式,然而在具体做技术预研的时候,就发现会遇到很多问题,网上找的资料也是比较片面,所以我踩了坑,并且把解决方案和相关资料源码提供出来,给需要的朋 ...
- HDU 1045 Fire Net 二分图建图
HDU 1045 题意: 在一个n*n地图中,有许多可以挡住子弹的墙,问最多可以放几个炮台,使得炮台不会相互损害.炮台会向四面发射子弹. 思路: 把行列分开做,先处理行,把同一行中相互联通的点缩成一个 ...
- CF995B Suit and Tie 贪心 第十三
Suit and Tie time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- yzoj P1122 阶乘 题解
T组数据,给出N,求出N!最右边非零的数. 对于30%的数据,N <= 30,T<=10. 对于全部的数据,N <= 10^2009,T<=30. 一道数学题 解析 N!/(1 ...
- Java服务器-Disruptor使用注意
最近看了一下部署游戏后台的服务器状况,发现我的一个Java程序其占用的CPU时长超过100%,排查后发现竟是Disruptor引起的,让我们来看看究竟为什么Disruptor会有这样的表现. 发现占用 ...
- Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.catalina.connector.CoyoteWriter and no properties discovered to create BeanSerializer
一.什么是序列化In computer science, in the context of data storage, serialization is the process of transla ...
- Spring.Net是怎么在MVC中实现注入的(原理)
本文将介绍Spring.Net(不仅仅是Spring.Net,其实所有的IoC容器要向控制器中进行注入,原理都是差不多的)在MVC控制器中依赖注入的实现原理,本文并没有关于在MVC使用Spring怎么 ...
- Webpack安装配置及打包详细过程
引言 前端经过漫长的发展,涌现出了很多实践方法来处理复杂的工作流程,让开发变得更加简便,其中,模块化可以使复杂的程序细化成为各个小的文件,而webpack并不强制你使用某种模块化方案,而是通过兼容所有 ...
- Nginx使用GeoIP模块来限制地区访问
举例比如限制泰国地区的IP访问: 前提条件,安装了http geoip 或stream geoip模块的Nginx Plus或者开源nginx Maxmind的GeoLite Legacy数据库 1. ...