public static Sobel Sobel(float[,] input, int min = 1, int max = 2) { var width = input.GetLength(0); var height = input.GetLength(1); var result = new Sobel(width, height); Parallel.For(1, width - 1, x => { for (var y = 1; y < height - 1; y++) { var gx = input[x + 1, y - 1] * min + input[x + 1, y] * max + input[x + 1, y + 1] * min - input[x - 1, y - 1] * min - input[x - 1, y] * max - input[x - 1, y + 1] * min; var gy = input[x - 1, y + 1] * min + input[x, y + 1] * max + input[x + 1, y + 1] * min - input[x - 1, y - 1] * min - input[x, y - 1] * max - input[x + 1, y - 1] * min; result.Magnitude[x, y] = Math.Abs(gx) + Math.Abs(gy); result.Horizontal[x, y] = gx; result.Vertical[x, y] = gy; } }); return(result); }
public static float[,] Canny(Sobel sobel, int min, int max) { var width = sobel.Orientation.GetLength(0); var height = sobel.Orientation.GetLength(1); var result = new float[width, height]; Parallel.For(1, width - 1, x => { for (var y = 0; y < height - 1; y++) { result[x, y] = sobel.Magnitude[x, y]; } }); // Non maximum supression for (var x = 1; x < width - 1; x++) { for (var y = 1; y < height - 1; y++) { var gx = sobel.Horizontal[x, y]; var gy = sobel.Vertical[x, y]; var magnitude = sobel.Magnitude[x, y]; var orientation = Math.Atan2(gy, gx) * 180f / Math.PI; //if (orientation >= 0 && orientation <= 45 || // orientation < -135 && orientation >= -180) //{ // var yBot = new[] // { // sobel.Magnitude[x, y + 1], sobel.Magnitude[x + 1, y + 1] // }; // var yTop = new[] // { // sobel.Magnitude[x, y - 1], sobel.Magnitude[x - 1, y - 1] // }; // var xEst = Math.Abs(gy / magnitude); // if (magnitude >= (yBot[1] - yBot[0]) * xEst + yBot[0] && // magnitude >= (yTop[1] - yTop[0]) * xEst + yTop[0]) // { // result[x, y] = magnitude; // } // else // { // result[x, y] = 0; // } // continue; //} //if (orientation > 45 && orientation <= 90 || // orientation < -90 && orientation >= -135) //{ // var yBot = new[] // { // sobel.Magnitude[x + 1, y], sobel.Magnitude[x + 1, y + 1] // }; // var yTop = new[] // { // sobel.Magnitude[x - 1, y], sobel.Magnitude[x - 1, y - 1] // }; // var xEst = Math.Abs(gy / magnitude); // if (magnitude >= (yBot[1] - yBot[0]) * xEst + yBot[0] && // magnitude >= (yTop[1] - yTop[0]) * xEst + yTop[0]) // { // result[x, y] = magnitude; // } // else // { // result[x, y] = 0; // } // continue; //} //if (orientation > 90 && orientation <= 135 || // orientation < -45 && orientation >= -90) //{ // var yBot = new[] // { // sobel.Magnitude[x + 1, y], sobel.Magnitude[x + 1, y - 1] // }; // var yTop = new[] // { // sobel.Magnitude[x - 1, y], sobel.Magnitude[x - 1, y + 1] // }; // var xEst = Math.Abs(gy / magnitude); // if (magnitude >= (yBot[1] - yBot[0]) * xEst + yBot[0] && // magnitude >= (yTop[1] - yTop[0]) * xEst + yTop[0]) // { // result[x, y] = magnitude; // } // else // { // result[x, y] = 0; // } // continue; //} //if (orientation > 135 && orientation <= 180 || // orientation < 0 && orientation >= -45) //{ // var yBot = new[] // { // sobel.Magnitude[x, y - 1], sobel.Magnitude[x + 1, y - 1] // }; // var yTop = new[] // { // sobel.Magnitude[x, y + 1], sobel.Magnitude[x - 1, y + 1] // }; // var xEst = Math.Abs(gy / magnitude); // if (magnitude >= (yBot[1] - yBot[0]) * xEst + yBot[0] && // magnitude >= (yTop[1] - yTop[0]) * xEst + yTop[0]) // { // result[x, y] = magnitude; // } // else // { // result[x, y] = 0; // } //} // E-W if (orientation <= 22.5 && orientation >= -22.5 || orientation >= 157.5 || orientation <= -157.5) { if (magnitude < sobel.Magnitude[x - 1, y] || magnitude < sobel.Magnitude[x + 1, y]) { result[x, y] = 0; } } // N-S if (orientation >= 67.5 && orientation <= 112.5 || orientation >= -112.5 && orientation <= -67.5) { if (magnitude < sobel.Magnitude[x, y - 1] || magnitude < sobel.Magnitude[x, y + 1]) { result[x, y] = 0; } continue; } // SE-NW if (orientation <= -112.5 && orientation >= -157.5 || orientation >= 22.5 && orientation <= 67.5) { if (magnitude < sobel.Magnitude[x - 1, y - 1] || magnitude < sobel.Magnitude[x + 1, y + 1]) { result[x, y] = 0; } continue; } if (orientation <= 157.5 && orientation >= 112.5 || orientation >= -67.5 && orientation <= -22.5) { if (magnitude < sobel.Magnitude[x + 1, y - 1] || magnitude < sobel.Magnitude[x - 1, y + 1]) { result[x, y] = 0; } continue; } } } ; return(result);// Hysteresis(result, min, max); }