Ich schreibe Canny-Algorithmus, und ich habe ein Problem mit der Hysterese. Die Thresholds scheint zu verarbeiten, aber meine Hysterese scheint überhaupt nicht zu funktionieren. Sowie Methode entfernen schwach aus irgendeinem seltsamen Grund. Bitte helfen Sie!Canny Algorithmus: Hysterese Mal-Funktion
Low @ 10
Hoch @ 75
Nach Hysterese, mit Problem A, Kanten wurden stärken nicht mit Methode performHysteresis; B schwache Nicht-Kanten werden nicht mit der Methode removeWeak entfernt.
Quellcode für das Verfahren wie folgt:
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;
}
}
entschuldige dich nicht für Kommentare - Kommentare hinzufügen. Beides, um uns zu helfen, Ihren Code zu verstehen, und damit Sie nächste Woche Ihren eigenen Code verstehen können. Verknüpfen Sie auch nicht mit Code, von dem Sie glauben, dass er möglicherweise vor dem Kompilieren bearbeitet werden muss: Postleitzahl, die Sie kompilieren. Erinnere dich, wir sind nur Menschen, so wie du. Je mehr Zeit wir damit verbringen, Ihren Code zu verstehen oder sogar auszuführen, desto mehr gehen wir stattdessen zur nächsten Frage über. –
Danke für den Vorschlag, für Ihren Vorschlag habe ich Kommentare für die betreffende Klasse abgegeben und sichergestellt, dass die Klasse fehlerfrei kompiliert wird. Ich habe ein Problem mit meinem Code festgestellt, aber es gibt immer noch ein Problem in meiner Operation für und nach Hysterese, ich würde Ihre Hilfe sehr schätzen, wenn Sie eine anbieten können. – DVCode