2017-01-04 9 views
-1

私はソーベルエッジ検出プログラムをjavaで記述しようとしています。しかし、私は厄介な出力を得ています。助けて。ここに私のプログラムです。ソーベルエッジ検出プログラムin java

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); 
    } 
    } 

入力画像:ここ This is input image i given

とは、私は、コードを実行したときに私が得る出力されます。 OUTPUT IMAGE

は2があり

+0

レコードのためだけに:あなたはここに来ることはできません。あなたは良い質問をしようとします。私たちは何をしているのかを見ます。しかし、まれにそれは誰かがあなたの上に働く解決策を落とすことを意味します!その意味では、単にそのようなステートメントを避けてください。彼らは少し上に来る可能性があります...無礼... – GhostCat

+0

ごめんなさい –

+0

ヒント:あなたの質問を編集することができます;-) – GhostCat

答えて

3

を......................あなたのコードに関する問題。まず、コードでは、カラー整数そのものではなく、計算で色成分(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は必ずしも範囲0-255にあるわけではないので、最大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; 
    } 
} 

出力

enter image description here

編集

第二の画像は、最初の1に反対アルファチャンネルが含まれている、以下の両方の詳細を参照してください。

#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 

第2の画像にはアルファ成分が含まれており、アルファを設定していないので完全に透明になります。

コードの次の部分を変更して、アルファを不透明にする必要があります。

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

これまでのコードを変更しました。

ここに変更が出力されます。

enter image description here

あなたのコメントでは、画像のようにエッジが、あなたは勾配の方向に基づいてグループのエッジにあり、弱いエッジを無視するように、適切なしきい値を使用します取得します。

+0

ありがとうございました –

+0

よろしくお願いします! – 11thdimension

+0

Mr.11次元。このアルゴリズムを適用したとき。次の画像では機能しませんでした。リンク:https://upload.wikimedia.org/wikipedia/commons/2/20/%C3%84%C3%A4retuvastuse_n%C3%A4ide.pngこれは空白になりました。なぜ –

関連する問題