图像处理------图像梯度效果

基本思想:

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

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

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

二:程序思路及实现

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

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

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

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

 三:运行效果

原图像如下:

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

该滤镜的源代码如下:

[java] view plaincopy

  1. package com.process.blur.study;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4. /** 
  5.  *  
  6.  * @author gloomy-fish 
  7.  * @date 2012-06-11 
  8.  *  
  9.  * prewitt operator  
  10.  * X-direction 
  11.  * -1, 0, 1 
  12.  * -1, 0, 1 
  13.  * -1, 0, 1 
  14.  *  
  15.  * Y-direction 
  16.  * -1, -1, -1 
  17.  *  0,  0,  0 
  18.  *  1,  1,  1 
  19.  *   
  20.  * sobel operator 
  21.  * X-direction 
  22.  * -1, 0, 1 
  23.  * -2, 0, 2 
  24.  * -1, 0, 1 
  25.  *  
  26.  * Y-direction 
  27.  * -1, -2, -1 
  28.  *  0,  0,  0 
  29.  *  1,  2,  1 
  30.  * 
  31.  */  
  32. public class GradientFilter extends AbstractBufferedImageOp {  
  33.   
  34.     // prewitt operator  
  35.     public final static int[][] PREWITT_X = new int[][]{{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}};  
  36.     public final static int[][] PREWITT_Y = new int[][]{{-1, -1, -1}, {0,  0,  0}, {1,  1,  1}};  
  37.       
  38.     // sobel operator  
  39.     public final static int[][] SOBEL_X = new int[][]{{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};  
  40.     public final static int[][] SOBEL_Y = new int[][]{{-1, -2, -1}, {0,  0,  0}, {1,  2,  1}};  
  41.       
  42.     // direction parameter  
  43.     public final static int X_DIRECTION = 0;  
  44.     public final static int Y_DIRECTION = 2;  
  45.     public final static int XY_DIRECTION = 4;  
  46.     private int direction;  
  47.     private boolean isSobel;  
  48.       
  49.     public GradientFilter() {  
  50.         direction = XY_DIRECTION;  
  51.         isSobel = true;  
  52.     }  
  53.       
  54.     public void setSoble(boolean sobel) {  
  55.         this.isSobel = sobel;  
  56.     }  
  57.   
  58.     public int getDirection() {  
  59.         return direction;  
  60.     }  
  61.   
  62.     public void setDirection(int direction) {  
  63.         this.direction = direction;  
  64.     }  
  65.       
  66.     @Override  
  67.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  68.         int width = src.getWidth();  
  69.         int height = src.getHeight();  
  70.   
  71.         if (dest == null )  
  72.             dest = createCompatibleDestImage( src, null );  
  73.   
  74.         int[] inPixels = new int[width*height];  
  75.         int[] outPixels = new int[width*height];  
  76.         getRGB( src, 0, 0, width, height, inPixels );  
  77.         int index = 0, index2 = 0;  
  78.         double xred = 0, xgreen = 0, xblue = 0;  
  79.         double yred = 0, ygreen = 0, yblue = 0;  
  80.         int newRow, newCol;  
  81.         for(int row=0; row<height; row++) {  
  82.             int ta = 255, tr = 0, tg = 0, tb = 0;  
  83.             for(int col=0; col<width; col++) {  
  84.                 index = row * width + col;  
  85.                 for(int subrow = -1; subrow <= 1; subrow++) {  
  86.                     for(int subcol = -1; subcol <= 1; subcol++) {  
  87.                         newRow = row + subrow;  
  88.                         newCol = col + subcol;  
  89.                         if(newRow < 0 || newRow >= height) {  
  90.                             newRow = row;  
  91.                         }  
  92.                         if(newCol < 0 || newCol >= width) {  
  93.                             newCol = col;  
  94.                         }  
  95.                         index2 = newRow * width + newCol;  
  96.                         tr = (inPixels[index2] >> 16) & 0xff;  
  97.                         tg = (inPixels[index2] >> 8) & 0xff;  
  98.                         tb = inPixels[index2] & 0xff;  
  99.                           
  100.                         if(isSobel) {  
  101.                             xred += (SOBEL_X[subrow + 1][subcol + 1] * tr);  
  102.                             xgreen +=(SOBEL_X[subrow + 1][subcol + 1] * tg);  
  103.                             xblue +=(SOBEL_X[subrow + 1][subcol + 1] * tb);  
  104.                               
  105.                             yred += (SOBEL_Y[subrow + 1][subcol + 1] * tr);  
  106.                             ygreen +=(SOBEL_Y[subrow + 1][subcol + 1] * tg);  
  107.                             yblue +=(SOBEL_Y[subrow + 1][subcol + 1] * tb);  
  108.                         } else {  
  109.                             xred += (PREWITT_X[subrow + 1][subcol + 1] * tr);  
  110.                             xgreen +=(PREWITT_X[subrow + 1][subcol + 1] * tg);  
  111.                             xblue +=(PREWITT_X[subrow + 1][subcol + 1] * tb);  
  112.                               
  113.                             yred += (PREWITT_Y[subrow + 1][subcol + 1] * tr);  
  114.                             ygreen +=(PREWITT_Y[subrow + 1][subcol + 1] * tg);  
  115.                             yblue +=(PREWITT_Y[subrow + 1][subcol + 1] * tb);  
  116.                         }  
  117.                     }  
  118.                 }  
  119.                   
  120.                 double mred = Math.sqrt(xred * xred + yred * yred);  
  121.                 double mgreen = Math.sqrt(xgreen * xgreen + ygreen * ygreen);  
  122.                 double mblue = Math.sqrt(xblue * xblue + yblue * yblue);  
  123.                 if(XY_DIRECTION == direction)   
  124.                 {  
  125.                     outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);  
  126.                 }   
  127.                 else if(X_DIRECTION == direction)  
  128.                 {  
  129.                     outPixels[index] = (ta << 24) | (clamp((int)yred) << 16) | (clamp((int)ygreen) << 8) | clamp((int)yblue);  
  130.                 }   
  131.                 else if(Y_DIRECTION == direction)   
  132.                 {  
  133.                     outPixels[index] = (ta << 24) | (clamp((int)xred) << 16) | (clamp((int)xgreen) << 8) | clamp((int)xblue);  
  134.                 }   
  135.                 else   
  136.                 {  
  137.                     // as default, always XY gradient  
  138.                     outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);  
  139.                 }  
  140.                   
  141.                 // cleanup for next loop  
  142.                 newRow = newCol = 0;  
  143.                 xred = xgreen = xblue = 0;  
  144.                 yred = ygreen = yblue = 0;  
  145.                   
  146.             }  
  147.         }  
  148.         setRGB(dest, 0, 0, width, height, outPixels );  
  149.         return dest;  
  150.     }  
  151.       
  152.     public static int clamp(int value) {  
  153.         return value < 0 ? 0 : (value > 255 ? 255 : value);  
  154.     }  
  155.   
  156. }  
时间: 2024-10-30 00:23:26

图像处理------图像梯度效果的相关文章

jsp图片效果大全(图像震动效果、闪烁效果、自动切换图像)_JSP编程

本文主要介绍jsp实现图像震动效果.闪烁效果.自动切换图像的资料,废话不多说了,具体代码如下: 1.当鼠标指针经过图像时图像震动效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1

图像处理------像素格效果

图像中的像素格效果是最常见的图像特效,可以隐藏或者模糊一些不想被显示出来的图像细 节,是常用的图像处理手段.   像素格效果的算法其实非常的简单,只是对图像进行块扫描,求出每个像素块的平均RGB 值,然后赋值到块中的每个像素点,最后输出处理以后的图像,而像素块的扫描有点类似 卷积的处理.具体算法步骤如下: 1.      按照从左到右,自上而下的顺序,扫描每个像素点. 2.      对扫描到的像素,计算出它属于的像素块,并且计算像素块的平均RGB值 3.      将RGB赋值给扫描到的像素点

Cocos2D添加精灵纹理滤镜实现图像复古效果的转换

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 大家知道Cocos2d本身是一个非常强悍的2d游戏引擎,其中自带了很多使用的图像处理功能,但是别忘了Apple自带的Core Graphics里也有很多强大的图像处理功能,比如滤镜 CIFilter. Apple在iOS上提供了近百种不同的滤镜效果,可以用来方便快捷的渲染图像.至于CIFilter的具体使用大家可以参考苹果CG编程相关的书籍,这里由于篇幅原因不

javascript图像处理—边缘梯度计算函数_javascript技巧

前言 上一篇文章,我们讲解了图像处理中的膨胀和腐蚀函数,这篇文章将做边缘梯度计算函数. 图像的边缘 图像的边缘从数学上是如何表示的呢? 图像的边缘上,邻近的像素值应当显著地改变了.而在数学上,导数是表示改变快慢的一种方法.梯度值的大变预示着图像中内容的显著变化了. 用更加形象的图像来解释,假设我们有一张一维图形.下图中灰度值的"跃升"表示边缘的存在: 使用一阶微分求导我们可以更加清晰的看到边缘"跃升"的存在(这里显示为高峰值): 由此我们可以得出:边缘可以通过定位梯

图像处理------光源退化效果

基本思想: RGB像素的亮度是由RGB各个分量值的大小决定的,分量越大,亮度越大.看上去 好像光照效果越明显,光源退化效果是模拟光照在图像的中心点上,慢慢扩散到周 围,越靠近中心点像素,图像越亮,越远离图像越暗.原理可以说是非常的简单, 只要计算图像中每个像素到中心像素的欧几里德距离,归一化以后得到scale值(0 到1之间)乘以原来的RGB像素值即得到每个像素处理以后的RGB像素值. 效果如下: 关键代码解释: 中心像素点坐标取得: int centerX = width/2; int cen

《Mastering Opencv读书笔记》第一章 实现图像卡通效果

这本书和配套代码网上都有得下载. 要实现书中的效果,只要三步:1.使用拉普拉斯算子提取轮廓  2.使用双边滤波器对图像进行平滑 3.根据第一步得到的轮廓模版图,将第二步的结果拷贝过去[填充轮廓图中全白的部分] 由于我的笔记本摄像头坏了,故我的程序读取的是手机拍摄的视频. 下面给出我整理的两段代码: 1.边缘提取: // GetMySketch.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #in

图像处理------颜色梯度变化 (Color Gradient)

有过UI设计经验的一定对2D图形渲染中的Color Gradient 或多或少有些接触,很多编程 语言也提供了Gradient的接口,但是想知道它是怎么实现的嘛?   本文介绍三种简单的颜色梯度变化算法,就可以很容易实现常见的梯度变化算法 三种都要求提供两个参数即起始颜色RGB值, 最终颜色RGB的值.   垂直梯度颜色变化,效果如下:   水平梯度颜色变化,效果如下:   水平与垂直两个方向叠加梯度变化效果如下:   算法代码及其解释   计算起始颜色和终点颜色RGB之间差值代码如下: flo

图像处理------图像加噪

图像噪声源于现实世界中数字信号总会受到各种各样的干扰,最终接受的图像和源于的数字信号之间总 是存在一定的差异,对于图像噪声,使用均值滤波和中值滤波来消除图像噪声的做法已经是很常见的图 像消噪手段.   一:图像加噪原理 1.     椒盐噪声(Salt And Pepper Noise) 椒盐噪声是一种因为信号脉冲强度引起的噪声,信噪比(Signal NoiseRate)是衡量图像噪声的一个数字指标. 给一副数字图像加上椒盐噪声的处理顺序应该如下: 指定信噪比 SNR 其取值范围在[0, 1]之

Javascript图像处理—图像形态学(膨胀与腐蚀)_javascript技巧

前言 上一篇文章,我们讲解了图像处理中的阈值函数,这一篇文章我们来做膨胀和腐蚀函数. 膨胀与腐蚀 说概念可能很难解释,我们来看图,首先是原图: 膨胀以后会变成这样: 腐蚀以后则会变成这样: 看起来可能有些莫名其妙,明明是膨胀,为什么字反而变细了,而明明是腐蚀,为什么字反而变粗了. 实际上,所谓膨胀应该指: 较亮色块膨胀. 而所谓腐蚀应该指: 较亮色块腐蚀. 上面图里面,由于背景白色是较亮色块,所以膨胀时就把黑色较暗色块的字压扁了--相反腐蚀时,字就吸水膨胀了-- 用数学公式表示就是: 说白了就是