导读 /// 高斯密度函数 /// /// 随机数 /// 数学期望 ...
/// 高斯密度函数 /// /// 随机数 /// 数学期望 /// 方差 /// static double gossp(double z, double u, double a) { double p; p = ( 1 / (a * Math.Sqrt(2 * Math.PI)) * Math.Pow( Math.E, -( Math.Pow(z - u,2) / (2 * a * a)))); return p; } /// /// 对一幅图形进行高斯噪音处理。
/// /// /// 数学期望 /// 方差 /// static public Bitmap goss_noise(Image img, double u, double a) { int width = img.Width; int height = img.Height; Bitmap bitmap2 = new Bitmap(img); Rectangle rectangle1 = new Rectangle(0, 0, width, height); PixelFormat format = bitmap2.PixelFormat; BitmapData data = bitmap2.LockBits(rectangle1, ImageLockMode.ReadWrite, format); IntPtr ptr = data.Scan0; int numBytes = width * height * 4; byte[] rgbValues = new byte[numBytes]; Marshal.Copy(ptr, rgbValues, 0, numBytes); Random random1 = new Random(); for (int i = 0; i < numBytes; i += 4) { for (int j = 0; j < 3; j++) { double z; z = random1.NextDouble() - 0.5 + u; double pz = gossp(z, u, a); double r = random1.NextDouble(); // Debug.WriteLineIf(pz < 0.1, string.Format("z={0}pz={1}r={2}", z,pz,r)); if (r <= pz) { double p = rgbValues[i + j]; p = p + z * 128; if (p > 255) p = 255; if (p < 0) p = 0; rgbValues[i + j] = (byte)p; } } } Marshal.Copy(rgbValues, 0, ptr, numBytes); bitmap2.UnlockBits(data); return bitmap2; } 要回答这3个问题,需要你先理解概率密度函数的意义。
高斯密度函数的意义就是: 如果一个随机数发生很多次之后,其平均值为u, 并且其方差为a, 那么对于这个随机数序列中,出现一个特定的z值的概率是多少。
因此,需要先生成一个随机数z, 然后用高斯函数得知其发生的概率是多少。
也就是pz。
然后,知道这个z“应该”的发生概率是多少之后,我们就要想办法让他按这个概率作用于原图上的像素。
因此,再采用第二个随机数r, r是一个平均概率的0-1的数,因此,r小于等于pz的情况的概率正好等于pz。
因此,如果在r小于等于pz时,z这个随机量发生作用,那么z的概率就是pz了。
这样循环处理,对于n个z,他的概率就客观上服从高斯分布了。
最后,关于为何 - 0.5 的原因: 这涉及到z的值域问题。
原理上讲,如果产生的噪音在-128到+128之间,数学期望为0,而方差为0.1时,对于所产生的z(一般情况下都在几十的值段),其概率几乎为0,导致根本不可能产生可见的干扰。
因此,我考虑到是否采用-0.5到+0.5的z值,这样在方差为0.1的情况下,z的概率才大到足以产生足够多的噪音。
但是,这样一来,z的值就太小了,只是-0.5到+0.5的区间,对图像的干扰非常不明显,于是我试着把z看为一个比例值,放大z到-128到+128的区间,这样处理完之后,对图像的干扰就大到足以观察到效果。
免责声明:本文由用户上传,如有侵权请联系删除!