Wie oben vorgeschlagen, berechnet der Matlab Canny-Kantendetektor den Gradienten unter Verwendung einer "Ableitung eines Gaußschen Filters" (wie in der Dokumentation angegeben). Mit anderen Worten, Matlab macht eine Gaußsche Unschärfe des Bildes und findet dann den Gradienten dieses geglätteten Bildes ... alles unter Verwendung eines einzigen ausgefallenen Filters. [Wenn Sie die Details wissen möchten, geben Sie einfach edit edge
wie von Andrey vorgeschlagen ein und scrollen Sie dann nach unten zur smoothGradient()
Funktion.]
Durch die Unschärfe wird das im Bild vorhandene Rauschen erheblich reduziert, wodurch viele störende Kanten vermieden werden und das gute Material zurückbleibt.
Leider können Sie mit der OpenCV Canny-Funktion den verwendeten Filterkern nicht über die Funktionsparameter ändern. Jedoch. Sie können dieselben Ergebnisse erzielen, indem Sie zuerst das Eingabebild verwischen und dieses unscharfe Bild dann an die Canny-Funktion übergeben.
Dadurch wird die resultierende Kantenabbildung erheblich bereinigt. Um das Eingabebild zu verwischen, verwende ich persönlich die OpenCV- GaussianBlur()
Funktion mit sigmaX=2
. Dies ahmt das Standard-Sigma in Matlab nach. Die beste verwischende Kernelgröße kann von Fall zu Fall variieren, wird jedoch in Matlab mit berechnet filterLength = 8*ceil(sigma);
, sodass für ein Sigma von 2 eine Kernelgröße von bedeuten würde(16,16)
Da sowohl der Gaußsche Unschärfe- als auch der Sobel-Filter linear sind, entspricht die Übergabe eines unscharfen Eingabebilds an die OpenCV- Canny()
Funktion mathematisch dem, was Matlab aufgrund des Überlagerungsprinzips tut, wie in diesem Pseudocode gezeigt (Anmerkung: *
ist der Faltungsoperator):
// The Matlab method: the sobel and blur operations are combined into
// a single filter, and that filter is then convolved with the image
matlabFancyFilter = (sobel * blur);
gradient = matlabFancyFilter * image;
// Equivalent method: image is first convolved with the blur filter, and
// then convolved with the sobel filter.
gradient = sobel * (blur * image); // image is filtered twice
Hier finden Sie ein OpenCV Canny-Tutorial, das zeigt, wie dies mit C ++ gemacht wird. Ich bin ein Python-Typ, also mache ich Folgendes:
smoothedInput = cv2.GaussianBlur(image, (7,7), 2);
edges = cv2.Canny(smoothedInput, 25, 50);