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
basso @ 10 alta @ 75 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;
}
}
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. –
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