赞
踩
图像线性平滑空间滤波(加权均值滤波器,几何均值滤波,谐波均值滤波,逆谐波均值滤波),非线性平滑空间滤波(中值滤波,最大值滤波,最小值滤波)MATLAB自写函数实现
图像平滑,又称图像模糊,是一种简单而常用的图像处理操作,常用于图像去噪。
为了进行平滑操作,我们将对图像使用滤波。最常见的滤波器是线性的,其输出的像素值(即 g ( i , j ) ) g(i,j)) g(i,j))为输入像素值(即 f ( i + k , j + l ) f(i+k,j+l) f(i+k,j+l))的加权和,可以将滤波操作用卷积操作表示:
h ( k , l ) h (k,l) h(k,l)叫做核(kernel)。
下面简单介绍OpenCV中常用的滤波方法,包括均值滤波、高斯滤波中值滤波和双边滤波。
均值滤波的核为:
输出的每个像素是它的核覆盖的所有像素的平均值。
OpenCV提供了函数cv.blur()
或cv.boxFilter()
实现均值滤波。cv.blur()
的主要参数有:
src
:输入图像;它可以有任意数量的通道,但类型应该是CV_8U, CV_16U, CV_16S, CV_32F或CV_64F。dst
:与src
大小和类型相同的输出图像。ksize
:核的大小。anchor
:表示锚点(计算的像素)相对于整个核邻域的位置。如果为负值,则核的中心被视为锚点。默认值Point(-1,-1)
borderType
:在图像边界补充像素,防止核的某些元素位于图像之外,有以下补充类型(BORDER_WRAP
除外,默认为BORDER_DEFAULT
)。等价于:
boxFilter(src, dst, src.type(), ksize, anchor, true, borderType)
二维高斯函数可以表示:
其中
μ
μ
μ为均值(峰值),
σ
2
σ^2
σ2为方差。
根据高斯函数得到的核示例:
3x3 | 5x5 |
---|---|
1
16
[
1
2
1
2
4
2
1
2
1
]
\frac{1}{16}\left[ |
1
159
×
[
2
4
5
4
2
4
9
12
9
4
5
12
15
12
5
4
9
12
9
4
2
4
5
4
2
]
\frac{1}{159} \times\left[ |
高斯滤波是线性的,通过高斯核与输入图像的卷积进行计算,在OpenCV中可以通过函数cv.GaussianBlur()
实现。
主要参数有:
src
:源图像dst
:目标图像ksize
:需要两个参数,分别表示高和宽。w
和h
必须是奇数和正数,否则将使用sigmaX
和sigmaY
按照OpenCV内置的函数计算。sigmaX
:表示
x
x
x中的标准差,如果值为0,则按照OpenCV内置的函数由核大小计算
σ
x
σ_x
σx。sigmaY
:表示
y
y
y的标准差。写入0表示
σ
y
σ_y
σy由核大小计算。borderType
:与均值滤波相同。中值滤波器遍历图像的每个元素,并将每个像素替换为核区域内所有像素的中值。
中值滤波通过函数cv.medianBlur()
完成的。主要参数有:
src
:源图像dst
:目标图像,必须与src类型相同ksize
:核的大小。因为我们使用的是方形窗口,所以只有一个参数。另外,还必须是奇数。高斯滤波它在滤除图像中噪声信号的同时,也会对图像中的边缘信息进行平滑。 双边滤波则可以缓解这个问题。
原理推荐阅读:https://blog.csdn.net/u013921430/article/details/84532068
使用cv.bilateralFilter()
实现双边滤波,参数有:
src
:源图像dst
:目标图像d
:每个像素邻域的直径。sigmaColor
:颜色空间的标准差。sigmaSpace
:坐标空间的标准差。d<=0
时,d
与sigmaSpace
成正比。borderType
:与均值滤波相同import sys import cv2 as cv import numpy as np # Global Variables DELAY_CAPTION = 1500 DELAY_BLUR = 100 MAX_KERNEL_LENGTH = 31 src = None dst = None window_name = 'Smoothing Demo' def main(argv): cv.namedWindow(window_name, cv.WINDOW_AUTOSIZE) # Load the source image imageName = argv[0] if len(argv) > 0 else 'lena.jpg' global src src = cv.imread(cv.samples.findFile(imageName)) if src is None: print('Error opening image') print('Usage: smoothing.py [image_name -- default ../data/lena.jpg] \n') return -1 if display_caption('Original Image') != 0: return 0 global dst dst = np.copy(src) if display_dst(DELAY_CAPTION) != 0: return 0 # 均值滤波 if display_caption('Homogeneous Blur') != 0: return 0 for i in range(1, MAX_KERNEL_LENGTH, 2): dst = cv.blur(src, (i, i)) if display_dst(DELAY_BLUR) != 0: return 0 # 高斯滤波 if display_caption('Gaussian Blur') != 0: return 0 for i in range(1, MAX_KERNEL_LENGTH, 2): dst = cv.GaussianBlur(src, (i, i), 0) if display_dst(DELAY_BLUR) != 0: return 0 # 中值滤波 if display_caption('Median Blur') != 0: return 0 for i in range(1, MAX_KERNEL_LENGTH, 2): dst = cv.medianBlur(src, i) if display_dst(DELAY_BLUR) != 0: return 0 # 双边滤波 if display_caption('Bilateral Blur') != 0: return 0 for i in range(1, MAX_KERNEL_LENGTH, 2): dst = cv.bilateralFilter(src, i, i * 2, i / 2) if display_dst(DELAY_BLUR) != 0: return 0 # Done display_caption('Done!') return 0 def display_caption(caption): global dst dst = np.zeros(src.shape, src.dtype) rows, cols, _ch = src.shape cv.putText(dst, caption, (int(cols / 4), int(rows / 2)), cv.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255)) return display_dst(DELAY_CAPTION) def display_dst(delay): cv.imshow(window_name, dst) c = cv.waitKey(delay) if c >= 0: return -1 return 0 if __name__ == "__main__": main(sys.argv[1:])
#include <iostream> #include "opencv2/imgproc.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp" using namespace std; using namespace cv; int DELAY_CAPTION = 1500; int DELAY_BLUR = 100; int MAX_KERNEL_LENGTH = 31; Mat src; Mat dst; char window_name[] = "Smoothing Demo"; int display_caption( const char* caption ); int display_dst( int delay ); int main( int argc, char ** argv ) { namedWindow( window_name, WINDOW_AUTOSIZE ); const char* filename = argc >=2 ? argv[1] : "lena.jpg"; src = imread( samples::findFile( filename ), IMREAD_COLOR ); if (src.empty()) { printf(" Error opening image\n"); printf(" Usage:\n %s [image_name-- default lena.jpg] \n", argv[0]); return EXIT_FAILURE; } if( display_caption( "Original Image" ) != 0 ) { return 0; } dst = src.clone(); if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; } if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; } for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) { blur( src, dst, Size( i, i ), Point(-1,-1) ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; } for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) { GaussianBlur( src, dst, Size( i, i ), 0, 0 ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } if( display_caption( "Median Blur" ) != 0 ) { return 0; } for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) { medianBlur ( src, dst, i ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; } for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 ) { bilateralFilter ( src, dst, i, i*2, i/2 ); if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } } display_caption( "Done!" ); return 0; } int display_caption( const char* caption ) { dst = Mat::zeros( src.size(), src.type() ); putText( dst, caption, Point( src.cols/4, src.rows/2), FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) ); return display_dst(DELAY_CAPTION); } int display_dst( int delay ) { imshow( window_name, dst ); int c = waitKey ( delay ); if( c >= 0 ) { return -1; } return 0; }
原始图像:
均值滤波(核大小递增:1,3,5,…31):
高斯滤波
中值滤波
双边滤波
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。