Rath, T., Credner, J., Fadami, M., Rehrmann, P.: Blue Apple – Transformation of histograms to Gaussian distributions. BLab Code No. 20223, http://www.blab-osnabrueck.de/blue-apple3.txt, 2022. Title: Blue Apple - Transformation of histograms to Gaussian distributions Authors: Thomas Rath, Jonas Credner, Maryam Fadami, Peter Rehrmann, Year:2022 Keywords: Image pre-processing, histogramm transformation, color selection, identification biological objects, binarisation, Halcon Abstract: Image processing of color images often requires to analyse histograms of color chanels. Theses histograms are normally not normal distributed. With this algorithm one can transform a histogramm, which consists of any data, to a pseudo normal distributed histogram. Pseudo normal distributed means, that the histogram is as much as possible (or similar as) normal distributed. It is calculated by separating the histogram into a left side and a right side histogram. The code for the transformation is given. Additionally the code for transfomation of an absolute histogram to a relative histogram is given. Cite as: t.Rath, J. Credner, M. Fadami, P. Rehrmann (2022): Blue Apple - Transformation of histograms to Gaussian distributions. BLab Code No. 20223, http://www.blab-osnabrueck.de/blue-apple3.txt Literature: Halcon (2022): Halcon - Die Leistungsstarke Software fuer Ihre Bildverarbeitungsanwendung. MVTec Software GmbH, Munich, Germany Affiliation: T.Rath, J. Credner, M. Fadami, P. Rehrmann Biosystem Engineering Laboratory (BLab), Osnabrueck University of Applied sciences email: t.rath@hs-osnabrueck.de ############################################################################## # File generated by HDevelop for text file Version 13.0.3 ############################################################################## procedure gauss_classification_histogram (: : Rel_Histogramm: Klassifikations_Histogramm, L1, L2, L3, L4, R1, R2, R3, R4, Mue, MueY) * *********************************************************************************************** * *Berechnung des gauss-normierten Histgogrammes und Ausgabe von Stuetzstellen und Mittelwerten * *********************************************************************************************** * *********************************************************************************************************************** * Bestimmung von MueX bei beliebigem Histogramm, durch Berechnung der Schwerpunktlinie der Histogrammfläche, 2.3.2021 * * *********************************************************************************************************************** HistoSum := 0 for i := 1 to 256 by 1 tuple_select (Rel_Histogramm, i-1, Wert) HistoSum := HistoSum + Wert endfor * ********* * MueX-Suche von links * ********* Sum_von_links := 0.0 il := -1 repeat il := il + 1 tuple_select (Rel_Histogramm, il, Wert) Sum_von_links := Sum_von_links + Wert until ((Sum_von_links >= HistoSum/2) or (il = 255)) * ********* * MueX-Suche von rechts * ********* Sum_von_rechts := 0.0 ir := 256 repeat ir := ir - 1 tuple_select (Rel_Histogramm, ir, Wert) Sum_von_rechts := Sum_von_rechts + Wert until ((Sum_von_rechts >= HistoSum/2) or (ir = 0)) * ********* * MueX-Ermittlung als Mittelwert ungerundet * ********* MueX := (il + ir)/2.0 Mue2 := int(MueX) MueLinks := Mue2 MueRechts := Mue2 + 1 * ************************************* Ende Bestimmung MueX, also mittlerer X-Wert des Histogramms aufgrund der Histogramm-Y-W * *************************************** F4 := 0.00135 * HistoSum F3 := 0.02140 * HistoSum F2 := 0.13590 * HistoSum F1 := 0.34135 * HistoSum * ********Werte um 1 hochsetzen***************************** * for i := 0 to 255 by 1 * tuple_select (Rel_Histogramm, i, Wert) * Wert := Wert + 1.0 * tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) * endfor * tuple_round (Mue, Mue) tuple_gen_const (301, 0, LinkerZusatz) tuple_gen_const (300, 0, RechterZusatz) tuple_concat (LinkerZusatz, Rel_Histogramm, Rel_Histogramm) tuple_concat (Rel_Histogramm, RechterZusatz, Rel_Histogramm) MueLinks := MueLinks + 301 MueRechts := MueRechts + 301 tuple_select (Rel_Histogramm, MueLinks, MueY1) tuple_select (Rel_Histogramm, MueRechts, MueY2) MueY := (MueY1 + MueY2) / 2.0 FlaecheLinks := 0.5 * MueY i := MueLinks + 1 repeat i := i - 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheLinks := FlaecheLinks + Auswahl until ((FlaecheLinks >= F1) or (i = 300)) L1 := i FlaecheRechts := 0.5 * MueY i := MueRechts - 1 repeat i := i + 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheRechts := FlaecheRechts + Auswahl until ((FlaecheRechts >= F1) or (i = 557)) R1 := i * ************************************************ FlaecheLinks := 0.5 * MueY i := MueLinks + 1 repeat i := i - 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheLinks := FlaecheLinks + Auswahl until ((FlaecheLinks >= (F1+F2)) or (i=300)) L2 := i if (L2 >= L1) * L2 := L1 - 1 L2 := L1 endif FlaecheRechts := 0.5 * MueY i := MueRechts -1 repeat i := i + 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheRechts := FlaecheRechts + Auswahl until ((FlaecheRechts >= (F1+F2)) or (i=557)) R2 := i if (R2 <= R1) * R2 := R1 + 1 R2 := R1 endif * ******************************************* FlaecheLinks := 0.5 * MueY i := MueLinks + 1 repeat i := i - 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheLinks := FlaecheLinks + Auswahl until ((FlaecheLinks >= (F1+F2+F3)) or (i=300)) L3 := i if (L3 >= L2) * L3 := L2 - 1 L3 := L2 endif FlaecheRechts := 0.5 * MueY i := MueRechts - 1 repeat i := i + 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheRechts := FlaecheRechts + Auswahl until ((FlaecheRechts >= (F1+F2+F3)) or (i = 557 )) R3 := i if (R3 <= R2) * R3 := R2 + 1 R3 := R2 endif * ************************************************** FlaecheLinks := 0.5 * MueY i := MueLinks + 1 repeat i := i - 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheLinks := FlaecheLinks + Auswahl until ((FlaecheLinks >= (F1+F2+F3+F4)) or (i=300)) L4 := i if (L4 >= L3) * L4 := L3 -1 L4 := L3 endif FlaecheRechts := 0.5 * MueY i := MueRechts - 1 repeat i := i + 1 tuple_select (Rel_Histogramm, i, Auswahl) FlaecheRechts := FlaecheRechts + Auswahl until ((FlaecheRechts >= (F1+F2+F3+F4)) or (i=557)) R4 := i if (R4 <= R3) * R4 := R3 + 1 R4 := R3 endif * ***************************************************** DurchschnittlichL := ((L1-L2) + (L2-L3) + (L3-L4)) / 3 DurchschnittlichR := ((R2-R1) + (R3-R2) + (R4-R3)) / 3 LNix := L4 - DurchschnittlichL if (LNix >= 301) LNix := 300 endif RNix := R4 + DurchschnittlichR if (RNix <= 556) RNix := 557 endif * ************************************************** if (MueLinks != L1) L1Y := F1 /(MueLinks - L1) else L1Y := F1 / 1.0 endif if (L1 != L2) L2Y := F2 /(L1 - L2) else L2Y := L1Y endif if (L2 != L3) L3Y := F3 /(L2 - L3) else L3Y := L2Y endif if (L3 != L4) L4Y := F4 /(L3 - L4) else L4Y := L3Y endif if (MueRechts != R1) R1Y := F1 /(R1 - MueRechts) else R1Y := F1/1.0 endif if (R1 != R2) R2Y := F2 /(R2 - R1) else R2Y := R1Y endif if (R2 != R3) R3Y := F3 /(R3 - R2) else R3Y := R2Y endif if (R3 != R4) R4Y := F4 /(R4 - R3) else R4Y := R3Y endif * RNixY := 0 * LNixY := 0 * ************************************************** * if (L2Y > L1Y) * L2Y := L1Y - (MueY/256) * endif * if (L3Y > L2Y) * L3Y := L2Y - (MueY/256) * endif * if (L4Y > L3Y) * L4Y := L3Y - (MueY/256) * endif * LNixY := L4Y - (MueY/256) LNixY := 0 * if (R2Y > R1Y) * R2Y := R1Y - (MueY/256) * endif * if (R3Y > R2Y) * R3Y := R2Y - (MueY/256) * endif * if (R4Y > R3Y) * R4Y := R3Y - (MueY/256) * endif * RNixY := R4Y - (MueY/256) RNixY := 0 * ************************************************** for i := L1 to R1 by 1 Wert := ((R1Y-L1Y)/(R1-L1))*i+((L1Y*R1-R1Y*L1)/(R1-L1)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor if (R1 != R2) for i := R1+1 to R2 by 1 Wert := ((R2Y-R1Y)/(R2-R1))*i+((R1Y*R2-R2Y*R1)/(R2-R1)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor endif if (L1 != L2) for i := L1-1 to L2 by -1 Wert := ((L2Y-L1Y)/(L2-L1))*i+((L1Y*L2-L2Y*L1)/(L2-L1)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor endif if (R2 != R3) for i := R2+1 to R3 by 1 Wert := ((R3Y-R2Y)/(R3-R2))*i+((R2Y*R3-R3Y*R2)/(R3-R2)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor endif if (L2 != L3) for i := L2-1 to L3 by -1 Wert := ((L3Y-L2Y)/(L3-L2))*i+((L2Y*L3-L3Y*L2)/(L3-L2)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor endif if (R3 != R4) for i := R3+1 to R4 by 1 Wert := ((R4Y-R3Y)/(R4-R3))*i+((R3Y*R4-R4Y*R3)/(R4-R3)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor endif if (L3 != L4) for i := L3-1 to L4 by -1 Wert := ((L4Y-L3Y)/(L4-L3))*i+((L3Y*L4-L4Y*L3)/(L4-L3)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor endif for i := R4+1 to RNix by 1 Wert := ((RNixY-R4Y)/(RNix-R4))*i+((R4Y*RNix-RNixY*R4)/(RNix-R4)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor for i := L4-1 to LNix by -1 Wert := ((LNixY-L4Y)/(LNix-L4))*i+((L4Y*LNix-LNixY*L4)/(LNix-L4)) tuple_replace (Rel_Histogramm, i, Wert, Rel_Histogramm) endfor * ****************************************************************** tuple_select_range (Rel_Histogramm, 301, 556, Rel_Histogramm) Klassifikations_Histogramm := Rel_Histogramm * if (HistogrammRelative = true) * histogram_norm (Klassifikations_Histogramm, Klassifikations_Histogramm) * endif L1 := L1 - 301 L2 := L2 - 301 L3 := L3 - 301 L4 := L4 - 301 R1 := R1 - 301 R2 := R2 - 301 R3 := R3 - 301 R4 := R4 - 301 Mue := MueX - 301 * MueY := MueY/2 return () ############################################################################## # File generated by HDevelop for text file Version 13.0.3 ############################################################################## procedure histogram_norm (: : Lineares_Gauss_Histogramm: Lineares_Gauss_Histogramm_Normiert) * ******************************************************* * *Normierung eines Histogrammes auf den Summenwert 1 * ******************************************************* tuple_length (Lineares_Gauss_Histogramm, Length) tuple_sum (Lineares_Gauss_Histogramm, Sum) Faktor := 1.0/Sum for i := 0 to Length-1 by 1 tuple_select (Lineares_Gauss_Histogramm, i, Selected) NormierterWert := Selected * Faktor tuple_replace (Lineares_Gauss_Histogramm, i, NormierterWert, Lineares_Gauss_Histogramm) endfor Lineares_Gauss_Histogramm_Normiert := Lineares_Gauss_Histogramm return ()