通过手机获取的图像由于多方面的原因或多或少存在一些噪声,即图像的去噪处理。简单的来说就是用 的矩阵在灰度图像一个一个像素移动,以某种逻辑来消除灰度图像中的孤立点,即噪声。去噪的方法主要有均值滤波、中值滤波、自适应维纳滤波器、形态学噪声滤除器、高斯滤波器。
图像高斯滤波是在二维空间利用正态分布(高斯函数)计算平滑模版,并利用该模板与灰度图像做卷积运算来达到滤波去噪的目的。若 是正态分布的标准差,n为模板的大小,则模板上 处元素的计算公式为:
根据正态分布的特性, 越大得到的图像越模糊。从理论上讲图像上灰度不为0的点都应该构成卷积矩阵与原图像做变换,也就是说每个像素的计算都得包括整幅图像。然而在实际中计算高斯函数的离散近似时候, 距离外的像素值可以看作不起作用,也就是模板大小为(6*sigma+1)*(6*sigma+1)
。本文实验选择的是 的模板矩阵, sigma取值越大越模糊。由所得的模板矩阵与原灰度图像做卷积运算即可去除图像中的部分噪声。
因此高斯模糊一般分为以下四步:
1、获取高斯模板矩阵:
public float[][] get2DKernalData(int n, float sigma) { int size = 2 * n + 1; float sigma22 = 2 * sigma * sigma; float sigma22PI = (float) Math.PI * sigma22; float[][] kernalData = new float[size][size]; int row = 0; for (int i = -n; i <= n; i++) { int column = 0; for (int j = -n; j <= n; j++) { float xDistance = i * i; float yDistance = j * j; kernalData[row][column] = (float) Math .exp(-(xDistance + yDistance) / sigma22) / sigma22PI; column++; } row++; } return kernalData; }
2、获取灰度矩阵
public int[][]getGrayMatrix(Bitmap bt) { int hdjz[][]=new int[h][w]; for(int i=0;i<h;i++) for(int j=0;j<w;j++) { int argb=bt.getPixel(j , i); int r = (argb >> 16) & 0xFF; int g = (argb >> 8) & 0xFF; int b = (argb >> 0) & 0xFF; int grayPixel = (int) (r + g + b) / 3; hdjz[i][j]=grayPixel; } return hdjz; }
3、卷积运算
public int[][] GS(int[][] hd, int size, float sigma) { float[][] gs = get2DKernalData(size, sigma); int outmax = 0; int inmax = 0; for (int x = size; x < w - size; x++) for (int y = size; y < h - size; y++) { float hc1 = 0; if (hd[y][x] > inmax) inmax = hd[y][x]; for (int k = -size; k < size + 1; k++) for (int j = -size; j < size + 1; j++) { hc1 = gs[size + k][j + size] * hd[y + j][x + k] + hc1; } hd[y][x] = (int) (hc1); if (outmax < hc1) outmax = (int) (hc1); } float rate = inmax / outmax; for (int x = size; x < w - size; x++) for (int y = size; y < h - size; y++) { hd[y][x] = (int) (hd[y][x] * rate); } return hd; }
4、将得到的灰度矩阵创建灰度图
//由灰度矩阵创建灰度图 public Bitmap createGrayImage(int[][]hdjz) { int h=hdjz.length; int w = hdjz[0].length; Bitmap bt=Bitmap.createBitmap(w, h, image.getConfig()); for(int i=0;i<h;i++) for(int j=0;j<w;j++) { int grayValue=hdjz[i][j]; int color = ((0xFF << 24)+(grayValue << 16)+(grayValue << 8)+grayValue); bt.setPixel(j, i, color); } return bt; }