KI‑Kompass
Kompass

Kanten und Konturen

Sobel, Canny und findContours: wie man Umrisse findet, zählt und vermisst, ohne ein einziges Modell zu trainieren.

·2 Min. Lesezeit·Von Fachredaktion Technik
DETAILGRAD
3 Abschnitte

Die Idee

Wo ein Bild von hell nach dunkel springt, ist eine Kante. Ein Rechner findet diese Stellen, indem er benachbarte Pixel voneinander abzieht: kleiner Unterschied bedeutet Fläche, großer Unterschied bedeutet Kante.

Wozu es gut ist

  • Teile auf einem Förderband zählen.
  • Prüfen, ob ein Bauteil den richtigen Umriss hat.
  • Ein Dokument im Foto finden und entzerren.
  • Linien, Kreise und Rechtecke messen.

Canny mit automatischen Schwellwerten

import cv2, numpy as np

def canny_auto(grau, sigma=0.33):
    v = float(np.median(grau))
    unten = int(max(0, (1.0 - sigma) * v))
    oben  = int(min(255, (1.0 + sigma) * v))
    return cv2.Canny(grau, unten, oben)

img  = cv2.imread("teile.jpg")
grau = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
grau = cv2.GaussianBlur(grau, (5, 5), 0)     # ohne das: Rauschkanten
kanten = canny_auto(grau)

konturen, _ = cv2.findContours(kanten, cv2.RETR_EXTERNAL,
                               cv2.CHAIN_APPROX_SIMPLE)

for k in konturen:
    flaeche = cv2.contourArea(k)
    if flaeche < 800:
        continue
    umfang = cv2.arcLength(k, True)
    ecken  = cv2.approxPolyDP(k, 0.02 * umfang, True)
    rund   = 4 * np.pi * flaeche / (umfang ** 2)      # 1,0 = perfekter Kreis
    form = "Kreis" if rund > 0.85 else f"{len(ecken)}-Eck"
    print(f"Flaeche {flaeche:8.0f}  Rundheit {rund:.2f}  -> {form}")

Die Konturmerkmale, die man braucht

MerkmalFunktionWofür
FlächecontourAreaFiltern, Größe prüfen
UmfangarcLengthRundheit, Glattheit
RechteckboundingRectZuschneiden, Position
Gedrehtes RechteckminAreaRectWinkel bestimmen
HülleconvexHullFehlende Stücke erkennen
MomentemomentsSchwerpunkt berechnen

Der Gradient

Sobel-Gradient

Gₓ = [[−1,0,1],[−2,0,2],[−1,0,1]] * I G_y = [[−1,−2,−1],[0,0,0],[1,2,1]] * I |G| = √(Gₓ² + G_y²) θ = arctan(G_y / Gₓ)

Betrag und Richtung ergeben sich aus den beiden Richtungsableitungen wie bei einem Vektor.

Gₓ, G_y
Ableitungen in x- und y-Richtung
|G|
Betrag des Gradienten, also die Kantenstärke
θ
Richtung der Kante

Die vier Schritte von Canny

  1. 01

    Glätten

    Gaußfilter, damit Rauschen keine Gradienten erzeugt.

  2. 02

    Gradient bestimmen

    Sobel in beiden Richtungen, daraus Betrag und Richtung.

  3. 03

    Nicht-Maxima unterdrücken

    Nur der stärkste Punkt quer zur Kantenrichtung bleibt stehen. Dadurch werden die Linien ein Pixel dünn.

  4. 04

    Hysterese

    Punkte über dem oberen Schwellwert sind sicher Kante. Punkte zwischen den Schwellwerten nur dann, wenn sie mit einer sicheren Kante zusammenhängen.

Der vierte Schritt ist der eigentliche Gewinn: er verbindet unterbrochene Linien und unterdrückt gleichzeitig isolierte Störpunkte, was mit einem einzigen Schwellwert nicht gleichzeitig möglich ist.

Vermessen mit Referenz

Maßstab aus einem Referenzobjekt

mm_je_pixel = l_ref / p_ref l_obj = p_obj · mm_je_pixel

Der Maßstab folgt aus dem bekannten Objekt und überträgt sich auf alle Objekte in derselben Ebene.

p_ref
Länge des Referenzobjekts in Pixeln
l_ref
seine bekannte Länge in Millimetern
p_obj
gemessene Pixellänge des Objekts

Die Einschränkung „in derselben Ebene" ist entscheidend. Objekte, die näher an der Kamera liegen, erscheinen größer, und ohne Entzerrung ist die Messung um den perspektivischen Faktor falsch. Bei senkrechter Aufnahme mit einem Referenzobjekt neben dem Prüfteil sind Genauigkeiten unter einem Prozent erreichbar, bei schräger Aufnahme ohne Entzerrung leicht zehn Prozent daneben.

Passende Kurse und Quellen

KursKostenlosEN

OpenCV-Tutorials

Die offiziellen Anleitungen zu Filtern, Kanten, Merkmalen und Kalibrierung, jeweils mit lauffähigem Python-Code.

Für alle, die Bildverarbeitung selbst schreiben; jedes Beispiel ist lauffähig.

War diese Seite hilfreich?
Kanten und Konturen