public void ComputeGradient(Arr source, GradientOperator gradientOperator, double gradientThreshold) { // gaussian filtering CV.Smooth(source, _smoothed, SmoothMethod.Gaussian, 5, 5, 1.0); // calculate gradients switch (gradientOperator) { case GradientOperator.Prewitt: CV.Filter2D(_smoothed, _gradientX, PrewittX); CV.Filter2D(_smoothed, _gradientY, PrewittY); if (gradientThreshold < 0.0) { gradientThreshold = 6.0; } break; case GradientOperator.Sobel: CV.Sobel(_smoothed, _gradientX, 1, 0); CV.Sobel(_smoothed, _gradientY, 0, 1); break; case GradientOperator.Scharr: CV.Sobel(_smoothed, _gradientX, 1, 0, -1); CV.Sobel(_smoothed, _gradientY, 0, 1, -1); break; default: throw new Exception($"Unknown gradient operator: {gradientOperator}"); } // calculate absolute values for gradients CV.ConvertScaleAbs(_gradientX, _absGradientX); CV.ConvertScaleAbs(_gradientY, _absGradientY); // merge gradients // d = 0.5 * abs(dx) + 0.5 * abs(dy) CV.AddWeighted(_absGradientX, 0.5, _absGradientY, 0.5, 0.0, GradientMap); // eliminate gradient weak pixels CV.Threshold(GradientMap, GradientMap, gradientThreshold, 255, ThresholdTypes.ToZero); // edge direction // abs(dx) >= abs(dy) => VERTICAL CV.Cmp(_absGradientX, _absGradientY, DirectionMap, ComparisonOperation.GreaterOrEqual); }