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:

Match Contours (extrahierte Formen) 1:

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:

Match Contours (extrahierte Formen) 2:

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:

Match Contours (extrahierte Formen) 3:

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:

Match Contours (extrahierte Formen) 4:

Dieses Ergebnis macht deutlich, dass je nach Anwendung eine andere Berechnungsmethode die besten Resultate liefern kann.

Ähnliches Beispiel