繁体   English   中英

Java中的Sobel Edge Detection程序

[英]Sobel Edge Detecting program in java

我正在尝试用Java编写sobel边缘检测程序。 但是我得到了疲软的输出。 救命。 这是我的程序。

import java.io.*;
import java.awt.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.Scanner;
import java.lang.Math;

public class sobeltest
{
  public static void main(String args[]) throws IOException{

    System.out.println("Enter the file name :");
    Scanner ne1=new Scanner(System.in);
    String filename=ne1.nextLine();


   File file= new File(filename);
   BufferedImage image = ImageIO.read(file);

   int x=image.getWidth();
   int y=image.getHeight();

   for(int i=1;i<x-1;i++)
    {
     for(int j=1;j<y-1;j++)
      {

     int val00=image.getRGB(i-1,j-1);
     int val01=image.getRGB(i-1,j);
     int val02=image.getRGB(i-1,j+1);

     int val10=image.getRGB(i,j-1);
     int val11=image.getRGB(i,j);
     int val12=image.getRGB(i,j+1);

     int val20=image.getRGB(i+1,j-1);
     int val21=image.getRGB(i+1,j);
     int val22=image.getRGB(i+1,j+1);

     int gx=(((-1*val00)+(0*val01)+(1*val02))+((-2*val10)+(0*val11)+(2*val12))+((-1*val20)+(0*val21)+(1*val22)));
     int gy=(((-1*val00)+(-2*val01)+(-1*val02))+((0*val10)+(0*val11)+(0*val12))+((1*val20)+(2*val21)+(1*val22)));

     double gval=Math.sqrt((gx*gx)+(gy*gy));
     int g=(int)gval;

     image.setRGB(i,j,g);

      }
      }
    File outputfile = new File("sobel.png");
    ImageIO.write(image, "png", outputfile);
  }
  }

输入图像: 这是我给的输入图像

这是我运行代码时得到的输出。 输出图像

...............................................

您的代码有两个问题。 首先是代码应该在计算中使用颜色分量(R,G,B)而不是颜色整数本身。

int val00=image.getRGB(i-1,j-1);
//Should be
int val00 = getGrayScale(image.getRGB(i - 1, j - 1));

Where getGrayScale() gives the luminance of the color in gray scale, otherwise you can use all three components individually.

第二个问题是您直接将gcal or g渐变值设置为颜色。 同样,它应该仅是一种成分,并应使用g<<16 | g<<8 | g转换为颜色g<<16 | g<<8 | g g<<16 | g<<8 | g g<<16 | g<<8 | g

但是g不一定在0-255范围内,因此我们必须通过找到max g然后使用255/max(g)归一化所有梯度来解决这一问题。

以下是工作代码。

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class SobelTest {
    public static void main(String args[]) throws IOException {

        System.out.println("Started");
        /*System.out.println("Enter the file name :");
        Scanner ne1 = new Scanner(System.in);
        String filename = ne1.nextLine();*/

        String filename = "engine.png";

        File file = new File(filename);
        BufferedImage image = ImageIO.read(file);

        int x = image.getWidth();
        int y = image.getHeight();

        int maxGval = 0;
        int[][] edgeColors = new int[x][y];
        int maxGradient = -1;

        for (int i = 1; i < x - 1; i++) {
            for (int j = 1; j < y - 1; j++) {

                int val00 = getGrayScale(image.getRGB(i - 1, j - 1));
                int val01 = getGrayScale(image.getRGB(i - 1, j));
                int val02 = getGrayScale(image.getRGB(i - 1, j + 1));

                int val10 = getGrayScale(image.getRGB(i, j - 1));
                int val11 = getGrayScale(image.getRGB(i, j));
                int val12 = getGrayScale(image.getRGB(i, j + 1));

                int val20 = getGrayScale(image.getRGB(i + 1, j - 1));
                int val21 = getGrayScale(image.getRGB(i + 1, j));
                int val22 = getGrayScale(image.getRGB(i + 1, j + 1));

                int gx =  ((-1 * val00) + (0 * val01) + (1 * val02)) 
                        + ((-2 * val10) + (0 * val11) + (2 * val12))
                        + ((-1 * val20) + (0 * val21) + (1 * val22));

                int gy =  ((-1 * val00) + (-2 * val01) + (-1 * val02))
                        + ((0 * val10) + (0 * val11) + (0 * val12))
                        + ((1 * val20) + (2 * val21) + (1 * val22));

                double gval = Math.sqrt((gx * gx) + (gy * gy));
                int g = (int) gval;

                if(maxGradient < g) {
                    maxGradient = g;
                }

                edgeColors[i][j] = g;
            }
        }

        double scale = 255.0 / maxGradient;

        for (int i = 1; i < x - 1; i++) {
            for (int j = 1; j < y - 1; j++) {
                int edgeColor = edgeColors[i][j];
                edgeColor = (int)(edgeColor * scale);
                edgeColor = 0xff000000 | (edgeColor << 16) | (edgeColor << 8) | edgeColor;

                image.setRGB(i, j, edgeColor);
            }
        }

        File outputfile = new File("sobel.png");
        ImageIO.write(image, "png", outputfile);

        System.out.println("max : " + maxGradient);
        System.out.println("Finished");
    }

    public static int  getGrayScale(int rgb) {
        int r = (rgb >> 16) & 0xff;
        int g = (rgb >> 8) & 0xff;
        int b = (rgb) & 0xff;

        //from https://en.wikipedia.org/wiki/Grayscale, calculating luminance
        int gray = (int)(0.2126 * r + 0.7152 * g + 0.0722 * b);
        //int gray = (r + g + b) / 3;

        return gray;
    }
}

输出量

在此处输入图片说明

编辑

第二张图片包含与第一张图片相对的Alpha通道,请在下面查看两者的详细信息。

#Engine
type = 5 ColorModel: #pixelBits = 24 numComponents = 3 has alpha = false
#Type 5 is BufferedImage.TYPE_3BYTE_BGR
#Girl
type = 6 ColorModel: #pixelBits = 32 numComponents = 4 has alpha = true
#type 6 is BufferedImagef.TYPE_4BYTE_ABGR

由于第二个图像包含Alpha分量,并且我们未设置Alpha,因此它变得完全透明。

接下来的部分代码需要更改以将alpha设置为不透明。

edgeColor = (edgeColor << 16) | (edgeColor << 8) | edgeColor;
//Should be
edgeColor = 0xff000000 | (edgeColor << 16) | (edgeColor << 8) | edgeColor;

我已经用相同的方法更改了上面的原始代码。

这是带有更改的输出。

在此处输入图片说明

要获得注释中图像中的边缘,您将必须基于渐变的方向对边缘进行分组,并使用适当的阈值来忽略弱边缘。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM