Sobel运算符仅适用于小图像



这个sobel运算符的想法是首先将每个像素的值放入数组中,然后将这些值分为三个数组,每个RGB分量一个。然后将包含RGB分量值的阵列中的每一个进行变换,然后将其组合成最终阵列以生成输出图像。

然而,它似乎只适用于350x350像素大小的较小图像,我不知道为什么。

我认为问题出在getRGB()和setRGB(。

public class Sobel {

private BufferedImage image;
public Sobel(BufferedImage image)
{
    this.image = image;
}
public BufferedImage process()
{
    double  A[][], B[][], Ar[][], Br[][], Ag[][], Bg[][], Ab[][], Bb[][], G[][], Gr[][], Gg[][], Gb[][];
    BufferedImage inImg =  image;
    int width = inImg.getWidth();   
    int height = inImg.getHeight();   
    int[] pixels = new int[width * height];   
    // RGB channels of the image
    int[][] red = new int[width][height];
    int[][] green = new int[width][height];
    int[][] blue = new int[width][height];
    try {
        image.getRGB(0, 0, width, height, pixels, 0, width);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    int counter = 0;   
    for(int i = 0 ; i < width ; i++ )   
    {   
        for(int j = 0 ; j < height ; j++ )   
        {   
            // get color of each pixel and separate it in the RGB components
            Color c = new Color(pixels[counter]);
            red[i][j] = c.getRed();
            green[i][j] = c.getGreen();
            blue[i][j] = c.getBlue();
            counter = counter + 1;   
        }              
    }   
// Arrays for RGB values (Ar, Br, Ag, Bg, Ab, Bb) which are than combined into final array for generating processed image  
A = new double[width][height];   
B = new double[width][height];
Ar = new double[width][height];   
Br = new double[width][height]; 
Ag = new double[width][height];   
Bg = new double[width][height];
Ab = new double[width][height];   
Bb = new double[width][height]; 
G  = new double[width][height];
Gr  = new double[width][height];
Gg  = new double[width][height];
Gb  = new double[width][height];

/**
 *  Transform pixel p of each RGB channel
 *  p = sqrt(A^2 + B^2),
 *  where A = (p3 + 2*p4 + p5) - (p1 + 2*p8 + p7)
 *   and  B = (p1 + 2*p2 + p3) - (p7 + 2*p6 + p5)
 *  
 *      Pixel p
 * 
 *      p1 p2 p3
 *      p8 p  p4
 *      p7 p6 p5
 */
for (int i=0; i<width; i++) {   
  for (int j=0; j<height; j++) {   
    if (i==0 || i==width-1 || j==0 || j==height-1)   
      A[i][j] = B[i][j] = G[i][j] = Ar[i][j] = Br[i][j] = Gr[i][j] = Ag[i][j] = Bg[i][j] = Gg[i][j] = Ab[i][j] = Bb[i][j] = Gb[i][j] = 0; // Image boundary cleared   
    else
    {   
        // RED CHANNEL
        Ar[i][j] = red[i-1][j+1] + 2*red[i][j+1] + red[i+1][j+1] - red[i-1][j-1] - 2*red[i][j-1] - red[i+1][j-1];   
        Br[i][j] = red[i-1][j-1] + 2*red[i-1][j] + red[i-1][j+1] - red[i+1][j-1] - 2*red[i+1][j] - red[i+1][j+1];
        Gr[i][j] = Math.sqrt(Ar[i][j]*Ar[i][j] + Br[i][j]*Br[i][j]);
        // GREEN CHANNEL
        Ag[i][j] = green[i-1][j+1] + 2*green[i][j+1] + green[i+1][j+1] - green[i-1][j-1] - 2*green[i][j-1] - green[i+1][j-1];   
        Bg[i][j] = green[i-1][j-1] + 2*green[i-1][j] + green[i-1][j+1] - green[i+1][j-1] - 2*green[i+1][j] - green[i+1][j+1];
        Gg[i][j] = Math.sqrt(Ag[i][j]*Ag[i][j] + Bg[i][j]*Bg[i][j]);
        // BLUE CHANNEL
        Ab[i][j] = blue[i-1][j+1] + 2*blue[i][j+1] + blue[i+1][j+1] - blue[i-1][j-1] - 2*blue[i][j-1] - blue[i+1][j-1];   
        Bb[i][j] = blue[i-1][j-1] + 2*blue[i-1][j] + blue[i-1][j+1] - blue[i+1][j-1] - 2*blue[i+1][j] - blue[i+1][j+1];
        //System.out.println(output[i][j]);
        Gb[i][j] = Math.sqrt(Ab[i][j]*Ab[i][j] + Bb[i][j]*Bb[i][j]);
        //if((int)Gg[i][j] > 255) System.out.println("GREEN : " + Gg[i][j] + " ~ " + (int)Gg[i][j] + "n" + green[i-1][j+1] + " " + green[i][j+1] + " " + green[i+1][j+1] + " " + green[i-1][j-1] + " " + green[i][j-1] + " " + green[i+1][j-1] + " " + green[i-1][j-1] + " " + green[i-1][j] + " " + green[i-1][j+1] + " " +  green[i+1][j] + " " + green[i+1][j] + " " + green[i+1][j+1]);
        if((int)Gg[i][j] > 255) {Gg[i][j] = 255; }
        if((int)Gb[i][j] > 255) {Gb[i][j] = 255; }
        if((int)Gr[i][j] > 255) {Gr[i][j] = 255; }

        G[i][j] = new Color((int)Gr[i][j], (int)Gg[i][j], (int)Gb[i][j]).getRGB();
    }   
  }   
}   
counter = 0;   
for(int ii = 0 ; ii < width ; ii++ )   
{   
    for(int jj = 0 ; jj < height ; jj++ )   
    {                  
        pixels[counter] = (int)G[ii][jj];   
        counter = counter + 1;   
    }              
}
BufferedImage outImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
System.out.println("pixels.length = " + pixels.length + "; Image size: " + outImg.getHeight() + "x" + outImg.getWidth());

//outImg.getRaster().setPixels(0,0,width,height,pixels);   
outImg.setRGB(0, 0, width, height, pixels, 0, width);
return outImg;
}

}

图像以行主格式存储。

因此,外循环应该在行上迭代(应该有height迭代),内循环应该在每行中的像素上迭代(应当有width迭代)。因此,基本上,除了对getRGB/setRGB的调用之外,您需要在任何地方交换widthheight

使用内部使用opencv 的javacv可以获得良好的结果

  IplImage iploriginal = IplImage.createFrom(originalBufferedImg);
  IplImage srcimg = IplImage.create(iploriginal.width(),iploriginal.height(), IPL_DEPTH_8U, 1);
  IplImage destimg = IplImage.create(iploriginal.width(),iploriginal.height(), IPL_DEPTH_8U, 1);
  cvCvtColor(iploriginal, srcimg, CV_BGR2GRAY);
  cvSmooth(srcimg, destimg, CV_BLUR,9, 9, 2, 2);
  cvSobel(srcimg, destimg,0,1,3);
  BufferedImage img=destimg.getBufferedImage();

相关内容

最新更新