2014-12-17 8 views
7

Sto scrivendo Algoritmo di Canny e mi sembra di avere un problema con l'isteresi. Le soglie Appare da elaborare, tuttavia la mia isteresi non sembra funzionare affatto. Così come il metodo rimuove debole per qualche strana ragione. Per favore aiuto!Algoritmo di Canny: Isteresi Mal funzione

Low @ 10 basso @ 10 High @ 75 alta @ 75 After Hysteresis Dopo isteresi, con il problema A, bordi erano non rafforzano con metodo performHysteresis; I B non-edge deboli non vengono rimossi con il metodo removeWeak.

Il codice sorgente per il metodo come segue:

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

non chiedere scusa per non aver commenti - aggiungere commenti. Sia per aiutarci a capire il tuo codice, sia per farti capire il tuo codice la prossima settimana. Inoltre, non collegare al codice che pensi possa aver bisogno di noi per modificarlo prima di compilarlo: codice postale che conosci compilare. Ricorda, siamo solo umani, proprio come te. Più tempo avremo bisogno di spendere per capire o persino eseguire il tuo codice, più passeremo alla domanda successiva. –

+0

Grazie per il suggerimento, per il tuo suggerimento ho fatto commenti per la classe in questione e mi sono assicurato che la classe si compili senza errori. Ho trovato un problema con il mio codice, tuttavia c'è ancora un problema nel mio funzionamento e post isteresi, apprezzerei molto il tuo aiuto se puoi offrirne uno. – DVCode

risposta

2

ho capito. L'isteresi stava funzionando, era solo difficile da dire data la qualità dell'immagine.

Per quanto riguarda la rimozione deboli, ho utilizzato il ciclo avanzato per che sto iniziando a vedere che solo una copia dell'elemento viene ottenuta e modificata, non in realtà l'elemento nella matrice stessa. Una volta che l'ho cambiato in un ciclo regolare, ha funzionato!