Walsh Template Matching mit Rotation
In diesem Beispiel wird ein Template Matching mit Berücksichtigung der Drehlage durchgeführt, um alle Instanzen eines Referenzbildes in einem Suchbild zu lokalisieren und deren Orientierung zu bestimmen.
Dazu wird eine die folgenden Funktionen verwendet:
- F_VN_FindTemplateWalshExp für eine Suche über den gesamten 360°-Bereich mit festen Winkelschritten.
- F_VN_FindTemplateWalshExp_AngleRange für eine gezielte Eingrenzung auf einen definierten Winkelbereich und frei einstellbaren Winkelschritten.
Erläuterung
Beim Walsh Template Matching werden Instanzen eines Referenzbildes im Eingangsbild auf Basis der Walsh-Transformation gesucht. Da für einen zuverlässigen Vergleich meist schon wenige dieser Projektionen ausreichen, ist das Verfahren sehr performant und ermöglicht so auch die Suche über verschiedene Rotationswinkel, um Position und Orientierung gedrehter Objekte zu bestimmen.
Das Sample enthält drei verschiedene Templatebilder zum Testen. Das zu verwendende Template wird über sFolderPath und sTemplateFileName festgelegt. Um ein neues Template zu laden, muss bTemplateLoaded auf FALSE gesetzt werden, woraufhin das Bild automatisch neu eingelesen wird. Die Matching-Parameter sollten nach einem Templatewechsel überprüft und gegebenenfalls angepasst werden.
Über den Parameter bUseRotationSteps kann zwischen den beiden Funktionen umgeschaltet werden:
- Bei
TRUEwirdF_VN_FindTemplateWalshExpausgeführt. Hierbei wird der gesamte Rotationsbereich (0° bis 360°) geprüft. Die Winkelauflösung ergibt sich aus dem ParameternRotationswobei nur die Werte 1, 2, 4, 8, 16 und 32 gültig sind. - Bei
FALSEwirdF_VN_FindTemplateWalshExp_AngleRangeverwendet. Diese Funktion ermöglicht, den Suchbereich überfStartAngleundfStopAngle(z. B. auf ±90°) einzugrenzen und mitnAnglesauf eine beliebig gewünschte Anzahl an Prüfschritten festzulegen.
Die Parameter nRotations bzw. nAngles definieren die Anzahl der zu prüfenden Winkelschritte und bestimmen somit die Winkelauflösung der Suche. Da der Algorithmus zwischen diesen diskreten Prüfschritten interpoliert, können auch Rotationswerte zwischen den expliziten Prüfwinkeln ermittelt werden. Die gewählte Anzahl der Prüfrotationen hat einen maßgeblichen Einfluss auf die Gesamtlaufzeit der Funktion. Zur Performance-Optimierung ist es daher empfehlenswert, den Suchbereich mittels F_VN_FindTemplateWalshExp_AngleRange auf den tatsächlich relevanten Winkelbereich einzugrenzen. Dadurch lässt sich die Anzahl der Prüfwinkel reduzieren und die Ausführungszeit gezielt minimieren.
Darüber hinaus wird die Laufzeit und die erreichbare Matching-Qualität maßgeblich durch das Zusammenspiel von nProjections und fScaleFactor bestimmt. Eine höhere Anzahl an Projektionen lässt mehr Bildinformationen in den Prozess einfließen, was die Zuverlässigkeit des Matchings verbessert, jedoch die Rechenzeit erhöht. Ebenso steigert ein größerer Skalierungsfaktor (näher an 1.0) die Genauigkeit bei gleichzeitig längerer Rechenzeit. Da beide Parameter die Ähnlichkeitswerte direkt beeinflussen, muss der Schwellwert fMatchThreshold nach jeder Parameteränderung entsprechend neu abgestimmt werden.
Am Ende dieses Kapitels finden Sie weitere Hinweise zur Parametrierung und Optimierung der hier beschriebenen Parameter.
Zusätzlich wird eine ROI (stMatchingRoi) gesetzt, die den Suchbereich auf einen relevanten Bildausschnitt einschränkt. Dies reduziert die Anzahl der auszuwertenden Pixel und verkürzt somit die Rechenzeit. Es können jedoch nur Objekte gefunden werden, die vollständig innerhalb der ROI liegen.
Ausführung des Template Matchings
Zunächst wird die ROI im Eingangsbild definiert. Abhängig vom Parameter bUseRotationSteps wird anschließend entweder die 360°-Suche (F_VN_FindTemplateWalshExp) oder die gezielte Suche in einem definierten Winkelbereich (F_VN_FindTemplateWalshExp_AngleRange) ausgeführt.
Da der Parameter nRotations auf die festen Werte 1, 2, 4, 8, 16 und 32 beschränkt ist, stellt eine vorgeschaltete CASE-Anweisung sicher, dass die Eingabe auf den nächstkleineren gültigen Wert abgerundet wird. Ohne diese Korrektur würde die Funktion einen Fehlercode HRESULT 0x70B (INVALIDPARM) zurückgeben.
Für beide Suchfunktionen werden dem Parameter eOptions die Flags TCVN_FTWO_FUSE_MATCHES und TCVN_FTWO_ROTATED_RECTANGLE übergeben. Die Verwendung von TCVN_FTWO_FUSE_MATCHES ist grundsätzlich immer zu empfehlen, da diese Option redundante Treffer aus leicht abweichenden Rotationen und Positionen zu einem einzelnen Match zusammenfasst. Das Flag TCVN_FTWO_ROTATED_RECTANGLE vereinfacht die anschließende Auswertung deutlich, da die Ergebnisse direkt als strukturierter Datentyp TcVnRotatedRectangle zur Verfügung gestellt werden.
Variablen
// ROI for the template matching
stMatchingRoi : TcVnRectangle_UDINT := (nX := 150, nY := 150, nWidth := 740, nHeight := 650);
// Template matching parameters
bUseRotationSteps : BOOL := TRUE;
bShowMatchValue : BOOL := TRUE;
bShowRotationValue : BOOL := TRUE;
fMatchThreshold : REAL := 0.94;
nProjections : UDINT := 15;
nRotations : UDINT := 32;
fScaleFactor : REAL := 0.225;
eInterpolationType : ETcVnInterpolationType := TCVN_IT_BILINEAR;
// Template matching with angle range specific parameters.
nAngles : UDINT := 16;
fStartAngle : LREAL := -90;
fStopAngle : LREAL := 90;
// Template matching results
hrMatch : HRESULT;
ipMatches : ITcVnContainer;
ipMatchValues : ITcVnContainer;Code
hr := F_VN_SetRoi_TcVnRectangle_UDINT(stMatchingRoi, ipImageIn, hr);
IF bUseRotationSteps THEN
// Use when object rotation is not specified to cover up to 360° range
// Valid values for the number of rotations: 1 (0°), 2 (0° and 180°), 4 (0°, 90°, 180°, and 270°), 8 (0°, 45°, ..., 315°), 16 (0°, 22.5°, ..., 337.5°) and 32 (0°, 11.25°, ..., 348.75°)
// Set value to the next lower valid rotation step
CASE nRotations OF
0..1: nRotations := 1;
2..3: nRotations := 2;
4..7: nRotations := 4;
8..15: nRotations := 8;
16..31: nRotations := 16;
ELSE
nRotations := 32;
END_CASE
hrMatch := F_VN_FindTemplateWalshExp(
ipSrcImage := ipImageIn,
ipTemplateImage := ipImageTemplate,
ipMatches := ipMatches,
fMatchThreshold := fMatchThreshold,
nProjections := nProjections,
eOptions := TCVN_FTWO_FUSE_MATCHES OR TCVN_FTWO_ROTATED_RECTANGLE,
nRotations := nRotations,
fScaleFactor := fScaleFactor,
eInterpolationType := eInterpolationType,
ipMatchValues := ipMatchValues,
hrPrev := hr);
ELSE
// Use when rotation range can be limited (e.g. ±45°)
hrMatch := F_VN_FindTemplateWalshExp_AngleRange(
ipSrcImage := ipImageIn,
ipTemplateImage := ipImageTemplate,
ipMatches := ipMatches,
fMatchThreshold := fMatchThreshold,
nProjections := nProjections,
fStartAngle := fStartAngle,
fStopAngle := fStopAngle,
nAngles := nAngles,
eOptions := TCVN_FTWO_FUSE_MATCHES OR TCVN_FTWO_ROTATED_RECTANGLE,
fScaleFactor := fScaleFactor,
eInterpolationType := eInterpolationType,
ipMatchValues := ipMatchValues,
hrPrev := hr);
END_IFAuswertung und Zeichnen der Ergebnisse
Zunächst wird überprüft, ob die Funktion erfolgreich ausgeführt wurde und Matches gefunden wurden. Die gefundenen Matches werden iteriert, um die Koordinaten (mit ROI-Offset) und Match-Values auszulesen und in das Ergebnisbild einzuzeichnen. Dafür wird eine Hilfsfunktion F_DrawMatchResult in dem Projekt bereitgestellt, die ein rotiertes Rechteck und einen Pfeil zur Darstellung der Orientierung zeichnet. Zusätzlich werden der Match-Value und der erkannte Rotationswinkel eingeblendet. Über die Variablen bShowMatchValue und bShowRotationValue lassen sich diese Texte ausblenden, falls nur das gedrehte Rechteck visualisiert werden soll.
Variablen
stMatchRectangle : TcVnRotatedRectangle;
fMatchValue : REAL;
nNumberOfMatches : ULINT;
nMatchIdx : ULINT;
// Color and Drawing
sStatusText : STRING;
aColorGreen : TcVnVector4_LREAL := [0, 255, 0];
aColorWhite : TcVnVector4_LREAL := [255, 255, 255];
aColorBlack : TcVnVector4_LREAL := [0, 0, 0];
aColorOrange : TcVnVector4_LREAL := [255, 140, 0];
hr : HRESULT;Code
IF hrMatch = S_OK THEN
hr := F_VN_GetNumberOfElements(ipMatches, nNumberOfMatches, hr);
IF nNumberOfMatches > 0 THEN
// Write the number of matches into result image
sStatusText := CONCAT('Matches: ', ULINT_TO_STRING(nNumberOfMatches));
FOR nMatchIdx := 0 TO nNumberOfMatches - 1 DO
// Get match region
hr := F_VN_GetAt_TcVnRotatedRectangle(ipMatches, stMatchRectangle, nMatchIdx, hr);
// Add ROI offeset
stMatchRectangle.aCenter[0] := stMatchRectangle.aCenter[0] + UDINT_TO_REAL(stMatchingRoi.nX);
stMatchRectangle.aCenter[1] := stMatchRectangle.aCenter[1] + UDINT_TO_REAL(stMatchingRoi.nY);
// Get match value
hr := F_VN_GetAt_REAL(ipMatchValues, fMatchValue, nMatchIdx, hr);
// Draw matches on result image
hr := F_DrawMatchResult(stMatchRectangle, ipImageResult, bShowRotationValue, bShowMatchValue, fMatchValue, 3, 1.2, aColorGreen, aColorOrange, hr);
END_FOR
ELSE
sStatusText := 'No matches';
END_IF
ELSIF hrMatch = Tc2_System.E_HRESULTAdsErr.NOTFOUND THEN
sStatusText := 'No matches';
ELSE
// Last 3 hex digits of HRESULT
sStatusText := CONCAT('HRESULT: 0x', DWORD_TO_HEXSTR((TO_DWORD(hrMatch) AND 16#FFF), 3, FALSE));
END_IF
// Draw status text
hr := F_VN_PutLabelExp(sStatusText, ipImageResult, 0, 32, 3, 3, TCVN_FT_HERSHEY_PLAIN, aColorBlack, aColorWhite, TCVN_LT_8_CONNECTED, S_OK);
hr := F_VN_ResetRoi(ipImageIn, S_OK);Ergebnis
Das Ergebnisbild ipImageResultDisp visualisiert die gefundenen Matches, die von den Funktionen über den Container ipMatches ausgegeben wurden. Die verwendete ROI ist in Blau dargestellt.
Mit den im Samplecode hinterlegen Defautwerten wird das "CE"-Zeichen als Template gesucht (sTemplateFileName := 'Template01.png'):

Das zweite Template (Template02.png) kann mit identischen Parametern im Bild gesucht werden.

Interessant ist hierbei eine Performance-Analyse durch Auswertung der Ausführungszeit nach dem Funktionsaufruf über die fExecutionTime_ms. Da Template02.png insgesamt fast eine doppelt so große Bildfläche aufweist, wird das Matching in diesem Fall schneller ausgeführt; obwohl die gleichen Parameter verwendet werden.
Grundsätzlich beeinflussen die Wahl der Template-Größe und das -Seitenverhältnis die Rechenzeit:
- Größere Templates werden Algorithmus bedingt schneller verarbeitet als sehr kleine.
- Quadratische Templates sind gegenüber rechteckigen Formaten zu bevorzugen, um die geringsten Ausführungszeiten zu erzielen. Wobei das nur dann zielführend ist, wenn sich der gesuchte Objektbereich gut in einem quadratischen Ausschnitt isolieren lässt, ohne dass zu viele störende Hintergrundpixel in das Template einfließen.
Als zweiter Anwendungsfall kannTemplate03.png verwendet werden, um z.B. über die Kontakte auf der Klemme zu prüfen, ob das Bauteil vorhanden ist, an welcher Position und in welcher Orientierung es sich befindet. Wenn beispielsweise nur Ausrichtungen von ±60° annehmbar sind, kann die Funktion F_VN_FindTemplateWalshExp_AngleRange verwendet werden, um den Suchbereich gezielt einzuschränken:
bUseRotationSteps := FALSE;
fStartAngle := -60;
fStopAngle := 60;.Damit die gesuchten Kontakte bei allen möglichen Rotationen innerhalb der erlaubten ±60° sicher gefunden werden können, muss die ROI entsprechend angepasst und großzügig dimensioniert werden. Gleichzeitig sollte sie so klein wie möglich gehalten werden, um die Ausführungszeit nicht unnötig zu verlängern. Darüber hinaus lässt sich die Anzahl der Prüfwinkel deutlich reduzieren, da die Suche auf einen Bereich von lediglich 120° eingegrenzt wird, was die Rechenzeit minimiert. Für dieses Szenario haben sich folgende Parameter bewährt:
// Adjusted parameters for Template03.png
stMatchingRoi.nX := 200;
stMatchingRoi.nY := 10;
stMatchingRoi.nWidth := 750;
stMatchingRoi.nHeight := 500;
fMatchThreshold := 0.94;
nProjections := 18;
nAngles := 16;
fScaleFactor := 0.2;
Hinweise zur Parametrierung und Optimierung
Um das Sample auf eigene Applikationen, Bilder oder neue Templates zu adaptieren, müssen die Matching-Parameter überprüft und gegebenenfalls angepasst werden. Für die Parametrierung und Fehleranalyse empfehlen sich folgende Schritte:
- Wahl des Templatebildes: Da das Walsh-Matching pixelbasiert ist, entscheidet die Eignung des gewählten Templatebildes (strukturelle Beschaffenheit) maßgeblich über den Erfolg der Erkennung. Das Template sollte das gesuchte Objekt mit möglichst markanten, kontrastreichen und einzigartigen Strukturen (z. B. spezifische Konturen oder Muster) einfassen. Vermeiden Sie homogene, strukturlose Flächen oder sich stark wiederholende Muster. Zudem müssen die Grauwertvariationen des Templates möglichst exakt mit den Bildregionen der gesuchten Objekte übereinstimmen. Starke Abweichungen führen zu einem geringeren Match-Wert, wodurch unter Umständen mit dem gewählten Template kein zuverlässiges Matching möglich ist.
- Schwellwert (
fMatchThreshold):
Dieser Parameter filtert die Ergebnisse. Ist der Schwellwert zu hoch angesetzt, werden korrekte Treffer unter Umständen nicht gefunden. Ist er zu niedrig, resultiert dies in vielen fehlerhaften Matches. Der von der Funktion ausgegebene Match-Wert (fMatchValue) der gefundenen Objekte dient dabei als Orientierung, um den Threshold inkl. einer Toleranz so zu justieren, dass gültige Treffer zuverlässig von fehlerhaften Matches getrennt werden. - Stabilisierung des Matchings:
Lassen sich gehäuft auftretende fehlerhafte Matches nicht allein über den Schwellwert isolieren, fließen oft zu wenige Bildinformationen in den Matching-Prozess ein. Eine höhere Anzahl an Projektionen (nProjections) und/oder ein größerer Skalierungsfaktor (fScaleFactor) steigern die Genauigkeit und Zuverlässigkeit. Da beide Parameter die resultierenden Ähnlichkeitswerte direkt beeinflussen, muss der Schwellwert nach jeder Parameteränderung entsprechend neu abgestimmt werden. - Kontrolle der skalierten Eingangsbilder:
Zur Überprüfung der Einstellungen erzeugt das Sample skalierte Debug-Bilder. Diese visualisieren das Eingangs- und das Templatebild in exakt der Auflösung, in der sie intern von der Matching-Funktion (unter Berücksichtigung der ParameterfScaleFactorundeInterpolationType) verarbeitet werden. Diese visuelle Kontrolle dient dazu sicherzustellen, dass markante Objektstrukturen auch nach der Skalierung für eine robuste Erkennung noch ausreichend sichtbar bleiben. - Genauigkeit des Rotationswinkels:
Erscheint der ermittelte Winkel unpräzise, kann die Anzahl der zu prüfenden Winkelschritte (nRotationsbzw.nAngles) erhöht werden. Eine unzureichende Winkelgenauigkeit kann jedoch auch darauf zurückzuführen sein, dass generell zu wenige Bildinformationen in den Matching-Prozess einfließen, um die Orientierung überhaupt robust bestimmen zu können. - Beleuchtungseinflüsse:
Führen diese Parameteranpassungen nicht zum Erfolg, können auch ungleichmäßige Beleuchtungssituationen die Ursache sein. Durch die zusätzliche Übergabe des FlagsTCVN_FTWO_SKIP_DC(an den ParametereOptions) wird die erste Walsh-Projektion ignoriert, wodurch globale Helligkeits- und Kontrastunterschiede weniger ins Gewicht fallen. Dies erfordert jedoch meist eine höhere Anzahl an Projektionen. Alternativ sollte die reale Beleuchtungssituation verbessert oder die Ungleichmäßigkeit im Vorfeld durch ein geeignetes Preprocessing behoben werden.