滤波
滤波是将信号中特定波段频率滤除的操作,是从含有干扰的接收信号中提取有用信号的一种技术。
均值滤波
均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(如3×3模板:以目标象素为中心的周围8个象素,构成一个滤波模板,即去掉目标象素本身),再用模板中的全体像素的平均值来代替原来像素值。
效果
平滑线性滤波处理降低了图像的“尖锐”变化。由于典型的随机噪声由灰度级的急剧变化组成,因此常见的平滑处理的应用就是降低噪声。均值滤波器的主要应用是去除图像中的不相关细节,其中“不相关”是指与滤波器模板尺寸相比较小的像素区域。然而,由于图像的边缘也是由图像灰度的尖锐变化带来的特性,所以均值滤波处理还是存在着边缘模糊的负面效应。
实验
使用OpenCV进行实验的部分代码:
IplImage *pImgTmp = cvCloneImage(m_pImg);
// 第二种边界处理:对边界特殊处理
for (i = 0; i < m_pImg->width; i++)
{
for (j = 0; j < m_pImg->height; j++)
{
CvScalar color;
CvScalar colorTmp;
int m, n, cnt = 0;
color.val[0] = color.val[1] = color.val[2] = 0;
for (m = i - nKernelSize/2; m <= i+nKernelSize/2; m++)
{
for (n = j-nKernelSize/2; n <= j+nKernelSize/2; n++)
{
// 处理边界和中心像素
if ( (m == i && n == j) || m < 0 || m >= m_pImg->width
|| n < 0 || n >= m_pImg->height )
continue;
cvGetPixel(pImgTmp, n, m, colorTmp);
color.val[0] += colorTmp.val[0];
color.val[1] += colorTmp.val[1];
color.val[2] += colorTmp.val[2];
cnt++;
}
}
// 取邻域中像素的平均值
color.val[0] /= cnt;
color.val[1] /= cnt;
color.val[2] /= cnt;
cvSetPixel(m_pImg, j, i, color);
}
}
cvReleaseImage(&pImgTmp);
void cvGetPixel(const IplImage* pIplImg, int row, int col, CvScalar &color)
{
if (col >= pIplImg->width || col < 0 ||
row >= pIplImg->height || row < 0 )
return;
uchar *p = ((uchar*)(pIplImg->imageData + pIplImg->widthStep * row + col * 3));
color = cvScalar(p[0], p[1], p[2]);
}
void cvSetPixel(IplImage* pIplImg, int row, int col, CvScalar color)
{
if (col >= pIplImg->width || col < 0 ||
row >= pIplImg->height || row < 0 )
return;
uchar *p = ((uchar*)(pIplImg->imageData + pIplImg->widthStep * row + col * 3));
p[2] = color.val[2];
p[1] = color.val[1];
p[0] = color.val[0];
}
3×3模板结果:
5×5模板结果:
21×21模板结果:
参考
http://baike.baidu.com/view/1220844.htm
http://page.renren.com/601107605/note/803745240