天天看点

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

基本思想:

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

使用的两种微分算子分别为prewitt与sobel,其中soble在x, y两个方向算子分别为:

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

prewitt在x, y方向上梯度算子分别为:

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

二:程序思路及实现

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

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

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

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

 三:运行效果

原图像如下:

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

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

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

该滤镜的源代码如下:

package com.process.blur.study;  

import java.awt.image.bufferedimage;  

/** 

 *  

 * @author gloomy-fish 

 * @date 2012-06-11 

 * prewitt operator  

 * x-direction 

 * -1, 0, 1 

 * y-direction 

 * -1, -1, -1 

 *  0,  0,  0 

 *  1,  1,  1 

 *   

 * sobel operator 

 * -2, 0, 2 

 * -1, -2, -1 

 *  1,  2,  1 

 * 

 */  

public class gradientfilter extends abstractbufferedimageop {  

    // prewitt operator  

    public final static int[][] prewitt_x = new int[][]{{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}};  

    public final static int[][] prewitt_y = new int[][]{{-1, -1, -1}, {0,  0,  0}, {1,  1,  1}};  

    // sobel operator  

    public final static int[][] sobel_x = new int[][]{{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};  

    public final static int[][] sobel_y = new int[][]{{-1, -2, -1}, {0,  0,  0}, {1,  2,  1}};  

    // direction parameter  

    public final static int x_direction = 0;  

    public final static int y_direction = 2;  

    public final static int xy_direction = 4;  

    private int direction;  

    private boolean issobel;  

    public gradientfilter() {  

        direction = xy_direction;  

        issobel = true;  

    }  

    public void setsoble(boolean sobel) {  

        this.issobel = sobel;  

    public int getdirection() {  

        return direction;  

    public void setdirection(int direction) {  

        this.direction = direction;  

    @override  

    public bufferedimage filter(bufferedimage src, bufferedimage dest) {  

        int width = src.getwidth();  

        int height = src.getheight();  

        if (dest == null )  

            dest = createcompatibledestimage( src, null );  

        int[] inpixels = new int[width*height];  

        int[] outpixels = new int[width*height];  

        getrgb( src, 0, 0, width, height, inpixels );  

        int index = 0, index2 = 0;  

        double xred = 0, xgreen = 0, xblue = 0;  

        double yred = 0, ygreen = 0, yblue = 0;  

        int newrow, newcol;  

        for(int row=0; row<height; row++) {  

            int ta = 255, tr = 0, tg = 0, tb = 0;  

            for(int col=0; col<width; col++) {  

                index = row * width + col;  

                for(int subrow = -1; subrow <= 1; subrow++) {  

                    for(int subcol = -1; subcol <= 1; subcol++) {  

                        newrow = row + subrow;  

                        newcol = col + subcol;  

                        if(newrow < 0 || newrow >= height) {  

                            newrow = row;  

                        }  

                        if(newcol < 0 || newcol >= width) {  

                            newcol = col;  

                        index2 = newrow * width + newcol;  

                        tr = (inpixels[index2] >> 16) & 0xff;  

                        tg = (inpixels[index2] >> 8) & 0xff;  

                        tb = inpixels[index2] & 0xff;  

                        if(issobel) {  

                            xred += (sobel_x[subrow + 1][subcol + 1] * tr);  

                            xgreen +=(sobel_x[subrow + 1][subcol + 1] * tg);  

                            xblue +=(sobel_x[subrow + 1][subcol + 1] * tb);  

                            yred += (sobel_y[subrow + 1][subcol + 1] * tr);  

                            ygreen +=(sobel_y[subrow + 1][subcol + 1] * tg);  

                            yblue +=(sobel_y[subrow + 1][subcol + 1] * tb);  

                        } else {  

                            xred += (prewitt_x[subrow + 1][subcol + 1] * tr);  

                            xgreen +=(prewitt_x[subrow + 1][subcol + 1] * tg);  

                            xblue +=(prewitt_x[subrow + 1][subcol + 1] * tb);  

                            yred += (prewitt_y[subrow + 1][subcol + 1] * tr);  

                            ygreen +=(prewitt_y[subrow + 1][subcol + 1] * tg);  

                            yblue +=(prewitt_y[subrow + 1][subcol + 1] * tb);  

                    }  

                }  

                double mred = math.sqrt(xred * xred + yred * yred);  

                double mgreen = math.sqrt(xgreen * xgreen + ygreen * ygreen);  

                double mblue = math.sqrt(xblue * xblue + yblue * yblue);  

                if(xy_direction == direction)   

                {  

                    outpixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);  

                }   

                else if(x_direction == direction)  

                    outpixels[index] = (ta << 24) | (clamp((int)yred) << 16) | (clamp((int)ygreen) << 8) | clamp((int)yblue);  

                else if(y_direction == direction)   

                    outpixels[index] = (ta << 24) | (clamp((int)xred) << 16) | (clamp((int)xgreen) << 8) | clamp((int)xblue);  

                else   

                    // as default, always xy gradient  

                // cleanup for next loop  

                newrow = newcol = 0;  

                xred = xgreen = xblue = 0;  

                yred = ygreen = yblue = 0;  

            }  

        }  

        setrgb(dest, 0, 0, width, height, outpixels );  

        return dest;  

    public static int clamp(int value) {  

        return value < 0 ? 0 : (value > 255 ? 255 : value);  

}