Tausend strahlende Sonnen...

25.09.2013 19:00 von /cbx, derzeit 15.47874 Kommentare

Send to Kindle

…über vier glühenden Kernen. Ja, hätte ich auch nur einen leisen Schimmer von Gegenwartsliteratur, dann könnte ich diesen Post verblüffend subtil und aufsehenerregend intellektuell genau so benennen. So aber ist es ein reiner Zufall, dass mir dieser Titel eingefallen ist, wo es doch in Wahrheit um ein dröges Inschenjörsthema wie OpenMP geht.

Denn es begab sich, dass vor einiger Zeit das Unternehmen, für das zu arbeiten ich das gelegentlich durchaus zweifelhafte Vergnügen habe, eine Softwarebibliothek für digitale Bildverarbeitung kaufte.

Bildverarbeitung ist übrigens etwas komplett anderes als Bildbearbeitung, denn während man bei der Bildbearbeitung hauptsächlich daran interessiert ist, in einem gewöhnlichen Foto markante Features (wie Pickel, Falten usw.) verschwinden zu lassen (→sog. Photoshopping) ist das Hauptziel der Bildverarbeitung, genau solche Features reproduzierbar zu erkennen. Wir verwenden bei uns im G’schäft Bildbearbeitung, um die Sorgenfalten aus den Fotos der Geschäftsführer heraus zu retuschieren, während die Bildverarbeitung die Position der Chips in unseren Maschinen vermisst. Also nicht, dass diese Software (auch wenn ein Weinerliches Weichei wie ich damit zu Gange ist) sich in elegischen Iterationen darüber ergänge, wie sehr sie die alten Position der Chips vermisst und wie grundfalsch und abstoßend die neuen Position der Chips sind – die Software beschränkt sich schon nur darauf, die Position einfach festzustellen.


[Hightech Made in Germany]

Das jedoch kann ein durchaus aufwändiger Vorgang sein und deshalb lohnt es sich, jede Möglichkeit zu nutzen, die dafür benötigte Zeit zu minimieren. Eine sehr attraktive Möglichkeit, die benötigten Prozesse enorm zu beschleunigen, bietet dabei eine automatische Parallelisierung durch OpenMP. An einigen strategisch ausgewählten Stellen konnten wir damit die Zeit zur Lokalisierung eines komplexen Objekts in beliebiger Drehlage auf ein Viertel reduzieren, wenn alle vier Kerne des Core i5 in unserer Maschine ausgenutzt werden. Und mit den zwei Kernen der Core2 Prozessoren der älteren Modelle halbierte sich die Zeit immerhin noch. Wir hatten also mit sehr geringem Aufwand einen enormen Effekt erreicht und hätten sehr zufrieden und stolz sein können.

Was fehlt hier? Genau – ein “Wenn nicht…”. Und hier ist es:

Wenn nicht ein unerklärlicher Effekt aufgetreten wäre. Immer dann nämlich, wenn mindestens ein Kern der CPU schon ausgelastet war (immerhin wollte ja auch der Rest der Maschine noch irgendwie betrieben werden), explodierten die Zeiten förmlich. Was vorher 400ms gedauert hatte und durch OpenMP auf rund 100ms beschleunigt wurde, war dann plötzlich nach zwei Sekunden immer noch nicht fertig. Ja, das war etwas, das man in aller Bescheidenheit als einen wirklich fetten Showstopper bezeichnen konnte. Aufgrund dieses gelegentlich unvermeidbaren Seiteneffekts lag die Entwicklung über einen Monat auf Eis, während ich immer wieder versuchte, mir darüber klar zu werden, was dieses doch ziemlich unlogische Verhalten wohl auslösen mochte.

Überraschung! Natürlich hätte ich diesen Post nicht geschrieben, wenn sich dieser Zustand nicht genau heute geändert hätte. Einer Diskussion im GNU Bugzilla, die ich eher durch Zufall gefunden habe, konnte ich entnehmen, worauf ich selbst wohl nie gekommen wäre. Die Synchronisierung der Threads in GNU-OpenMP erfolgt im Normalfall mittels busy waiting! Das heißt nicht weniger als dass alle Threads, die schon fertig gerechnet haben, aktiv darauf warten, dass die restlichen Threads auch so weit sind – und aktiv warten heißt, dass dabei kein einziger Thread seine CPU frei gibt. Das wiederum führt dazu, dass letztlich überhaupt keine CPU-Zeit mehr frei ist und die Terminierung des Gesamtsystems auf Gedeih und Verderb den Lücken in der CPU-Belegung aller anderen Prozesse ausgeliefert ist.

Warum, so könnte man sich fragen, sollten ausgebuffte Profis aus dem Supercomputing-Bereich eine derart hirnrissige Synchronisierung programmieren? Die Antwort ist, wenn man sich die üblichen Einsatzszenarien solchen Codes ansieht, durchaus logisch: “Weil es Szenarien gibt, in denen diese Methode ihre Vorteile hat”. Im Supercomputing ist es nämlich durchaus üblich, dass sich aufwändige Berechnungen nicht gegen andere rüpelhafte Programme um die CPU-Zyklen prügeln müssen – und dann (allerdings eben nur dann) gewinnt man durch das aktive Warten den Vorteil einer deutlich geringeren Latenzzeit. Ob dieser Gewinn derart wertvoll ist, dass man diese Methode zur Standardeinstellung macht, könnte jedoch durchaus kontrovers diskutiert werden.

Die Latenzzeit ist mir nämlich herzlich egal, denn in diesem Zusammenhang ist die Rede von Mikrosekunden, während unsere Berechnungen sich immer im Millisekundenbereich abspielen. Glücklicherweise findet sich in dem länglichen Diskussionsthread auch eine Lösung für mein Problem. Es gibt eine Environment-Variable namens OMP WAIT POLICY, die man lediglich auf “passive” setzen muss – und schon stellen alle fertig gerechneten Threads brav ihre CPU dem Gemeinwohl zur Verfügung. Mein Code läuft dadurch im Durchschnitt um rund 120µs länger als im Idealfall, dafür aber skaliert die Geschwindigkeit jetzt wie erwartet mit der Anzahl wirklich verfügbarer CPUs. Problem gelöst.

Ich lerne mehrerlei aus dieser Geschichte.

  1. Wieder einmal entsteht das Problem an einer Stelle, wo man zuvor nicht einmal eine Stelle vermutet hatte.
  2. Was für den Einen ein zusätzlicher Gewinn ist, kann für den Anderen ein enormes Desaster sein
  3. Gut dokumentiert wird meist, was nicht als bekannt vorausgesetzt wird. Doch nicht alles, was als bekannt vorausgesetzt wird, ist auch jedem bekannt.
  4. Man sollte sich nie darauf verlassen,dass Standardwerte eine gute Einstellung für das eigene Problem sind.
  5. Und schließlich: Die Diskussion im Bugtracker zeigt schön, wie Menschen aneinander vorbei diskutieren können. Letztlich wurde nämlich nicht das eigentliche Problem gefixt, das der Reporter gemeldet hatte, sondern nur das Beispiel, das er zur Verdeutlichung angegeben hatte. Auch Fachleute mit gemeinsamem Fachgebiet sind nicht davor gefeit, einander gründlich misszuverstehen.

Mir soll’s recht sein, denn mein Bug wurde durch die Erkenntnisse aus dieser Diskussion gefixt.

/cbx, Kategorie: Aus der Schule - Linux LeidenSchaf(f)t

 

Eigener Senf dazu?

  1. The Angry Nerd gab am 25. September 2013, 23:41 folgenden Senf dazu:

    Als ich “OpenMP” las dachte ich direkt “Oh Gott, ist das nicht so ein Threading-Kram für C\C++? Himmel muss debuggen da eklig sein!”.

    Und ja, Spinlocks sind für einige Dinge erstaunlich gut geeignet und gar keine so hirnverbrannte Idee wie man glauben möchte, weil Kontextwechsel für CPUs fast so aufwändig sind wie für Menschen.
    Die 35% Verlangsamung aus dem Bugtracker scheinen mir sehr gut nachvollziehbar, wenn es eine Menge Locks gibt bei denen Warten unvermeidlich ist. Den Effekt hätte man so garantiert auch auf einem Desktop.

    Und ja, hätte ich mich mit verschiedenen Lockingmethoden nicht zufällig vor relativ kurzer Zeit beschäftigt, dann würde ich mich jetzt vermutlich ungläubig am Kopf kratzen, anstatt so zu klingen als ob ich irgendeine Ahnung hätte :D

    Bildverarbeitung kenne ich vor allem als “das Zeug, dass Alltagsbegriffe fachspezifisch mit Bedeutungen esoterischen Beiklanges überlagert”. Formen zu öffnen, zu schließen und eine Dilation darauf anzuwenden klingt irgendwie nach Waldorfschule und Erdgeistern.

    /cbx meint dazu:

    Hm, mit Multitasking (und Echtzeit) beschäftige ich mich jetzt auch schon seit ein paar tausend Wochen - insofern waren mir Spinkocks nicht unbekannt. Ich hätte eben nur nie gedacht, dass die irgendwo als generische Synchronisierung herhalten müssen, denn dazu scheinen sie mir schon ein bissl zu speziell in ihren Eigenschaften. Leider aber haben Menschen hier immer noch das Recht, nicht meiner Meinung zu sein...Und das mit der Waldorfschule verpetze ich unserem BV-Entwickler!

  2. Nordlicht gab am 26. September 2013, 06:53 folgenden Senf dazu:

    Glückwunsch zur Lösung!

    Und ein DANKE für dies hier: “…entsteht das Problem an einer Stelle, wo man zuvor nicht einmal eine Stelle vermutet hatte.”
    Göttlich.
    Daran wärme ich mich heute den ganzen Tag, da steckt was drin.

    In diesem Sinne gutes Werkeln wünscht
    Nordlicht
    (unter’m Regen)

    /cbx meint dazu:

    Schön, wenn es Dich wärmt. Das ist eine Variante der Weisheit, dass man in Gruben, mit denen man rechnet, nicht fällt (bzw. Probleme, die man erwartet, nicht auftreten).

  3. Hubert gab am 26. September 2013, 13:02 folgenden Senf dazu:

    Als nicht ganz unerheblich beteiligter Entwickler der angesprochenen Bildverarbeitungssoftware möchte ich kurz noch zur Abgrenzung des Begriffs Bild*ver*arbeitung beitragen: da ich eine angeborene Abneigung gegenüber Waldorfschulen habe und offenbar eine Phobie gegenüber Erdgeistern hege, kann ich garantieren, dass die Bildverarbeitungssoftware frei von Dilation und Erosion ist, womit sie möglicherweise eine atypische Ausprägung ihrer Art ist.

    Fachspezifische Begriffe lassen sich nicht völlig vermeiden, ob damit allerdings Alltagsbegriffe gemeint sind, hängt dann doch stark vom Betrachter ab. Das prominenteste Beispiel für Bildverarbeitung ist “pattern matching”, oder in anderen Worten: nichtlineare Optimierung bei durchschnittlich mehr als 90% Ausreißern. Aus meiner Perspektive ist sowas immernoch eine große technische Herausforderung. Die dabei verwendeten Techniken haben natürlich alle irgendeinen Namen (wie sollte Kommunikation auch ohne Namen funktionieren?): Gausspyramiden, Segmentierung, robuste Statistik, IIR Filter, Levenberg Marquardt, uvm.

    Um diesem Diskussionsbeitrag noch einen Bezug zum eigentlichen Thema zu geben: OpenMP war für diesen Fall eine interessante Möglichkeit, mit sehr geringem Entwicklungsaufwand die Vorzüge moderner Hardware ausnützen zu können. Das wirklich Schöne daran ist, dass ein und derselbe Quellcode mit sehr wenigen pragma-“Warzen” auf mehreren Plattformen läuft und mit einem einzigen Define Ein- und Mehrkernsysteme “optimal” unterstützt. Und was “optimal” bedeutet hat ja dieser Beitrag sehr erleuchtend erklärt. Danke!

    /cbx meint dazu:

    Dank für die erleuchtenden Geleitworte! Wobei ich meinerseits allerdings auch gerne zugebe, dass echte Bildverarbeitung für mich schon viel von - wenn schon nicht Erdgeistern, so doch - Voodoo hat. Und seit ich Deinen Code live vor Augen habe, um so mehr :-)

  4. Peter Suxdorf gab am 26. September 2013, 15:23 folgenden Senf dazu:

    @Hubert
    Du hättest auch Brrrzzzfgkhhklsdfj schreiben können. Häh? Kein Wort verstanden!
    Warzen auf Plattformen? Egal. Hauptsache das Teil läuft…

    /cbx meint dazu:

    Ja, wenn Experten ins Formulieren kommen, da bleibt kein Ohr trocken. Geht mit übrigens so, wenn mir jemand vom Fertigungsbetrieb als Vorschlag einen Stapel Materialbezeichnungen um die Ohren haut. Ich sage dann gerne mal: "Ich möchte das aus Eisen haben" oder wahlweise "aus Metall" ;-)

  5. The Angry Nerd gab am 26. September 2013, 18:21 folgenden Senf dazu:

    @ cbx

    Eigentlich sind Spinlocks ja nur schlecht wenn man Strom sparen will oder weniger Kerne für sich alleine hat, als man Threads besitzt. Ansonsten sind sie hervorragend.
    Bei einer Bibliothek für C oder C++ würde ich so etwas intuitiv erwarten, weil ich nur dann auf diese beiden zurückgreifen würde, wenn ich Performance aus etwas herausquetschen muss. Wenn ich das aber bei heutigen CPUs muss, dann frisst meine Anwendung vermutlich die CPU praktisch alleine. Mehr Arbeitsthreads als Kerne zu erzeugen… nagut, Hyperthreading…
    So ziemlich alles außer Spinlocks hat aber erhebliche Latenzen, die nur dann opportun scheinen, wenn man sich wirklich die Hardware teilen und kooperativ agieren muss. Dann ist aber nach Bauchgefühl die Performance auch nicht mehr so wichtig, dass man C oder C++ nehmen müsste.

    Wenn man sich dann überlegt, dass (vermutlich) viel von dem Multithreadingkram für C(++) aus der Welt des wissenschaftlichen Rechnens kommt, dann scheinen mir Spinlocks eigentlich die geradezu natürliche und offensichtliche Wahl zu sein.

    Und ja, wenn man sich mit genau dem Thema Prozesssynchronisation nicht zufällig beschäftigt hat, dann ist das alles ganz komisches, groteskes, opaques Zeug und man kann nur das tun, wozu ich bei den meisten Dingen dann auch immer wieder genötigt bin: sich an mehr oder weniger zufälligen Körperstellen zu kratzen.

    Wenn du mal mit was in Richtung Echtzeit kommst kannst du dir ziemlich sicher sein, dass ich statt dummer, hinter besserwischerischer Kommentare bestenfalls dumme Fragen von mir gebe.

    @ Hubert

    Ich glaube ich hätte etwas präziser sein müssen. Eigentlich ist es nicht Bildverarbeitung, sondern speziell Morphologie, bei der harmlos klingende Alltagsbegriffe komische Dinge bedeuten. Öffnen, Schließen und zumindest noch Erosion kennt man ja, Dila(ta)tion wenn man sich für Physik interessiert, aber der Bezug zu den morphologischen Operationen ist doch (anfangs zumindest) ziemlich abstrakt.

    Aber Bildverarbeitung ohne morphologische Primitive? Wen muss ich womit bestechen, um den Quellcode lesen zu dürfen? Das würde mich ernsthaft interessieren. Gerade weil ich über das Thema nur genug weiß um bei Levenberg Marquardt und Gauß Newton ein wenig zu frösteln und ansonsten gefährlich für Produktivcode zu sein.

    @ Peter
    “Pragma”-Zeug sind Anweisungen im Quellcode für den Compiler. Warzen sind das imo vor allem deshalb, weil man sich eigentlich im Code nicht mit Details des Verwurstens in ein laufendes Programm beschäftigen möchte.
    Stell dir vor du musst eine Zeichnung von einem Frästeil machen und dann Bereiche einzeichnen, die entweder grob weggefräst werden können oder nicht, um dann anzugeben, dass bei der Fertigung auf einer 3- statt 5-achsigen Maschine hier ein Loch rein darf, um nach dem Umspannen mit dem Fräskopf durch zu kommen.
    Klingt das nach Warze? :D

    /cbx meint dazu:

    1. Jaja, die Informatiker. Auch wenn ich Deine Argumente nachvollziehen kann... Wenn ich so etwas ähnliches wie Echtzeitfähigkeit auf einem System ohne harte Priorisierung durchziehen will, dann darf ich da halt keine Klugscheißer drin sitzen haben, die ein paar 100ms auf Spinlocks herumrödeln. Und wenn der Rechenaufwand bei gut optimiertem C-Code immer noch einige 10ms ist, dann kann ich auf ein paar 100µs weniger Latenz gut verzichten - auch, weil ich eben während dieser Rechenzeit noch CPU-Zeit für anderen Code brauche. Und - nein - so einen Amok laufenden CPU-Vernichter bekommt man auch mit einem richtigen Echtzeitsystem nicht unter Kontrolle. Da steht nämlich erfahrungsgemäß immer mindestens eine Priorität quer, es gibt eine Prioritätsinversion und die ganze Suppe kommt zum Stehen. Ich bleibe dabei - in einer Maschine will ich keine Prozess haben, der nicht weiß, wie blockierendes Warten funktioniert...

    2. Die Rechte für den Sourcecode liegen inzwischen bei uns - der Urheber aber ist Hubert. Aber ich glaube nicht, dass Du den Code wirklich sehen willst. Der ist zwar sehr schön, selbstdokumentierend und gut kommentiert, aber thematisch schon verdammt trocken.

    3. Die Erklärung für Peter ist ein Hammer. Ich verneige mich!

  6. The Angry Nerd gab am 26. September 2013, 20:01 folgenden Senf dazu:

    1. Du hast für die meisten praktischen Anwendungen völlig recht. Meine Begründung, warum ich Spinlocks erwartet hätte, fußt ja auch auf einer leicht stereotypen Annahme hinsichtlich der Verwendung von C und einem typischen Einsatzszenario, dass es in der “echten Welt” kaum gibt. Selbst dedizierte Systeme laufen ja heute meist virtualisiert und tun daher gut daran, nicht an den alleinigen Besitz von CPUs zu glauben. Ich glaube aber, dass die OpenMP Entwickler in etwa so ticken und vermutlich auch in weiten Teilen aus den Bereichen des wissenschaftlichen Rechnens mit dicken Büchsen kommen, die nur genau eine Aufgabe ausführen. In der Bugtracker Diskussion kam ja auch das Argument mit Benchmarks. Die werden garantiert, quasi per Definition, unter weltfremden Bedingungen durchgeführt.

    Falls der Funken Ironie nicht durchkam: Ja, Spinlocks sind meistens eine sehr schlechte Idee, weil die “kleinen Problemchen”, die es da gibt, genau die sind, die man meistens eben hat.

    2. Selbstdokumentierend, gut kommentiert… da macht mir einer den Mund wässrig!
    Lesen wollen würde ich ihn wirklich und die trockene Materie schreckt mich nicht ab. Bildverarbeitung finde ich (noch, mangels Ahnung) faszinierend. Viel eher sind da Dinge wie klamme Zeit und eine nachvollziehbare Unwilligkeit deinerseits, teuer bezahlte Geschäftsgeheimnisse zufälligen Fremden in die Hände zu geben, Hinderungsgründe.

    3. [herzt seinen Schein in Maschinenzeichnen]
    Ach, damals, als ich noch etwas Anständiges lernen wollte…

    /cbx meint dazu:

    1. So schließt such der Kreis. Ich habe ja schon im Post selbst vermutet, wes Geistes Kind die Schöpfer dieses Toolkits sind. Und - wichtig - mit dem korrekten Setup funktioniert es ja auch.

    2. Lass mich das mal ein Wochenende überschlafen.

    3. Ich habe mal meinen (damals sehr kargen) Lebensunterhalt mit dem Konstruieren von Trafostationen (MIT dem Häuschen) verdient. Wann immer ich daran zurückdenke, falle ich in panische Katatonie...

  7. The Angry Nerd gab am 27. September 2013, 04:54 folgenden Senf dazu:

    2. Das ist wirklich keine gute Idee. Das würde mich ebenfalls nötigen, dir nochmal ein Bier bei deinem nächsten Halt in München anzubieten, was du wieder ausschlagen müsstest…
    Und es birgt die Gefahr von Rückfragen. Ich würde es nicht tun.

    3. Trafostationen? Mit dem kompletten, ölgefüllten Ding, seinen Blechen, dem Krepppapier, dem Schallschutz, Peripherieteilen wie Buchholz-Relais, Mittel- und Niederspannungsschaltteil, der Berechnung des Streuflusses, Ölrückhaltevorrichtung etc?
    Also mein 12 Jahre jüngeres Alter Ego würde vermutlich laut “GEIL!” rufen.

    /cbx meint dazu:

    1. Wenn Du das sogar selbst empfiehlst....

    2. Leider nicht. Wenn's das gewesen wäre, hätte ich nicht nach einem Jahr hingeschmissen. Es waren nur Die Stationen mit der elektrischen Inneneinrichtung, leider nicht die Trafos. Das war ein gottverdammter Scheißjob - aber damals, frisch von der Uni habe ich doch ein Jahr gebraucht, um zu erkennen, dass ich da eine ganz besondere Niete gezogen hatte.

  8. Hubert gab am 27. September 2013, 11:46 folgenden Senf dazu:

    @Angry Nerd

    Bildverarbeitung hat oft den Mief, auf binarisierten Bildern einzig morphologische Operationen auszuführen. Ich will ja gar nicht abstreiten, dass man damit auch ganz interessante Ergebnisse erzielen kann, aber schlussendlich ist das die Technologie vor ca. 1990 (du kannst statt 1990 auch 1980 oder 2000 sagen, aber um ca. diese Zeit passierte dann ein Wandel). Die damalige (bezahlbare) Hardware hat wohl auch einfach nicht für mehr gereicht (Speicher und CPU Power). Insbesondere konnten binarisierte Bilder gut mit FPGAs oder ähnlicher Hardware “ver“arbeitet werden.

    Ich bin einfach kein Fan von Binarisierung. Natürlich setze ich auch Binarisierung ein, wenn es aus meiner Sicht und Erfahrung sinnvoll ist. Ein guter Moment für Binarisierung ist bspw., wenn Bilder sehr unscharf sind. Es ist erstaunlich, was man dann manchmal noch rausholen kann, entsprechende Vorsicht vorausgesetzt.

    Ab ca. 1990 setzt sich dann doch weitgehend die Verwendung von Grauwertbildern mit “beleuchtungsinvarianten” Feature Extractoren durch. Das funktioniert auch so einigermaßen: anstatt eines statischen Binarisierungsthresholds (oder einer smarten Funktion wie Otsu’s Method, um diesen zu schätzen), der entscheidet, ob ein Pixel an/aus ist, wird nun eher mit dem Begriff “Änderung von Hell auf Dunkel” gearbeitet. Dabei ist es dann gar nicht mehr so entscheidend, welchen genauen Wert die Grauwerte im Bild wirklich haben. Solange ihre Differenz ausreichend groß ist, verwendet der Algorithmus solche Stellen nach dem Motto “huch, da passiert etwas Aufregendes im Bild” -> Feature/Kante. Zusätzlich haben solche Features oft auch noch weitere Informationen: in diesem Fall bspw. gibt es eine Richtung, in der der Übergang von Hell auf Dunkel erfolgt. Wenn du bspw. diese Richtungen verwertest, hast du “ganz schnell” eine Bildsegmentierung geschrieben, die — ähnlich zu Höhenlinien — helle von dunklen Flächen trennt.

    Du merkst schon die Stoßrichtung: anstatt einfach auf den Grauwert zu schauen, verwenden wir die Differenz (== diskrete Ableitung) von zwei Pixeln. Das kann man natürlich auch erweitern auf mehr Pixel und/oder höhere Ableitungen (bekanntes Beispiel: Sobel-Operator). Aber Vorsicht: zuviele Ableitungen sind auch nicht so toll, da das Ableiten sehr empfindlich gegenüber Rauschen ist (deswegen immer zuerst ein bisschen glätten und dann ableiten).

    Solche “High level” Features haben also zwei Vorteile:
    1) falls sich die Beleuchtung ändert (bspw. die Lichtquelle wird durch Alterung dunkler), wird zwar das Bild gesamt dunkler aber der Unterschied zwischen hell und dunkel bleibt (beinahe) erhalten
    2) es gibt (bei den üblichen Bildern) viel weniger Stellen im Bild, wo sich helle und dunkle Flächen berühren, als es gesamt Pixel im Bild gibt (Datenreduktion)

    Das ist die Stoßrichtung, wie ich Bilder*ver*arbeitung sehe und angehe. Gerne mehr, wenn es dich interessiert.

    Danke für diesen vergnüglichen “Thread”.

    PS: selbstdokumentierend usw… hmmm, gerade ausreichend, dass ich als Urheber mich nach einiger Zeit noch einigermaßen zurecht finden kann.

    /cbx meint dazu:

    Wir danken für die umfassende Erörterung. Einen Kommentar allerdings kann ich mir nicht verkneifen. Als jemand, der andauernd die BV-Operationen sieht, die unsere Kunden so verwenden, kann ich nicht umhin, zu bemerken, dass die "Alterung einer Lichtquelle" als relevantes Problemfeld ungefähr so üblich und plausibel ist, wie ein Orgon-Akkumulator im Kernkraftwerk... :-)

  9. Hubert gab am 27. September 2013, 14:08 folgenden Senf dazu:

    @cbx

    Du hast natürlich recht, das Beispiel mit der Alterung der Beleuchtung war miserabel, aber wenigstens leicht verständlich und kurz zu tippen.

    Was aber in der Praxis wirklich vorkommt, sind beispielsweise leicht verkippte Bauteile. Da deren Oberfläche selten Lambertsche Materialen sind (diffuse Reflexion) sondern oft eher spiegelnd, hängt die Helligkeit des Bildes sehr stark von der Verkippung des Bauteils ab.

    Ähnliche Effekte gibt es auch mit Bauteilen, wo eine Art Dünnfilmeffekt zu Newton Ringen führt (bspw. viele Wafer die besputtert sind).

    Das sind Beispiele, in denen Binarisierung extreme Schwierigkeiten macht, bei denen aber die Featureextraktion wie oben beschrieben noch gelingen kann.

    /cbx meint dazu:

    Ja, wenn man den BV-Magier bei der Ehre packt... Diese Szenarien kann ich schon viel besser nachvollziehen. Dazu kommen noch ungleichmäßig passivierte oder (besonders beliebt) verdreckte(!) Chipoberflächen und dergleichen mehr. Nachdem mein Leidensweg als BV-Anwender und -Anwendungsentwickler noch mit binarisierter Strukturerkennung im FPGA angefangen hat, weiß ich die Vorteile der neuen Methoden nur zu gut zu schätzen...

  10. The Angry Nerd gab am 30. September 2013, 22:59 folgenden Senf dazu:

    So, jetzt komme ich noch mal zu einer Antwort…

    @ Hubert
    Ja, es zeigt sich auch hier wieder, dass die Gruppe der Softwarehanseln eine heile Welt ist, in der die Leute aus reiner Freude über ihr tun bereit sind Wissen auszuspucken, anstatt dafür abzukassieren. Danke dafür!

    Ich dachte bei Morphologie auch nicht unbedingt an Binarisierung. Man kann die Grundoperationen ja auch sinnvoll für Grauwerte definieren. Wenn ich mich recht entsinne, kann man so auch Kantenfindung und Segmentierung betreiben, indem man den morphologischen Gradienten als Differenz zwischen Dilation und Erosion berechnet.
    Vermutlich ist das Ergebnis aber ziemlich genau dasselbe, wenn man einfach die diskreten Ableitungen berechnet.

    Ja doch, je mehr ich darüber nachdenke, desto unspektakulärer erscheint mir die Aussage, dass der Code ohne morphologische Operationen auskommt.
    Mich würden auch brennend die Tricks und Kniffe interessieren, mit denen man aus absurd spiegelnden Chipoberflächen mit Dreckpunkten tatsächlich noch sicher die eigentlichen Kanten des Chips heraussließt, aber das würde wohl wesentlich zu weit führen.

    Ich glaube ich muss das Thema nochmal aufgreifen. Irgendwo habe ich noch eine Webcam und OpenCV könnte ich auch mal wieder installieren…

    Was die Kommentare angeht kommt mir die Äußerung auch bekannt vor. Bei mir endet das meistens in einem Verhältnis von 1:1 bis 2:1 zwischen Code und Kommentaren und trotzdem verstehe ich nach einem Monat oder zwei nicht mehr so recht, was der Affe sich bei dem Schmuh mal gedacht haben könnte.

    @ cbx
    Naja, auch wenn man die Trafos weglassen muss, so schlimm klingt es nicht. Hmm. Andererseits, wenn ich mir die Bilder deiner Prototypen so ansehe, dann scheint mir das in Relation zu dem, was du jetzt machst, doch ziemlich dröge.

    /cbx meint dazu:

    Ui, OpenCV - das würde ich persönlich als Lebenszeitverschwendung bezeichnen - ist aber nur meine Meinung. Und was die Trafostationen betrifft: Das war ungefähr so kreativ und abwechslungsreich wie Kartoffel schälen.

  11. Hubert gab am 1. Oktober 2013, 10:36 folgenden Senf dazu:

    @Angry Nerd
    Morphologie ist so ein riesiges Ungetüm (geworden). Ich denke, ein Teil der Faszination bei Morpholgie liegt darin begründet, dass sie sich mathematisch schön formulieren und darstellen lässt. Hier kann man rein formal tolle Dinge ableiten und mit Definition->Satz->Beweis weit kommen. Und ich mag das nicht besonders (obwohl ich Mathematiker bin!). Für mich persönlich ist das Hauptproblem bei Morphologie, dass die Ergebnisse oft nicht gut vorhersehbar sind (nicht lineare Operation, für lineare Operationen haben die meisten Menschen ein “Grundgespür” bzw. vehält es sich einfach “stetiger”), eine gewisse Instabilität in sich haben und extrem stark vom Strukturelement abhängen. Und lass sowas mal von einem Operator einstellen…

    Deswegen bin ich auch nicht davon ausgegangen, dass mein Verzicht auf Morphologie als spektakulär gelten könnte :-)
    Der wesentliche Trick bei der Bildverarbeitung ist, eine robuste Auswertung hinzubekommen, die rechnerisch nicht zu teuer ist. Die bekannteste Methode ist die Hough-Transformation (klassisch für Geraden und Kreise) und ihre Spielarten für andere Muster. Schlussendlich aber laufen die meisten stabilen Algorithmen dann auf eine Art Voting hinaus.

    Hat man das einmal geschafft, braucht man noch eine Idee, wie man dann sein neues Rechenzeitmonster zähmt. Zwei bekannte Ansätze dazu sind Randomisierung (bspw. RANSAC) bzw. Gausspyramiden. Eine effiziente Implementierung hilft auch. Immer attraktiver wird aber auch einfach rohe Rechenpower darauf anzusetzen (bspw. CUDA).

    Und ganz zum Schluss braucht man Erfahrung, Zeit und Glück, um die zahllosen “Magics” im Code auf ein vernünftiges Verhalten zu tunen. Vielleicht ist das der wirkliche Knackpunkt, ob eine Lib funktioniert oder nicht?

    Kommentare sind schon eine komische Sache. Ich habe für komplexe Codestücke festgestellt, dass der folgende “Entwicklungsprozess” für mich am effizientesten funktioniert:
    1) Schreibe eine Signatur mit Doku für die gerade benötigte Funktion (wenn das Doku schreiben zu lange braucht, ist die Funktion viel zu komplex und macht zuviel)
    2) Implementiere die Funktion
    Zeitmäßig braucht 1) fast immer länger als 2). Der angenehme Nebeneffekt: der Code ist einigermaßen strukturiert und dokumentiert.

    @cbx
    Es gibt hier in A eine größere Firma, die verstärkt auf OpenCV setzt. Aber ich teile da ganz deine Meinung :-D

    /cbx meint dazu:

    Ich trete mal in den Hintergrund und lasse die Aussagen für sich sprechen. :-)

  12. The Angry Nerd gab am 1. Oktober 2013, 19:17 folgenden Senf dazu:

    @ Hubert

    “Der wesentliche Trick bei der Bildverarbeitung ist, eine robuste Auswertung hinzubekommen, die rechnerisch nicht zu teuer ist.”
    Ich glaube, das kann man verallgemeinern. Der wesentliche Trick beim Programmieren ist es, einen robusten Algorithmus für irgendetwas zu basteln, der rechnerisch nicht zu teuer ist. ;)

    Wie darf ich mir denn das Voting bei robusten Algorithmen vorstellen? Verschiedene Ansätze der Erkennung, die jeweils einen Scoringwert ergeben und dazu eine Schwelle, die überschritten werden muss, um zwischen Objekt und Rauschen, bzw. verschiedenen Ausrichtungn, Dimensionen, etc, zu unterscheiden?
    (Ja, den Rest habe ich auch sehr interessiert gelesen, kann aber wenig dazu sagen oder fragen.)

    Dein Entwicklungsprozess kommt mir sehr bekannt vor. Ich entwickle zwar meist die Signatur während der Implementierung, aber der erste Schritt ist eine textuelle Beschreibung dessen, was der Kram tun soll. Würde man noch einen Test schreiben, bevor man die Methode implementiert, wäre man praktisch bei Test-Driven-Development. Dinge die über eine Methode hinausgehen und gefühlt komplex sind beginnen bei mir meistens auf (A3-) Papier, mit einer Art krudem UML-Klassendiagramm, um die Zusammenhänge und den Datenfluss irgendwie halbwegs erfassbar zu machen. Und ja, implementieren geht meist viel schneller, als es im Kopf zu ordnen.

    Was mich jetzt aber ernsthaft interessieren würde ist, was denn Leute mit Erfahrung in dem Bereich anstelle von OpenCV anraten. Neben den klaffenden Schluchten der generellen Ahnungslosigkeit, die sich ja schon in der Form anfänglicher Verwunderung über mangelnden Einsatz morphologischer Mätzchen gezeigt haben, ist mein praktisches Wissen in dem Bereich in etwa ein evakuierter Mariannengraben.
    Bessere Bibliotheken? Alles selber schreiben?

    Mir schien OpenCV im Rahmen meiner sehr, sehr kurzen Bekanntschaft (ein längerer Nachmittag) eigentlich ganz nett zu sein. So haben aber eigentlich vernünftige Leute schon über PHP gesprochen…

    /cbx meint dazu:

    Sagt mal, Ihr zwei, soll ich mal Eure Mailadressen auskreuzen?

  13. Hubert gab am 3. Oktober 2013, 14:37 folgenden Senf dazu:

    @Angry Nerd

    Tja, ich habe die kleine Welt der Bildverarbeitung auch immer als Abbild der großen Welt der “echten” Programmierung gesehen ;-)

    Der klassische Voting Algorithmus ist die Hough-Transformation

    Hier die Idee hinter allen Voting Algorithmen am Beispiel der Hough-Transformation für Geraden
    1) berechne alle Features in einem Bild (bspw. Kantenpunkte mit einer Orientierung)
    2) iteriere über alle Features und trage sie in einem “Akkumulator” ein (in unserem Beispiel könntest du aus xy-Koordinate des Features und Orientierung berechnen, welche Gerade das ergibt. Für diese Gerade würde dann in einem Akkumulator der Eintrag um +1 erhöht. Der Akkumulator könnte bspw. die 2d Matrix Steigung x Abszisse sein)
    3) suche im Akkumulator nach dem maximalen Wert (für den die meisten Features “gevotet” haben)
    4) die Features, die für diesen Maximalwert gevotet haben, sind die Inlier für die weitere Verarbeitung, der Rest sind Outlier

    OpenCV ist definitiv eine gute Library. Du wirst damit recht schnell Projekte umsetzen können. Die Library nimmt dir alle “low level” Probleme ab und hat auch für viele “high level” Probleme schon Lösungen parat. Trotzdem muss ich sie ja nicht mögen :-) Wo bleibt denn da noch der Spaß? Und Bildverarbeitung selbst zu entwickeln hat was pädagogisch Wertvolles: hier erlebt man den vielzitierten Murphy in seiner ganzen Pracht — von Anfang an und immer. Das lehrt Demut.

    Ansonsten ist auch HALCON einen Blick wert, falls du bereit bist, den geforderten Preis zu zahlen. Billig ist HALCON nicht…

    @cbx

    Sag mal, bist du neidisch? :-)

  14. The Angry Nerd gab am 4. Oktober 2013, 01:35 folgenden Senf dazu:

    @ cbx
    Von meiner Seite aus gern, also Mailadressen tauschen.

    Erst schimpfen sie beide über OpenCV wie die Rohrspatzen und wenn man nachfragt bleibt der eine stumm und der andere rudert zurück. Man könnte fast meinen, ich hätte nach Rudolph Hess gefragt…

    @ Hubert
    Hough sagte mir vom Namen her was, aber ja, jetzt weiß ich in welchem Sinne Voting gemeint ist.

    Und natürlich ist es immer pädagogisch wertvoll, das Rad neu zu erfinden. Das habe ich früh gelernt. Der Erfahrung nach würde es mich auch wundern, wenn Murphy hier nichtj zuschlagen würde. Das tat er sonst nämlich auch bei nahezu allem ;-)

    Halcon klingt interessant, aber zum Rumspielen und für Babys Ersten Ball-Tracker zögere ich dann doch, ernsthaft Geld in die Hand zu nehmen, wenn so etwas wie OpenCV zu haben ist.

    /cbx meint dazu:

    Mein Schweigen rührt da der, dass ich derzeit unterwegs bin und das hier suf meim iPod3 mache...

  15. Hubert gab am 5. Oktober 2013, 06:05 folgenden Senf dazu:

    @Angry Nerd

    Murphy ist natürlich ein omnipräsentes Allroundphänomen. Dennoch habe ich das Gefühl und die Erfahrung, dass er sich auf Bildverarbeitung ein wenig spezialisiert hat :-)

    “Das Rad neu zu erfinden” ist natürlich richtig. Eigentlich mache ich das aus reiner Faulheit nur sehr ungern. Die hier disukutierte Library stammt aber auch aus einer Zeit, als OpenCV bei weitem noch nicht da war, wo die Library heute ist. Was auf der Haben-Seite bleibt, ist aber die volle Kontrolle, was die Library wirklich macht. Oft ist es bspw. einfach auch bei Low Level Funktionen sinnvoll, ein bisschen Performance gegen ein bisschen Generizität einzutauschen.

    Und zu OpenCV: ich habe die Library nie ernsthaft selbst hergenommen, sondern nur immer ein bisschen beobachtet und damit herum gespielt (kein Einsatz im “Feld”). Inzwischen würde ich die OpenCV als gut bezeichnen, vor ein paar Jahren war das aber noch anders. Aber wie es eben so ist: nur weil es gut ist, muss es einem noch nicht schmecken, das ist ein bisschen wie mit der haute cuisine…

    @ cbx
    Kein Problem auf meiner Seite mit einem Mailadressenaustausch.

Kommentarfunktion für diesen Artikel geschlossen.