2014-12-17 2 views
7

나는 Canny 's Algorithm을 쓰고 있는데, 나는 히스테리 시스에 문제가있는 것 같다. 임계 값이 처리되는 것처럼 보이지만 히스테리시스가 전혀 작동하지 않는 것 같습니다. 방법뿐만 아니라 어떤 이상한 이유로 약한 제거합니다. 도와주세요!Canny 's Algorithm : Hysteresis Mal-function

Low @ 10 낮은 10 High @ 75 높은 75 After Hysteresis 히스테리시스 후, 문제 A를, 가장자리 방법 performHysteresis으로 강화되지 않은 @ @; B 약한 비 에지는 removeWeak 메소드로 제거되지 않습니다. 방법에 대한

소스 코드는 다음과 같이이 :

import java.awt.image.BufferedImage; 
import java.awt.image.ConvolveOp; 
import java.awt.image.Kernel; 

class CannyMethod { 

private static final float[] sobelX = { 1.0f, 0.0f, -1.0f, 
             2.0f, 0.0f, -2.0f, 
             1.0f, 0.0f, -1.0f}; 
private static final float[] sobelY = { 1.0f, 2.0f, 1.0f, 
             0.0f, 0.0f, 0.0f, 
             -1.0f,-2.0f,-1.0f}; 
private static int low, high; 


public CannyMethod() {} 

private ConvolveOp getSobel(boolean xy) { 
    Kernel kernel; 
    if (xy) kernel = new Kernel(3, 3, sobelX); 
    else kernel = new Kernel(3, 3, sobelY); 

    return new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null); 
} 

public BufferedImage getCannyFilter(BufferedImage img) { 
    return getCannyFilter(img, low, high); 
} 

public BufferedImage getCannyFilter(BufferedImage img, int l, int h) { 
    int width = img.getWidth(); 
    int height = img.getHeight(); 
    low = l; 
    high = h; 

    int size = width * height; 
    int[] x = new int[size]; 
    int[] y = new int[size]; 
    int[] pixelM = new int[size]; 
    double[] pixelD = new double[size]; 
    int[] pixelNew = new int[size]; 

    BufferedImage sobelXImg = getSobel(true).filter(img, null); 
    BufferedImage sobelYImg = getSobel(false).filter(img, null); 


    // returns arrays for x and y direction after convultion with Sobel Operator 
    sobelXImg.getRaster().getPixels(0, 0, width, height, x); 
    sobelYImg.getRaster().getPixels(0, 0, width, height, y); 

// Calculates Gradient and Magnitude 
    for(int i = 0; i < size; i++) { 
     pixelM[i] = (int) Math.hypot(x[i], y[i]); 
     pixelD[i] = Math.atan2((double) y[i], (double) x[i]); 
    } 

//Operations for Canny Algorithm takes magnitude and gradient and input into new array fo WritableRaster 
    normalizeDirection(pixelD); 
    nonMaximaSupression(pixelM, pixelD, pixelNew, width, height); 
    performHysteresis(pixelNew, width); 
    removeWeak(pixelNew); 

    BufferedImage result = 
     new BufferedImage(width, height, 
          BufferedImage.TYPE_BYTE_GRAY); 
    result.getRaster().setPixels(0, 0, width, height, pixelNew); 

    return result; 
} 

private void normalizeDirection(double[] dArray) { 
//Round degrees 

    double pi = Math.PI; 
    for(double i : dArray) { 
     if (i < pi/8d && i >= -pi/8d) i = 0; 
     else if (i < 3d*pi/8d && i >= pi/8d) i = 45; 
     else if (i < -3d*pi/8d || i >= 3d*pi/8d) i = 90; 
     else if (i < -pi/8d && i >= -3d*pi/8d) i = 135; 
    } 
} 

private void nonMaximaSupression(int[] pixelM, double[] pixelD, 
    int[] pixelNew, int width, int height) { 
//non-Maxima Supression 
//Since array is not in 2-D, positions are calulated with width - functions properly 

    for(int i = 0; i < pixelNew.length; i++) { 
     if (i % width == 0 || (i + 1) % width == 0 || 
      i <= width || i >= width * height - 1) pixelNew[i] = 0; 
     else { 
      switch ((int) pixelD[i]) { 
       case 0: if (pixelM[i] > pixelM[i+1] 
          && pixelM[i] > pixelM[i-1]) 
          setPixel(i, pixelM[i], pixelNew); 
         else pixelNew[i] = 0; 
         break; 
       case 45: if (pixelM[i] > pixelM[i+(width-1)] 
          && pixelM[i] > pixelM[i-(width-1)]) 
          setPixel(i, pixelM[i], pixelNew); 
         else pixelNew[i] = 0; 
         break; 
       case 90: if (pixelM[i] > pixelM[i+width] 
          && pixelM[i] > pixelM[i-width]) 
          setPixel(i, pixelM[i], pixelNew); 
         else pixelNew[i] = 0; 
         break; 
       case 135:if (pixelM[i] > pixelM[i+width] 
          && pixelM[i] > pixelM[i-width]) 
          setPixel(i, pixelM[i], pixelNew); 
         else pixelNew[i] = 0; 
         break; 
       default: pixelNew[i] = 0; 
      } 
     } 
    } 
} 

private void performHysteresis(int[] array, int width) { 
//performs hysteresis 

    int[] temp; 
    for(int i = width; i < array.length - width; i++) { 
     if (i % width == 0 || (i + 1) % width == 0) {} 
     else { 
      if (array[i] == 255) { 
    //found strong one, track surrounding weak ones 
    //temp is the positions of surrounding pixels 
       temp = new int[] 
        {i - (width + 1), i - width, i - (width - 1), 
        i - 1,      i + 1, 
        i + (width - 1), i + width, i + (width + 1)}; 
       trackWeak(array, temp, width); 
      } 
     } 
    } 
} 

private void trackWeak(int[] array, int[] pos, int width) { 
    int[] temp; 
    for (int i : pos) { 
     if (array[i] > 0 && array[i] < 255) { 
      array[i] = 255; 
    //set weak one to strong one 

      if (i % width == 0 || (i + 1) % width == 0) {} 
      else { 
    //temp is the positions of surrounding pixels 
       temp = new int[] 
        {i - (width + 1), i - width, i - (width - 1), 
        i - 1,      i + 1, 
        i + (width - 1), i + width, i + (width + 1)}; 
       trackWeak(array, temp, width); 
      } 
     } 
    } 
} 

private void removeWeak(int[] array) { 
//remove remaining weak ones from lew Threshold 

    for(int i : array) { 
     if (i < 255) {i = 0;} 
    } 
} 

private void setPixel(int pos, int value, int[] pixelNew) { 
    if (value > high) pixelNew[pos] = 255; 
    else if (value > low) pixelNew[pos] = 128; 
    else pixelNew[pos] = 0; 
} 

public void setThreshold(int l, int h) { 
    low = l; 
    high = h; 
} 
} 
+3

의견이 없으므로 사과하지 마세요. 의견을 추가하십시오. 둘 다 우리의 코드를 이해하는 데 도움이되며 다음 주에 코드를 이해할 수 있습니다. 또한 컴파일하기 전에 편집해야 할 것으로 생각되는 코드 (컴파일 한 게시 코드)에 연결하지 마십시오. 기억하세요, 우리는 당신과 아주 흡사 한 인간입니다. 코드를 이해하고 실행하기 위해 더 많은 시간을 할애해야 할수록 다음 질문으로 넘어갈 것입니다. –

+0

제안 해 주셔서 감사합니다. 귀하의 제안에 따라 문제의 수업에 대한 의견을 말하고 수업이 오류없이 컴파일되었는지 확인했습니다. 내 코드로 한 가지 문제를 알아 냈습니다. 그러나 히스테리시스에 대한 작업 및 게시에는 여전히 문제가 있습니다. 제공 할 수 있다면 귀하의 도움에 크게 감사드립니다. – DVCode

답변

2

나는 그것을 알아 냈다. 히스테리시스가 작동하고 있었기 때문에 이미지의 품질을 알기 란 어려웠습니다.

제거 약점에 대해서는 향상된 for 루프를 사용했는데 실제로 배열 자체의 요소가 아니라 요소의 복사본 만 가져오고 변경된다는 것을 알기 시작했습니다. 루프를 일반 for 루프로 변경하면 효과적입니다!