打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
图像处理之图像梯度效果

基本思想:

利用X方向与Y方向分别实现一阶微分,求取振幅,实现图像梯度效果。关于如何计算图像

一阶微分参见这里:http://blog.csdn.net/jia20003/article/details/7562092

使用的两种微分算子分别为Prewitt与Sobel,其中Soble在X, Y两个方向算子分别为:


Prewitt在X, Y方向上梯度算子分别为:


二:程序思路及实现

梯度滤镜提供了两个参数:

– 方向,用来要决定图像完成X方向梯度计算, Y方向梯度计算,或者是振幅计算

– 算子类型,用来决定是使用sobel算子或者是prewitt算子。

计算振幅的公式可以参见以前《图像处理之一阶微分应用》的文章

 三:运行效果

原图像如下:


基于Prewitt与sobel算子的XY方向振幅效果如下:



该滤镜的源代码如下:

  1. package com.process.blur.study;
  2. import java.awt.image.BufferedImage;
  3. /**
  4. *
  5. * @author gloomy-fish
  6. * @date 2012-06-11
  7. *
  8. * prewitt operator
  9. * X-direction
  10. * -1, 0, 1
  11. * -1, 0, 1
  12. * -1, 0, 1
  13. *
  14. * Y-direction
  15. * -1, -1, -1
  16. * 0, 0, 0
  17. * 1, 1, 1
  18. *
  19. * sobel operator
  20. * X-direction
  21. * -1, 0, 1
  22. * -2, 0, 2
  23. * -1, 0, 1
  24. *
  25. * Y-direction
  26. * -1, -2, -1
  27. * 0, 0, 0
  28. * 1, 2, 1
  29. *
  30. */
  31. public class GradientFilter extends AbstractBufferedImageOp {
  32. // prewitt operator
  33. public final static int[][] PREWITT_X = new int[][]{{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}};
  34. public final static int[][] PREWITT_Y = new int[][]{{-1, -1, -1}, {0, 0, 0}, {1, 1, 1}};
  35. // sobel operator
  36. public final static int[][] SOBEL_X = new int[][]{{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
  37. public final static int[][] SOBEL_Y = new int[][]{{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};
  38. // direction parameter
  39. public final static int X_DIRECTION = 0;
  40. public final static int Y_DIRECTION = 2;
  41. public final static int XY_DIRECTION = 4;
  42. private int direction;
  43. private boolean isSobel;
  44. public GradientFilter() {
  45. direction = XY_DIRECTION;
  46. isSobel = true;
  47. }
  48. public void setSoble(boolean sobel) {
  49. this.isSobel = sobel;
  50. }
  51. public int getDirection() {
  52. return direction;
  53. }
  54. public void setDirection(int direction) {
  55. this.direction = direction;
  56. }
  57. @Override
  58. public BufferedImage filter(BufferedImage src, BufferedImage dest) {
  59. int width = src.getWidth();
  60. int height = src.getHeight();
  61. if (dest == null )
  62. dest = createCompatibleDestImage( src, null );
  63. int[] inPixels = new int[width*height];
  64. int[] outPixels = new int[width*height];
  65. getRGB( src, 0, 0, width, height, inPixels );
  66. int index = 0, index2 = 0;
  67. double xred = 0, xgreen = 0, xblue = 0;
  68. double yred = 0, ygreen = 0, yblue = 0;
  69. int newRow, newCol;
  70. for(int row=0; row<height; row++) {
  71. int ta = 255, tr = 0, tg = 0, tb = 0;
  72. for(int col=0; col<width; col++) {
  73. index = row * width + col;
  74. for(int subrow = -1; subrow <= 1; subrow++) {
  75. for(int subcol = -1; subcol <= 1; subcol++) {
  76. newRow = row + subrow;
  77. newCol = col + subcol;
  78. if(newRow < 0 || newRow >= height) {
  79. newRow = row;
  80. }
  81. if(newCol < 0 || newCol >= width) {
  82. newCol = col;
  83. }
  84. index2 = newRow * width + newCol;
  85. tr = (inPixels[index2] >> 16) & 0xff;
  86. tg = (inPixels[index2] >> 8) & 0xff;
  87. tb = inPixels[index2] & 0xff;
  88. if(isSobel) {
  89. xred += (SOBEL_X[subrow + 1][subcol + 1] * tr);
  90. xgreen +=(SOBEL_X[subrow + 1][subcol + 1] * tg);
  91. xblue +=(SOBEL_X[subrow + 1][subcol + 1] * tb);
  92. yred += (SOBEL_Y[subrow + 1][subcol + 1] * tr);
  93. ygreen +=(SOBEL_Y[subrow + 1][subcol + 1] * tg);
  94. yblue +=(SOBEL_Y[subrow + 1][subcol + 1] * tb);
  95. } else {
  96. xred += (PREWITT_X[subrow + 1][subcol + 1] * tr);
  97. xgreen +=(PREWITT_X[subrow + 1][subcol + 1] * tg);
  98. xblue +=(PREWITT_X[subrow + 1][subcol + 1] * tb);
  99. yred += (PREWITT_Y[subrow + 1][subcol + 1] * tr);
  100. ygreen +=(PREWITT_Y[subrow + 1][subcol + 1] * tg);
  101. yblue +=(PREWITT_Y[subrow + 1][subcol + 1] * tb);
  102. }
  103. }
  104. }
  105. double mred = Math.sqrt(xred * xred + yred * yred);
  106. double mgreen = Math.sqrt(xgreen * xgreen + ygreen * ygreen);
  107. double mblue = Math.sqrt(xblue * xblue + yblue * yblue);
  108. if(XY_DIRECTION == direction)
  109. {
  110. outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);
  111. }
  112. else if(X_DIRECTION == direction)
  113. {
  114. outPixels[index] = (ta << 24) | (clamp((int)yred) << 16) | (clamp((int)ygreen) << 8) | clamp((int)yblue);
  115. }
  116. else if(Y_DIRECTION == direction)
  117. {
  118. outPixels[index] = (ta << 24) | (clamp((int)xred) << 16) | (clamp((int)xgreen) << 8) | clamp((int)xblue);
  119. }
  120. else
  121. {
  122. // as default, always XY gradient
  123. outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);
  124. }
  125. // cleanup for next loop
  126. newRow = newCol = 0;
  127. xred = xgreen = xblue = 0;
  128. yred = ygreen = yblue = 0;
  129. }
  130. }
  131. setRGB(dest, 0, 0, width, height, outPixels );
  132. return dest;
  133. }
  134. public static int clamp(int value) {
  135. return value < 0 ? 0 : (value > 255 ? 255 : value);
  136. }
  137. }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
图像处理之Canny边缘检测
图像处理之霍夫变换(直线检测算法)_java
图像边缘检测技术的实现及应用
图像处理之Harris角度检测算法
几种边缘检测算子的评估
图像处理常用边缘检测算子总结
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服