图像处理之空间滤波
Posted 落樱弥城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图像处理之空间滤波相关的知识,希望对你有一定的参考价值。
1 原理
1.1 空间滤波简介
滤波器即只让一部分频率的波形通过来达到波形过滤目的的器件。空间域指一张图像像素平面一定范围内的像素域,相对的是时间域,即多帧图像之间的关系,主要在处理视频帧时描述。在图像处理中,滤波分为两种:
- 频域滤波,将图像转换到频域进行相应的滤波;
- 空间滤波,更准确的说法是掩膜,即在图像的像素平面上利用空间滤波器对图像进行处理。
空间滤波器是一个 m × n m\\times n m×n大小的矩阵(通常为 3 × 3 3\\times 3 3×3,一般都为奇数,偶数核无法完全对齐,需要进行但方向上的padding就会产生图像移位的问题),矩阵定义了希望对当前像素邻域执行的操作和具体的参数,该滤波器会掠过待处理图像的每个像素点来达到,得到对应的输出图像。空间滤波器根据滤波器的特性分为:
- 线性空间滤波:即对邻域内像素的操作为线性。比如当前像素的输出为滤波器与邻域像素点乘积之和;
- 非线性空间滤波:即对邻域内像素的操作为非线性。比如输出像素只取当前像素邻域的最大值。
比如,对于输入为
M
×
N
M\\times N
M×N的图像,滤波器的核大小为
m
×
n
m\\times n
m×n的线性滤波的数学表示为:
g
(
x
,
y
)
=
∑
i
=
−
a
a
∑
j
=
−
b
b
w
(
i
,
j
)
f
(
x
+
i
,
y
+
j
)
g(x,y)=\\sum_i=-a^a\\sum_j=-b^bw(i,j)f(x+i,y+j)
g(x,y)=i=−a∑aj=−b∑bw(i,j)f(x+i,y+j)
其中
g
(
x
,
y
)
g(x,y)
g(x,y)为输出像素,区间
[
−
a
,
−
b
]
[-a,-b]
[−a,−b]的长度为
m
m
m,区间
[
−
n
,
n
]
[-n,n]
[−n,n]的长度为
n
n
n,
w
(
i
,
j
)
w(i,j)
w(i,j)为对应
i
,
j
i,j
i,j位置的滤波器的权重参数。
在进行空间滤波时如果不对原图像进行填充(padding)的话输出的图像的大小就是
(
M
−
m
+
1
)
×
(
N
−
n
+
1
)
(M - m + 1)\\times(N - n + 1)
(M−m+1)×(N−n+1),如果希望滤波器的中心能够掠过每个像素或者得到和输入大小箱通风的图像就需要对原图进行填充。填充的方式根据具体的需要来定,最为常用的为在边界上填充固定像素,如果
m
≠
n
m\\ne n
m=n时,则水平和垂直方向padding的像素值不同。当然也可以在原图像素间填充固定像素值。
1.2 空间相关和卷积
线性空间滤波中相关和卷积的概念相近:
- 相关:滤波器掠过图像中每个像素计算乘积之和;
- 卷积:首先将滤波器旋转 18 0 。 180^。 180。滤波器略过图像中每个像素计算每个像素的乘积之和。
二者的区别是,假如输入图像是单位冲激图像,则相关得到的是滤波器输入的180度旋转的值;而卷积得到的是原滤波器的参数值。
2 不同类型的滤波器
2.1 均值滤波器
均值滤波器,顾名思义,对邻域邻域内像素取均值,属于低通滤波器。均值滤波器可以将预期内的像素值平均化,降低图像中原来比较尖锐的部分抑制图像的高频。均值滤波的数学表达比较简单:
g
(
x
,
y
)
=
∑
s
=
−
a
a
∑
t
=
−
b
b
w
(
s
,
t
)
f
(
x
+
s
,
y
+
t
)
∑
s
=
−
a
a
∑
t
=
−
b
b
w
(
s
,
t
)
g(x,y)=\\frac\\sum_s=-a^a\\sum_t=-b^bw(s,t)f(x+s,y+t)\\sum_s=-a^a\\sum_t=-b^bw(s,t)
g(x,y)=∑s=−aa∑t=−bbw(s,t)∑s=−aa∑t=−bbw(s,t)f(x+s,y+t)
公式中,
w
,
f
,
g
w,f,g
w,f,g分别为滤波器参数,输入像素,输出像素。输出像素的值为领域内每个像素的像素值和滤波器权重逐一相乘然后求和再除以滤波器权重之和求平均。
影响滤波器的效果有两部分,滤波器的参数和滤波器的大小。滤波器的核越大所能作用的邻域越大,均质化的效果越明显。下图为核尺寸从
[
3
,
33
]
[3,33]
[3,33]步进为2,权重参数为全1的效果。
如果均值滤波器的权重参数全部为1就是盒装滤波器。下面两个矩阵左边是盒装滤波器的参数,右边是根据像素距离作为权重的矩阵。
[
1
1
1
1
1
1
1
1
1
]
[
1
2
1
2
4
2
1
2
1
]
\\beginbmatrix 1&1&1\\\\ 1&1&1\\\\ 1&1&1\\\\ \\endbmatrix \\beginbmatrix 1&2&1\\\\ 2&4&2\\\\ 1&2&1\\\\ \\endbmatrix
⎣
⎡111111111⎦
⎤⎣
⎡121242121⎦
⎤
在实践中,由于这些模板在一幅图像中跨过的区域很小,即便权重参数不同,通常也很难看出差异。——《数字图像处理》
另外需要注意的是,从上面的图像中能够明显的看出边缘有黑边,而且滤波器的核越大越明显。原因很简单就是因为边缘填充的是0导致的,实际处理中只需要填充最近的像素值即可。
static Mat avgFilterTransformOneChannel(const Mat &gray, const Mat &weight)
int weiHeight = weight.rows, weiWidth = weight.cols;
assert( gray.channels() == 1 && weight.channels() == 1 && weiHeight % 2 == 1 && weiWidth % 2 == 1);
double wsum = cv::sum(weight)[0];
//填充padding像素保证每个像素都能被滤波器掠过
Mat paddingMat, retMat(cv::Size(gray.rows, gray.cols), CV_8UC1);
int horPaddPixels = floor(weiHeight / 2), verPaddPixels = floor(weiHeight / 2);
copyMakeBorder(gray, paddingMat, verPaddPixels, verPaddPixels, horPaddPixels, horPaddPixels, BORDER_CONSTANT, Scalar(0));
unsigned int imgWidth = gray.cols, imgHeight = gray.rows;
for (int i = 0; i < imgHeight; i++)
for (int j = 0; j < imgWidth; j++)
Mat currentRoi = paddingMat(cv::Range(i, i + 2 * horPaddPixels + 1), cv::Range(j, j + 2 * verPaddPixels + 1)), multMat;
cv::multiply(weight, currentRoi, multMat);
double currentValue = sum(multMat)[0] / (wsum * 1.0);
retMat.at<uchar>(i, j) = floor(currentValue);
return retMat;
Mat GrayTransform::avgFilterTransform(const cv::Mat &img, const cv::Mat &weight)
std::vector<Mat> chanelMats;
split(img, chanelMats);
for (int i = 0; i < chanelMats.size(); i++)
chanelMats[i] = avgFilterTransformOneChannel(chanelMats[i], weight);
Mat returnMat;
merge(chanelMats, returnMat);
return returnMat;
2.2 统计排序滤波
统计排序滤波就是利用邻域内像素的统计特性的一种非线性滤波。比如输出的像素取邻域内像素最大值的最大值滤波,取最小值的最小值滤波,取中值的中值滤波。
下图从左到右分别为:原图,最大值滤波,最小值滤波,中值滤波。
中值滤波可以用来消除图像中的椒盐噪声。
static double matMaxValue(const Mat &img)
assert(img.elemSize() == sizeof(uchar));
std::vector<uchar> vec(img.begin<uchar>(), img.end<uchar>());
std::sort(vec.begin(), vec.end());
return vec.at(vec.size() - 1);
static double matMinValue(const Mat &img)
assert(img.elemSize() == sizeof(uchar));
std::vector<uchar> vec(img.begin<uchar>(), img.end<uchar>());
std::sort(vec.begin(), vec.end());
return vec.at(0);
static double matMedValue(const Mat &img)
assert(img.elemSize() == sizeof(uchar));
std::vector<uchar> vec(img.begin<uchar>(), img.end<uchar>());
std::sort(vec.begin(), vec.end());
return vec.size(<以上是关于图像处理之空间滤波的主要内容,如果未能解决你的问题,请参考以下文章