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.
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 |
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:
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.