Match Contours (extrahierte Formen)
In diesem Beispiel werden zwei Konturen mit Hilfe der Funktion F_VN_MatchContours miteinander verglichen.
Erläuterung
Die Funktion F_VN_MatchContours vergleicht zwei gegebene Konturen mit Hilfe der Hu Momente. In diesem Beispiel wird die Funktion benutzt, um ein vorgegebenes Bauteil in einer neuen Situation wiederzuerkennen. Hierzu wird in einem Referenzbild ein Bauteil ausgewählt, dessen Kontur abgespeichert und anschließend mit den Konturen aus einem anderen Bild verglichen. Auf diese Weise werden die Bauteile, die eine gewisse Ungleichheit gegenüber dem Referenzbauteil unterschreiten markiert.
Eingangsparameter
Neben den zu vergleichenden Konturen, muss der Funktion nur ein Parameter übergeben werden, der die Berechnungsmethode beschreibt, mit der aus den Hu Momenten das Ungleichheitsmaß bestimmt wird (eComparisonMethod vom Typ ETcVnContoursMatchComparisonMethod). Die Methode TCVN_CMCM_CONTOURS_MATCH_I1 berechnet die Summe über die Differenzen der Kehrwerte der individuellen Charakteristiken, während die Methode TCVN_CMCM_CONTOURS_MATCH_I2 die Summe über die Differenzen der reinen Charakteristiken bildet. Im Gegensatz zu den ersten beiden Methoden berechnet die dritte Variante TCVN_CMCM_CONTOURS_MATCH_I3 nur die maximale Differenz der individuellen Charakteristiken. Je nach Anwendungsfall kann eine andere der drei Methoden am besten geeignet sein für den Vergleich zweier Konturen.
Variablen
hr : HRESULT;
ipImageIn : ITcVnImage;
ipImageInDisp : ITcVnDisplayableImage;
ipImageRes : ITcVnImage;
ipImageResDisp : ITcVnDisplayableImage;
ipIterator : ITcVnForwardIterator;
// result
ipContourList : ITcVnContainer;
ipContourReference : ITcVnContainer;
ipContourCheck : ITcVnContainer;
fBestDissimilarity : LREAL;
fDissimilarity : LREAL;
// parameters
fThreshold : REAL := 170;
fMinArea : REAL := 10000;
fMaxDissimilarity : LREAL := 0.01;
eComparisonMethod : ETcVnContoursMatchComparisonMethod := TCVN_CMCM_CONTOURS_MATCH_I3;
// drawing
aColorGreen : TcVnVector4_LREAL := [0, 175, 0];
aColorBlue : TcVnVector4_LREAL := [0, 0, 255];
aColorRed : TcVnVector4_LREAL := [255, 0, 0];
aColorRes : TcVnVector4_LREAL;
sText : STRING(255);
sTextReference : STRING(255) := 'Reference contour';
sTextCheck : STRING(255) := 'Check dissimilarity';
// other
bDarkBackground : BOOL;
nContours : ULINT;
nCounter : UINT := 0;
aPixelValue : TcVnVector4_LREAL;
stBoundingRectangle : TcVnRectangle_UDINT;
stParams : TcVnParamsBlobDetection;
Code
// Prepare result image
hr := F_VN_ConvertColorSpace(ipImageIn, ipImageRes, TCVN_CST_GRAY_TO_RGB, hr);
// Check if background is dark in order to identify reference image
hr := F_VN_GetPixel(ipImageIn, aPixelValue, 50, 50, hr);
bDarkBackground := SUCCEEDED(hr) AND_THEN aPixelValue[0] < 128;
IF bDarkBackground THEN
stParams.eThresholdType := TCVN_TT_BINARY;
ELSE
stParams.eThresholdType := TCVN_TT_BINARY_INV;
END_IF
// Find contours in image
hr := F_VN_DetectBlobs(ipImageIn, ipContourList, stParams, hr);
// Distinguish reference and test image
IF bDarkBackground THEN
// Select one of the found contours as reference for matching
hr := F_VN_GetNumberOfElements(ipContourList, nContours, hr);
hr := F_VN_GetAt_ITcVnContainer(ipContourList, ipContourReference, nCounter MOD nContours, hr);
// Draw selected contour and text
hr := F_VN_PutTextExp(sTextReference, ipImageRes, 50, 50, TCVN_FT_HERSHEY_SIMPLEX, 1.3, aColorBlue, 2, TCVN_LT_8_CONNECTED, FALSE, hr);
hr := F_VN_DrawContours(ipContourReference, -1, ipImageRes, aColorBlue, 5, hr);
nCounter := nCounter + 1;
ELSE
fBestDissimilarity := 10E300;
// Iterate through all found contours
hr := F_VN_GetForwardIterator(ipContourList, ipIterator, hr);
WHILE hr = S_OK AND_THEN ipIterator.CheckIfEnd() <> S_OK DO
hr := F_VN_GetContainer(ipIterator, ipContourCheck, hr);
hr := F_VN_IncrementIterator(ipIterator, hr);
// Match the current contour with the selected reference contour
hr := F_VN_MatchContours(ipContourReference, ipContourCheck, eComparisonMethod, fDissimilarity, hr);
// Save best result
IF fBestDissimilarity > fDissimilarity THEN
fBestDissimilarity := fDissimilarity;
END_IF
// Choose action depending on the dissimilarity of both contours
IF SUCCEEDED(hr) AND_THEN fDissimilarity < fMaxDissimilarity THEN
aColorRes := aColorGreen;
ELSE
aColorRes := aColorRed;
END_IF
// Draw matching results
sText := REAL_TO_STRING(LREAL_TO_REAL(fDissimilarity));
hr := F_VN_UprightBoundingRectangle(ipContourCheck, stBoundingRectangle, hr);
hr := F_VN_DrawContours(ipContourCheck, -1, ipImageRes, aColorRes, 5, hr);
hr := F_VN_PutTextExp(sText, ipImageRes, LREAL_TO_UDINT(stBoundingRectangle.nX + 30), LREAL_TO_UDINT(stBoundingRectangle.nY + (stBoundingRectangle.nHeight / 2)), TCVN_FT_HERSHEY_SIMPLEX, 0.8, aColorRes, 2, TCVN_LT_8_CONNECTED, FALSE, hr);
END_WHILE
// Draw text
hr := F_VN_PutTextExp(sTextCheck, ipImageRes, 50, 50, TCVN_FT_HERSHEY_SIMPLEX, 1.3, aColorGreen, 2, TCVN_LT_8_CONNECTED, FALSE, hr);
sText := CONCAT('Best match: ', REAL_TO_STRING(LREAL_TO_REAL(fBestDissimilarity)));
hr := F_VN_PutTextExp(sText, ipImageRes, 50, 100, TCVN_FT_HERSHEY_SIMPLEX, 1.3, aColorGreen, 2, TCVN_LT_8_CONNECTED, FALSE, hr);
END_IF
hr := F_VN_TransformIntoDisplayableImage(ipImageRes, ipImageResDisp, hr);
hr := F_VN_TransformIntoDisplayableImage(ipImageIn, ipImageInDisp, hr);
Ergebnisse
Auf dem Referenzbild wird die aktuell ausgewählte Referenzkontur in blau markiert:
Man sieht, dass die Kontur durch die Linsenverzerrung leicht gewölbt ist und einige kleinere Störungen aufweist. Im Testbild werden Konturen, deren Ungleichheitsmaß gegenüber der Referenzkontur den eingestellten Schwellwert unterschreitet, in Grün dargestellt - die übrigen Konturen in Rot. Außerdem wird über alle Konturen der berechnete Ungleichheitswert gezeichnet. Im Folgenden ist das Ergebnis zum Eingabebild MatchContours1.bmp bei Auswahl des Rechtecks als Referenzbauteil abgebildet:
Es ist zu erkennen, dass das rechteckige Bauteil mit Abstand den kleinsten Ungleichheitswert gegenüber der Referenzkontur hat. Ändert man nun den Parameter eComparisonMethod von TCVN_CMCM_CONTOURS_MATCH_I3 auf TCVN_CMCM_CONTOURS_MATCH_I2, ändern sich entsprechend die berechneten Ungleichheitswerte:
In diesem Fall ist das Ergebnis noch eindeutiger, allerdings trifft das nicht auf alle Formen zu. Wenn das Dreieck als Referenzbauteil ausgewählt ist, wird das Ergebnis mit dieser Einstellung deutlich weniger eindeutig als bei der ursprünglichen Einstellung:
Dieses Ergebnis macht deutlich, dass je nach Anwendung eine andere Berechnungsmethode die besten Resultate liefern kann.