目录
图像处理滤波是什么?
图像滤波分类
线性滤波
(以模糊图像为目的)
均值滤波
高斯滤波
(以增强图像为目的)
拉普拉斯
sobel
prewitt滤波
(其它,提取其它特征为目的)
各异向性滤波
非线性滤波
中值滤波
最大值、最小值滤波
双边滤波
模板匹配
本文说的图像都是在空域,且为正常的2D图像;特殊类型的图像可以灵活拓展;
设源图像为:
设滤波之后的图像为:
滤波函数(通常用滤波器的形式或者是一般函数的形式来表示);
则,滤波操作可定义为;
通俗来说就是,源图像的像素值经过滤波函数运算得到滤波之后的图像;滤波函数的自变量就是对应位置像素和其邻域的像素值;影响范围多大也就是邻域多大,由n决定;滤波计算多复杂以及得到什么效果由滤波函数决定;
这里要说明的是邻域的定义很广泛,可以是相邻像素、圆形、矩形或者不规则形状等等;
由滤波的描述可以看出,图像本身和像素邻域都不容易变化,真正变化的是滤波函数F,所以根据滤波函数F的不同,可以将图像滤波分为线性滤波和非线性滤波;
线性滤波,就是滤波函数为线性函数;
非线性滤波,就是滤波函数为非线性函数;
线性滤波主要是基于滤波器的滤波,有一些常用的滤波器,还有少量自定义滤波器;其它的线性函数也可以用在实际计算中,通常是为了得到比较复杂的滤波效果;
常用滤波器根据滤波的目的,可以分为模糊图像细节和增强图像细节两类;还有一些特殊功能的滤波器;
目标像素以及邻域像素值的平均值;用于图像模糊,去噪;
均值滤波器一般为方形,半径为3,5,7的单数;当然也有圆形、椭圆形的均值滤波;下面是opencv方形均值滤波的例子;
opencv实现(cv.boxfilte可以达到相同的效果):
import cv2 as cv
import numpy as np
img = cv.imread('img.png')
blur = cv.blur(img,(5,5))
cv.imshow("oriimg",img)
cv.imshow("blurimg",blur)
cv.waitKey(0)
高斯滤波器把目标像素作为二维高斯函数的中心,然后邻域赋予相应的高斯函数的值,从而生成高斯滤波器;使用高斯滤波器对图像进行滤波即为高斯滤波;参数为邻域大小和,高斯函数的方差,方差越大,越接近均值滤波,方差越小越接近原图像素值;用于图像模糊,去噪;
opencv实现:
blur = cv.GaussianBlur(img,(5,5),0)
拉普拉斯滤波器中心的值等于所有其它邻域值的和的负数,典型的就是下面这样;是四个方向的,可以对图像的边缘进行增强,突出小的区域;
0 1 0
1 -4 1
0 1 0
opencv实现:
laplacian = cv.Laplacian(img,cv.CV_64F)
分为x方向、y方向和两个方向相加,具体的滤波器长这样:
水平x方向:
-1 | 0 | 1 |
-2 | 0 | 2 |
-1 | 0 | 1 |
垂直y方向:
-1 | -2 | -1 |
0 | 0 | 0 |
1 | 2 | 1 |
或者水平与垂直相加,也可以近似为: 。;
opencv实现:
sobelx = cv.Sobel(img,cv.CV_64F,1,0,ksize=5)
sobely = cv.Sobel(img,cv.CV_64F,0,1,ksize=5)
滤波器长这样,也是为了边缘增强;
简单来说就是判断以该点为起点哪个方向上的差异最小就赋予与该方向接近的值;可以筛选出图像中的小线段,去掉噪点;自己实现了一个如下:
https://blog.csdn.net/h649070/article/details/118550051
非线性滤波即滤波函数为非线性,常用的有下面的一些;
首先把目标像素和邻域像素进行排序,取得排序得中位数即为滤波图像相应位置的值;可以去掉噪声点,较细的噪声线等;
opencv实现:
median = cv.medianBlur(img,5)
首先把目标像素和邻域像素进行排序,取得排序中最大值作为滤波图像对应位置的值则为最大值滤波,取得排序中最小值作为滤波图像对应位置的值则为最小值滤波;最大值滤波可以扩大亮度比较大的区域;最小值滤波可以扩大亮度比较暗的区域;
结合了图像的灰度值和灰度差异,在保留边缘的同时,起到了去噪的作用;
opencv实现:
blur = cv.bilateralFilter(img,9,75,75)
官方文档里的代码,但也算是一种非线性滤波,每一种不同的距离对应的滤波函数不一样;
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
img2 = img.copy()
template = cv.imread('template.jpg',0)
w, h = template.shape[::-1]
# All the 6 methods for comparison in a list
methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']
for meth in methods:
img = img2.copy()
method = eval(meth)
# Apply template Matching
res = cv.matchTemplate(img,template,method)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum
if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv.rectangle(img,top_left, bottom_right, 255, 2)
plt.subplot(121),plt.imshow(res,cmap = 'gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img,cmap = 'gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
参考文献:opencv官方文档