天天看點

圖像處理------圖像梯度效果

基本思想:

利用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);  

}