图像平滑(smoothing)也称为图像模糊(blurring),是一种在图像处理中使用频率很高的操作,进行图像平滑的操作原因有很多,在这里重点介绍使用平滑操作降低图片噪声。因为在图像中,噪声的能量大都集中在幅度谱的低频和中频部分,而在较高的频段,一些重要的细节信息往往被噪声淹没。在一幅图像中,所谓的高频部分是指图像中像素值落差很大的部分,而低频则是指像素值与旁边的像素值相差不大甚至相同,而图像的一些细节的部分往往由高频信息来展现,图像中掺杂的噪声往往也处于高频段,这就造成了一些细节信息被噪声淹没,可以根据不同的噪声类型用不同的滤波器进行处理。
滤波的目的有两个即:
1. 抽出对象的特征作为图像识别的特征模式;
2. 为适应图像处理要求,消除数字图像所混入的噪声
对图像滤波有两个要求:
1. 不能损坏图像的轮廓和边缘等重要信息;
2. 使图像清晰视觉效果更好
1. 均值模糊
根据输入的半径R,计算起始(2*R +1)
个像素的平均值, 作为第一个输出像素的结果,公式可以表示为:
像素
X0
= 其中K代表输入像素集合,i∈[-R, R]
然后计算每一行输出像素的值根据
Xi
=X0
+(K[index + R + 1] – K[index - R])
public static void boxBlur(Bitmap bitmap) {
org.opencv.android.Utils.bitmapToMat(bitmap, sSrc);//convert Bitmap to mat
Imgproc.blur(sSrc, sDst, new Size(15, 15), new Point(-1, -1), 4);
org.opencv.android.Utils.matToBitmap(sDst, bitmap);
sSrc.release();
sDst.release();
}
2. 高斯模糊
其实模糊滤波器就是对周围像素进行加权平均处理,均值模糊很简单,周围像素的权值都相同,所以不是很平滑。高斯模糊就有这个优点,所以被广泛用在图像降噪上。特别是在边缘检测之前,都会用来移除细节。
上面的正态分布是一维的,图像都是二维的,所以我们需要二维的正态分布。
正态分布的密度函数叫做”高斯函数”(Gaussian function):
其中,μ是x的均值,σ是x的标准差。因为计算平均值的时候,中心点就是原点,所以μ等于0。即:
根据一维高斯函数,可以推导得到二维高斯函数:
有了这个函数 ,就可以计算每个点的权重了。假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:
更远的点以此类推。下面就是5*5的高斯滤波器和平滑效果:
public static void gaussianBlur(Bitmap bitmap) {
org.opencv.android.Utils.bitmapToMat(bitmap, sSrc);//convert Bitmap to mat
Imgproc.GaussianBlur(sSrc, sDst, new Size(5, 5), 0, 0, 4);
org.opencv.android.Utils.matToBitmap(sDst, bitmap);
sSrc.release();
sDst.release();
}
3. 双边过滤算法
双边过滤算法作为一种改进的高斯过滤算法,在图像去噪,和均匀模糊(又称为磨皮),去锯齿效应上有不错的效果.双边过滤是采用Raised cosines函数来模拟高斯分布函数,并实现逼近高斯值域。
public static void bilBlur(Bitmap bitmap) {
org.opencv.android.Utils.bitmapToMat(bitmap, sSrc);//convert Bitmap to mat
Imgproc.cvtColor(sSrc, sSrc, Imgproc.COLOR_BGRA2BGR);
Imgproc.bilateralFilter(sSrc, sDst, 15, 150, 15, 4);
Mat kernel = new Mat(3, 3, CvType.CV_16S);
kernel.put(0, 0, 0, -1, 0, -1, 5, -1, 0, -1, 0);
Imgproc.filter2D(sDst, sDst, -1, kernel, new Point(-1, -1), 0.0, 4);
org.opencv.android.Utils.matToBitmap(sDst, bitmap);
sSrc.release();
sDst.release();
}