在ImageJ中实现Sobel滤波器

时间:2013-10-12 07:03:25

标签: java math image-processing imagej

你好我试图通过创建我自己的插件在imagej中实现一个Sobel过滤器。我有代码可以工作,但它没有正确突出边缘白色。我已经尝试了一段时间,我只是无法弄清楚我做错了什么,或者我不能完全理解索贝尔滤波器的植入和/或不理解数学。任何帮助将不胜感激。这是我的代码:

import ij.*;
import ij.process.*;
import ij.gui.*;
import java.util.*;
import java.awt.*;
import ij.plugin.filter.*;
import ij.process.*;
import java.lang.Math.*;

public class Filter_Plugin implements PlugInFilter {
String title = null; 

int sobel_x[][] = {{-1,0,1},
                        {-2,0,2},
                            {-1,0,1}};

        int sobel_y[][] = {{-1,-2,-1},
                            {0,0,0},
                            {1,2,1}};

int pixel_x;
int pixel_y;

public int setup(String arg, ImagePlus im) { 
    title = im.getTitle(); 
    return DOES_8G; 
} 

public void run(ImageProcessor ip) { 

    int w = ip.getWidth();
    int h = ip.getHeight();
    ImageProcessor copy = ip.duplicate(); 

     for (int x=1; x < w-2; x++) 
     {
            for (int y=1; y < h-2; y++) 
        {
            pixel_x = 1/6 * (sobel_x[0][0] * copy.getPixel(x-1,y-1)) + (sobel_x[0][1] * copy.getPixel(x,y-1)) + (sobel_x[0][2] * copy.getPixel(x+1,y-1)) +
                    (sobel_x[1][0] * copy.getPixel(x-1,y))   + (sobel_x[1][1] * copy.getPixel(x,y))   + (sobel_x[1][2] * copy.getPixel(x+1,y)) +
                            (sobel_x[2][0] * copy.getPixel(x-1,y+1)) + (sobel_x[2][1] * copy.getPixel(x,y+1)) + (sobel_x[2][2] * copy.getPixel(x+1,y+1));

            pixel_y = 1/6 * (sobel_y[0][0] * copy.getPixel(x-1,y-1)) + (sobel_y[0][1] * copy.getPixel(x,y-1)) + (sobel_y[0][2] * copy.getPixel(x+1,y-1)) +
                    (sobel_y[1][0] * copy.getPixel(x-1,y))   + (sobel_y[1][1] * copy.getPixel(x,y))   + (sobel_y[1][2] * copy.getPixel(x+1,y)) +
                            (sobel_y[2][0] * copy.getPixel(x-1,y+1)) + (sobel_y[2][1] * copy.getPixel(x,y+1)) + (sobel_x[2][2] * copy.getPixel(x+1,y+1));

            int val = (int)Math.sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y));

            if(val < 0)
            {
               val = 0;
            }

            if(val > 255)
            {
                  val = 255;
            }

            ip.putPixel(x,y,val);

             }
        }
 }

}

1 个答案:

答案 0 :(得分:5)

计算中出现错误:您只乘以1/6的第一个加数(即矩阵的左上角)。通过删除此因素,我得到以下适用于我的代码:

import ij.*;
import ij.process.*;
import ij.gui.*;
import java.util.*;
import java.awt.*;
import ij.plugin.filter.*;
import ij.process.*;
import java.lang.Math.*;

public class Filter_Plugin implements PlugInFilter {
    String title = null; 
    int sobel_x[][] = {{-1,0,1},
                       {-2,0,2},
                       {-1,0,1}};
    int sobel_y[][] = {{-1,-2,-1},
                       {0,0,0},
                       {1,2,1}};
    int pixel_x;
    int pixel_y;

    public int setup(String arg, ImagePlus im) { 
        title = im.getTitle(); 
        return DOES_8G; 
    } 

    public void run(ImageProcessor ip) { 
        int w = ip.getWidth();
        int h = ip.getHeight();
        ImageProcessor copy = ip.duplicate(); 
        for (int x=1; x < w-2; x++) {
            for (int y=1; y < h-2; y++) {
                pixel_x = (sobel_x[0][0] * copy.getPixel(x-1,y-1)) + (sobel_x[0][1] * copy.getPixel(x,y-1)) + (sobel_x[0][2] * copy.getPixel(x+1,y-1)) +
                    (sobel_x[1][0] * copy.getPixel(x-1,y))   + (sobel_x[1][1] * copy.getPixel(x,y))   + (sobel_x[1][2] * copy.getPixel(x+1,y)) +
                    (sobel_x[2][0] * copy.getPixel(x-1,y+1)) + (sobel_x[2][1] * copy.getPixel(x,y+1)) + (sobel_x[2][2] * copy.getPixel(x+1,y+1));
                pixel_y = (sobel_y[0][0] * copy.getPixel(x-1,y-1)) + (sobel_y[0][1] * copy.getPixel(x,y-1)) + (sobel_y[0][2] * copy.getPixel(x+1,y-1)) +
                    (sobel_y[1][0] * copy.getPixel(x-1,y))   + (sobel_y[1][1] * copy.getPixel(x,y))   + (sobel_y[1][2] * copy.getPixel(x+1,y)) +
                    (sobel_y[2][0] * copy.getPixel(x-1,y+1)) + (sobel_y[2][1] * copy.getPixel(x,y+1)) + (sobel_x[2][2] * copy.getPixel(x+1,y+1));

                int val = (int)Math.sqrt((pixel_x * pixel_x) + (pixel_y * pixel_y));

                if(val < 0)
                {
                   val = 0;
                }

                if(val > 255)
                {
                   val = 255;
                }

                ip.putPixel(x,y,val);
            }
        }
    }
}

您是否看过Stephan Preibisch's Sobel Filter Plugin作为参考?

也许您应该将输出设为32位浮点图像,而不是将值截断为0和255.