Durchschnittsintensität in beliebigen Formen

In diesem Beispiel wird die durchschnittliche Intensität eines Bildes innerhalb eines manuell definierten Bildbereichs berechnet. Dazu wird eine kreisförmige Bildmaske genutzt.

Dabei werden vor allem folgende Funktionen benutzt:

Erklärung

In dem Beispiel Statistische Bildmerkmale wird gezeigt, wie statistische Bildmerkmale (wie Durchschnitt, Maximum und Minimum) berechnet werden können. Häufig sollen diese Merkmale jedoch nicht für das gesamte Bild, sondern nur für bestimmte Bildbereiche berechnet werden. Sind diese Bereiche rechteckig, hilft das Setzen einer ROI. Um die Berechnung auf beliebig geformte Bereiche zu beschränken, müssen Sie mit Bildmasken arbeiten. Dies sind im Wesentlichen Bilder, deren Intensitätswerte beschreiben, welche Pixel in dem Originalbild berücksichtigt werden sollen. Somit kann eine Maske beliebige Formen annehmen; dieses Beispiel zeigt eine Maske in Kreisform.

Für dieses Beispiel wird ein quasi Binärbild mit einer Ansammlung von Schrauben betrachtet. Ein denkbarer Anwendungsfall wäre z. B., dass anhand des durchschnittlichen Intensitätswert annähernd die Menge der Schrauben bestimmt werden soll.

Durchschnittsintensität in beliebigen Formen 1:

Anwendung

Durch Variieren der Parameter nCircleShrink und aCenterOffset können Sie die Größe und Position der kreisförmigen Maske verändern. Entsprechend dieser Maske verändert sich der durchschnittliche Intensitätswert: Wenn die Maske kleiner wird und weniger des weißen Hintergrunds zeigt, verringert sich der Durchschnittswert. Wenn die Maske sich verschiebt und mehr des weißen Hintergrunds zeigt, vergrößert sich der Durchschnittswert.

Ergebnisbild

Maskenbild

Durchschnittsintensität in beliebigen Formen 2:

Durchschnittsintensität in beliebigen Formen 3:

Durchschnittsintensität in beliebigen Formen 4:

Durchschnittsintensität in beliebigen Formen 5:

Durchschnittsintensität in beliebigen Formen 6:

Durchschnittsintensität in beliebigen Formen 7:

Bei Bedarf können auch andere Bilder in dieses Beispielprojekt eingeladen werden. Achten Sie darauf, dass dann ggfs. die Masken-Parameter angepasst werden müssen.

Code

Das Beispielbild wird über eine FileSource-Zustandsmaschine als ipImageWork eingeladen und mit folgendem Code verarbeitet.

Zunächst werden die Eigenschaften der Maske festgelegt. Da die Maske ein Kreis ist, wird sie durch den Mittelpunkt aCenter und den Radius nRadius beschrieben. Als Mittelpunkt des Kreises wird der Bildmittelpunkt korrigiert durch das vom Nutzer einstellbares Offset aCenterOffset verwendet. Der Radius berechnet sich als Abstand vom Mittelpunkt zum nächstgelegenen Bildrand abzüglich des Werts nCircleShrink.

hr := F_VN_GetImageWidth(ipImageWork, nWidth, hr);
hr := F_VN_GetImageHeight(ipImageWork, nHeight, hr);
aCenter[0] := (nWidth / 2) + aCenterOffset[0];
aCenter[1] := (nHeight / 2) + aCenterOffset[1];
nRadius := (MIN(nWidth, nHeight) / 2) - nCircleShrink;

Als Maske wird ein neues Bild mit gleicher Größe wie das Eingangsbild ipImageWork erstellt und mit einem weißen Kreis auf schwarzem Hintergrund bemalt. Der Kreis erhält die errechneten Eigenschaften. Als Breite nThickness der Kreisumrandung wird der Wert -1 gewählt, damit der Kreis ausgefüllt wird.

hr := F_VN_CreateImageAndSetPixels(ipImageMask, nWidth, nHeight, TCVN_ET_USINT, 1, aColorBlack, hr);
hr := F_VN_DrawCircle(
    nCenterX    :=  aCenter[0],
    nCenterY    :=  aCenter[1],
    nRadius     :=  nRadius,
    ipDestImage :=  ipImageMask,
    aColor      :=  aColorWhite,
    nThickness  :=  -1,
    hrPrev      :=  hr
);

Als Resultat steht nun ein Maskenbild ipImageMask mit der gewünschten Kreisform zur Verfügung:

Durchschnittsintensität in beliebigen Formen 8:

Nun wird mit Hilfe dieser Maske ipImageMask der durchschnittliche Intensitätswert des Eingangsbildes ipImageWork im definierten kreisförmigen Bereich berechnet. Die Funktion F_VN_ImageAverageExp gibt das Array aAverage des Typs TcVnVector4_LREAL zurück, um die maximal möglich Anzahl an Bildkanälen abzudecken. Da das Eingangsbild in diesem Beispiel nur einen Kanal besitzt, ist das erste Array-Element der gewünschte Durchschnittswert und wird separat gespeichert.

hr := F_VN_ImageAverageExp(
    ipSrcImage  :=  ipImageWork,
    aAverage    :=  aAverage,
    ipMask      :=  ipImageMask,
    hrPrev      :=  hr
);
fAverageInMask := aAverage[0];

Schließlich werden der Maskenkreis sowie der errechnete Durchschnittswert in ein Ergebnisbild eingezeichnet.

hr := F_VN_ConvertColorSpace(ipImageWork, ipImageRes, TCVN_CST_GRAY_TO_RGB, hr);
hr := F_VN_DrawCircle(aCenter[0], aCenter[1], nRadius, ipImageRes, aColorGreen, 5, hr);
sText := CONCAT('Average: ', LREAL_TO_FMTSTR(fAverageInMask, 2, TRUE));
hr := F_VN_PutTextExp(sText, ipImageRes, 40, 60, TCVN_FT_HERSHEY_SIMPLEX, 2, aColorBlue, 3, TCVN_LT_ANTIALIASED, FALSE, hr);

Für die Funktion LREAL_TO_FMTSTR wird die SPS-Bibliothek Tc2_Utilities benötigt.