图像处理之基础---卷积去噪

讨论如何使用卷积作为数学工具来处理图像,实现图像的滤波,其方法包含以下几种,均值

滤波,中值滤波,最大最小值滤波,关于什么是卷积以及理解卷积在图像处理中作用参见这

里–http://blog.csdn.net/jia20003/article/details/7038938

均值滤波:

均值滤波,是图像处理中最常用的手段,从频率域观点来看均值滤波是一种低通滤波器,高

频信号将会去掉,因此可以帮助消除图像尖锐噪声,实现图像平滑,模糊等功能。理想的均

值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素。采样Kernel数

据通常是3X3的矩阵,如下表示:

从左到右从上到下计算图像中的每个像素,最终得到处理后的图像。均值滤波可以加上两个

参数,即迭代次数,Kernel数据大小。一个相同的Kernel,但是多次迭代就会效果越来越好。

同样,迭代次数相同,Kernel矩阵越大,均值滤波的效果就越明显。

中值滤波

中值滤波也是消除图像噪声最常见的手段之一,特别是消除椒盐噪声,中值滤波的效果要比

均值滤波更好。中值滤波是跟均值滤波唯一不同是,不是用均值来替换中心每个像素,而是

将周围像素和中心像素排序以后,取中值,一个3X3大小的中值滤波如下:

最大最小值滤波

最大最小值滤波是一种比较保守的图像处理手段,与中值滤波类似,首先要排序周围像素和

中心像素值,然后将中心像素值与最小和最大像素值比较,如果比最小值小,则替换中心像

素为最小值,如果中心像素比最大值大,则替换中心像素为最大值。一个Kernel矩阵为3X3的最大最小值滤波如下:

原图如下:

分别实现中值和均值滤波以后效果如下:

代码就不解释了,原理已经解释得很清楚了,全部算法源代码都是基于Java

特别说明一点的是,均值滤波对于高斯噪声的效果比较好,中值滤波对于椒盐噪声的效果比较好

想必大家从上面效果比较中也可以看到一点端倪。因为我选择的噪声图片是椒盐噪声的,哈哈

自己读吧,不解释了,有问题的可以问,源代码如下:

[java] view plaincopy

  1. package com.process.blur.study;
  2. import java.awt.image.BufferedImage;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. public class SmoothFilter extends AbstractBufferedImageOp {
  6. public final static int MEAN_FILTER_TYPE = 1;
  7. public final static int MEADIAN_FILTER_TYPE = 2;
  8. public final static int MIN_MAX_FILTER_TYPE = 4;
  9. private int repeats = 3; // default 1
  10. private int kernel_size = 3; // default 3
  11. private int type = 1; // default mean type
  12. public int getRepeat() {
  13. return repeats;
  14. }
  15. public void setRepeat(int repeat) {
  16. this.repeats = repeat;
  17. }
  18. public int getKernelSize() {
  19. return kernel_size;
  20. }
  21. public void setKernelSize(int kernelSize) {
  22. this.kernel_size = kernelSize;
  23. }
  24. public int getType() {
  25. return type;
  26. }
  27. public void setType(int type) {
  28. this.type = type;
  29. }
  30. @Override
  31. public BufferedImage filter(BufferedImage src, BufferedImage dest) {
  32. int width = src.getWidth();
  33. int height = src.getHeight();
  34. if ( dest == null )
  35. dest = createCompatibleDestImage( src, null );
  36. int[] inPixels = new int[width*height];
  37. int[] outPixels = new int[width*height];
  38. getRGB( src, 0, 0, width, height, inPixels );
  39. // pick up one filter from here!!!
  40. if(this.type == MEAN_FILTER_TYPE)
  41. {
  42. for(int i=0; i<repeats; i++) {
  43. performMeanFilter(width, height, inPixels, outPixels);
  44. System.arraycopy(outPixels, 0, inPixels, 0, inPixels.length);
  45. }
  46. }
  47. else if(this.type == MEADIAN_FILTER_TYPE)
  48. {
  49. performMedianFilter(width, height, inPixels, outPixels);
  50. }
  51. else if(this.type == MIN_MAX_FILTER_TYPE)
  52. {
  53. performMinMaxFilter(width, height, inPixels, outPixels);
  54. }
  55. // return result
  56. setRGB( dest, 0, 0, width, height, outPixels );
  57. return dest;
  58. }
  59. /**
  60. *  <p> perform convolution filter </p>
  61. *
  62. * @param width
  63. * @param height
  64. * @param inPixels
  65. * @param outPixels
  66. */
  67. public void performMeanFilter(int width, int height, int[] inPixels, int[] outPixels) {
  68. int rows2 = kernel_size/2;
  69. int cols2 = kernel_size/2;
  70. int index = 0;
  71. int index2 = 0;
  72. float total = kernel_size * kernel_size;
  73. for (int y = 0; y < height; y++) {
  74. for (int x = 0; x < width; x++) {
  75. float r = 0, g = 0, b = 0, a = 0;
  76. for (int row = -rows2; row <= rows2; row++) {
  77. int rowoffset = y + row;
  78. if(rowoffset < 0 || rowoffset >=height) {
  79. rowoffset = y;
  80. }
  81. //System.out.println("rowoffset == " + rowoffset);
  82. for(int col = -cols2; col <= cols2; col++) {
  83. int coloffset = col + x;
  84. if(coloffset < 0 || coloffset >= width) {
  85. coloffset = x;
  86. }
  87. index2 = rowoffset * width + coloffset;
  88. int rgb = inPixels[index2];
  89. a += ((rgb >> 24) & 0xff);
  90. r += ((rgb >> 16) & 0xff);
  91. g += ((rgb >> 8) & 0xff);
  92. b += (rgb & 0xff);
  93. }
  94. }
  95. int ia = 0xff;
  96. int ir = clamp((int)(r/total));
  97. int ig = clamp((int)(g/total));
  98. int ib = clamp((int)(b/total));
  99. outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
  100. }
  101. }
  102. }
  103. /**
  104. *  <p> perform median filter </p>
  105. *
  106. * @param width
  107. * @param height
  108. * @param src
  109. * @param inPixels
  110. * @param outPixels
  111. */
  112. public void performMedianFilter(int width, int height, int[] inPixels, int[] outPixels) {
  113. int rows2 = kernel_size/2;
  114. int cols2 = kernel_size/2;
  115. int index = 0;
  116. int index2 = 0;
  117. float total = kernel_size * kernel_size;
  118. int[] matrix = new int[(int)total];
  119. for (int y = 0; y < height; y++) {
  120. for (int x = 0; x < width; x++) {
  121. int count = 0;
  122. for (int row = -rows2; row <= rows2; row++) {
  123. int rowoffset = y + row;
  124. if(rowoffset < 0 || rowoffset >=height) {
  125. rowoffset = y;
  126. }
  127. for(int col = -cols2; col <= cols2; col++) {
  128. int coloffset = col + x;
  129. if(coloffset < 0 || coloffset >= width) {
  130. coloffset = x;
  131. }
  132. index2 = rowoffset * width + coloffset;
  133. int rgb = inPixels[index2];
  134. matrix[count] = rgb;
  135. count++;
  136. }
  137. }
  138. Arrays.sort(matrix);
  139. int ia = 0xff;
  140. int ir = ((matrix[count/2] >> 16) & 0xff);
  141. int ig = ((matrix[count/2] >> 8) & 0xff);
  142. int ib = (matrix[count/2] & 0xff);
  143. outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
  144. }
  145. }
  146. }
  147. /**
  148. * <p> perform min/max pixel filter </p>
  149. *
  150. * @param width
  151. * @param height
  152. * @param src
  153. * @param inPixels
  154. * @param outPixels
  155. */
  156. public void performMinMaxFilter(int width, int height, int[] inPixels, int[] outPixels) {
  157. int rows2 = kernel_size/2;
  158. int cols2 = kernel_size/2;
  159. int index = 0;
  160. int index2 = 0;
  161. float total = kernel_size * kernel_size;
  162. int[] matrix = new int[(int)total];
  163. for (int y = 0; y < height; y++) {
  164. for (int x = 0; x < width; x++) {
  165. int count = 0;
  166. for (int row = -rows2; row <= rows2; row++) {
  167. int rowoffset = y + row;
  168. if(rowoffset < 0 || rowoffset >=height) {
  169. rowoffset = y;
  170. }
  171. for(int col = -cols2; col <= cols2; col++) {
  172. int coloffset = col + x;
  173. if(coloffset < 0 || coloffset >= width) {
  174. coloffset = x;
  175. }
  176. index2 = rowoffset * width + coloffset;
  177. int rgb = inPixels[index2];
  178. matrix[count] = rgb;
  179. count++;
  180. }
  181. }
  182. int ia = 0xff;
  183. int oldPixel = matrix[count/2];
  184. int targetRGB = findNewPixel(matrix, oldPixel);
  185. int ir = ((targetRGB >> 16) & 0xff);
  186. int ig = ((targetRGB >> 8) & 0xff);
  187. int ib = (targetRGB & 0xff);
  188. outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib;
  189. }
  190. }
  191. }
  192. private int findNewPixel(int[] matrix, int oldPixel) {
  193. ArrayList<Integer> list = new ArrayList<Integer>();
  194. for(int i=0; i<matrix.length; i++) {
  195. if(matrix[i] == oldPixel)
  196. continue;
  197. list.add(matrix[i]);
  198. }
  199. int[] filterData = new int[list.size()];
  200. int index = 0;
  201. for(Integer rgb : list) {
  202. filterData[index++] = rgb;
  203. }
  204. Arrays.sort(filterData);
  205. if(filterData.length == 0)
  206. return oldPixel;
  207. return (oldPixel > filterData[0]) ? filterData[0] : (oldPixel < filterData[filterData.length -1])? filterData[filterData.length -1] : oldPixel;
  208. }
  209. public static int clamp(int c) {
  210. if (c < 0)
  211. return 0;
  212. if (c > 255)
  213. return 255;
  214. return c;
  215. }
  216. }

转载是请注明出自本博客,如果需要完全代码的留下Email

http://blog.csdn.net/jia20003/article/details/7294460

时间: 2024-09-30 13:04:20

图像处理之基础---卷积去噪的相关文章

图像处理之基础---卷积傅立叶变换中的复数

整个看FFT过程中复数一直很折磨我. 原本的实数的东西通过复数表达很像旋转矩阵用quaternion来表达,尽管旋转vector还是要用matrix来做,但是通过用quaternion表达的旋转意义可以做插值等很多快速的操作,而且内存消耗也小,在做完这些操作之后再转成matrix用就好了. 复数表达也是类似. a+bi = M*(cos(theta)+sin(theta)*i)----极坐标 cos(x) + sin(x)*i = exp(x*i)----欧拉公式 这个用欧拉公式转出来的exp(

图像处理之基础---卷积,滤波,平滑

/*今天师弟来问我,CV的书里到处都是卷积,滤波,平滑……这些概念到底是什么意思,有什么区别和联系,瞬间晕菜了,学了这么久CV,卷积,滤波,平滑……这些概念每天都念叨好几遍,可是心里也就只明白个大概的意思,赶紧google之~ 发现自己以前了解的真的很不全面,在此做一些总结,以后对这种基本概念要深刻学习了~*/ 1.图像卷积(模板) (1).使用模板处理图像相关概念: 模板:矩阵方块,其数学含义是一种卷积运算. 卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素分别于卷积核(权矩阵)

图像处理之基础---卷积模板简介

1.使用模板处理图像相关概念:       模板:矩阵方块,其数学含义是一种卷积运算. 卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素分别与卷积核(权矩阵)的每个元素对应相乘,所有乘积之和作为区域中心像素的新值. 卷积核:卷积时使用到的权,用一个矩阵表示,该矩阵与使用的图像区域大小相同,其行.列都是奇数,是一个权矩阵. 卷积示例: 假设3 * 3的像素区域R与卷积核G分别为: 则卷积运算为: R5(中心像素)=R1G1 + R2G2 + R3G3 + R4G4 + R5G5 +

图像处理之基础---卷积模板运算

1.使用模板处理图像相关概念: 模板:矩阵方块,其数学含义是一种卷积运算.      卷积运算:可看作是加权求和的过程,使用到的图像区域中的每个像素分别于卷积核(权矩阵)的每个元素对应相                乘,所有乘积之和作为区域中心像素的新值.      卷积核:卷积时使用到的权用一个矩阵表示,该矩阵与使用的图像区域大小相同,其行.列都是奇数,              是一个权矩阵.      卷积示例:              3 * 3 的像素区域R与卷积核G的卷积运算: 

图像处理之基础---卷积及其快速算法的C++实现

头文件: /* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation,

图像处理之基础---二维卷积运算原理剖析

卷积运算(Convolution)是通过两个函数f 和g 生成第三个函数的一种数学算子,表示函数f 与经过翻转和平移与g 的重叠部分的累积.如果将参加卷积的一个函数看作区间的指示函数,卷积还可以被看作是“滑动平均”的推广.假设: f(x),g(x)是R1上的两个可积函数,并且积分是存在的.这样,随着 x 的不同取值,这个积分就定义了一个新函数h(x),称为函数f 与g 的卷积,记为h(x)=(f*g)(x). 两个向量卷积,说白了就是多项式乘法.下面用个矩阵例子说明其工作原理: a和d的卷积就是

Atitit 图像处理之理解卷积attilax总结

Atitit 图像处理之理解卷积attilax总结 卷积的运算可以分为反转.平移,相乘,求和. 在图像处理中,图像是一个大矩阵,卷积模板是一个小矩阵.按照上述过程,就是先把小矩阵反转,然后平移到某一位置,小矩阵的每一个小格对应大矩阵里面的一个小格,然后把对应小格里面的数相乘,把所有对应小格相乘的结果相加求和,得出的最后结果赋值给小矩阵中央小格对应的图像中小格的值,替换原来的值.就是上述说到的,反转.平移.相乘.求和.        一般图像卷积就是从第一个像素(小格)开始遍历到最后一个像素(小格

图像处理之基础---内积、点积

定义在数学中,数量积(dotproduct;scalarproduct,也称为标量积.点积.点乘)是接受在实数R上的两个矢量并返回一个实数值标量的二元运算.它是欧几里得空间的标准内积.两个矢量a=[a1,a2,…,an]和b=[b1,b2,…,bn]的点积定义为:a·b=a1b1+a2b2+……+anbn使用矩阵乘法并把(纵列)矢量当作n×1矩阵,点积还可以写为:a·b=a^T*b,这里的a^T指示矩阵a的转置. 内积(inner product),又称 数量积(scalar product).

转:图像处理之理解卷积

图像处理之理解卷积 一:什么是卷积 离散卷积的数学公式可以表示为如下形式: f(x) =  - 其中C(k)代表卷积操作数,g(i)代表样本数据, f(x)代表输出结果. 举例如下: 假设g(i)是一个一维的函数,而且代表的样本数为G = [1,2,3,4,5,6,7,8,9] 假设C(k)是一个一维的卷积操作数, 操作数为C=[-1,0,1] 则输出结果f(x)可以表示为 F=[1,2,2,2,2,2,2,2,1]  //边界数据未处理 以上只是一维的情况下,当对一幅二维数字图像加以卷积时,其