Farbstreifenerkennung auf Reifenprofil mit OpenCV

  • C++

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von seh.

    Farbstreifenerkennung auf Reifenprofil mit OpenCV

    Hallo,

    ich arbeite momentan als Werksstudent für eine Firma in Zülpich und meine Aufgabe ist es, mit der Bibliothek OpenCV eine Farbstreifenerkennung auf einem Reifenprofil zu erkennen.
    Dazu auch direkt mal ein Beispielbild im Anhang (10% verkleinert, sonst wäre das Bild zu groß).

    Nun mal zu meiner Aufgabe:

    Auf dem Reifenprofil kann man als Mensch ganz klar und deutlich die farbigen Streifen erkennen, nun ist es meine Aufgabe das ganze digital zu erkennen.
    Da ich hier zunächst erstmal nur als Werksstudent arbeite, und ich in der Bildverarbeitung noch wirklich null Ahnung habe, fällt mir das ganze sehr schwer. Ich habe schon viel recherchiert und mich zumindest ein wenig schlauer gemacht wie man das ganze Problem angehen könnte.

    Dabei dachte ich zuerst, ich könnte den Canny Kantenfilter auf das Bild anwenden um so, die farbigen Kanten, welche sich ja doch schon erheblich vom dunklen bis schwarzen Ton des Reifens abhebt.
    Dies hat leider nicht sehr gut funktioniert, es wurden zu viele Kanten gefunden die dem Reifenprofil selbst entsprechen, deswegen habe ich mich um entschieden und mir gedacht, dass es vielleicht besser ist, nach den Farben direkt zu suchen.

    Ich habe eine Liste von Farben, die auf den Reifenprofilen vorkommen können (sind ca. 10-12 Stück bis jetzt).
    Darunter Rot, Grün, Blau, Gelb, Cyan, Weiß, Braun, Lila, Orange und noch'n paar.

    Ich habe mir von meinem Ansprechpartner hier sagen lassen, dass ich mit dem HSV Farbmodell arbeiten soll, da dies die Arbeit erheblich erleichtern würde.
    Deshalb hab ich dann das Bild mit OpenCV geladen, und mit cvtColor() das Bild erstmal in das HSV Modell konvertiert.
    Nun habe ich ein Objekt vom Typ Mat welches mir mit den verschiedenen Indizes 0, 1, 2 den jeweiligen Channel H, S oder V liefert.

    Bis jetzt habe ich dann mühselig Farbwerte von-bis rausgesucht und mit der Funktion inRange() die Farben rausgefiltert.
    Danach hab ich die Funktion HoughLinesP() auf das Bild angewandt, welche mir dann einen vector<Vec4i> zurückliefert mit den gefundenen Linien.

    Das hat auch viel besser funktioniert als mit dem Kantenfilter.
    Das Problem ist nur, wenn man sich das Bild im Anhang mal anschaut und ganz nah ranzoomt, kann man erkennen, dass die Farbstreifen Pixel nicht durchgehend z.B. grün sind. Es sind auch schwarze Pixel darin bzw. dunkle Pixel, weshalb die Linienerkennung nur teilweise gut funktioniert. Er findet dann den grünen Farbstreifen nicht als eine Linie, sondern als viele verschiedene Linien.
    Ich hab mir dann erstmal gedacht, gut solange er generell grün oder was auch immer eine Farbe, gefunden hat, ists ja gut. Ich kenn die Position der Linie und weiß, um welche Farbe es sich handelt.

    Nun gibt es nur leider auch den Fall, dass zwei grüne Linien sehr nah untereinander liegen, was natürlich bedeutet, das die zweite Linie auch im selben vector<Vec4i> liegt.
    Ich muss also innerhalb dieser Vec4i Liste zwischen beiden Linien unterscheiden können, und da die Breite der Linien, je nach Sprühdichte unterschiedlich sein kann, wird das ganze sehr schwer zu erkennen.

    Also überlege ich auch hier noch, ist es der richtige Ansatz nach den Farben zu suchen oder gibt es vielleicht doch noch eine ganz andere bessere Möglichkeit?

    Mein Ziel ist es, dass ich jetzt erstmal eine Textdatei habe, wo in jeder Zeile eine Farbe drin steht, diese Textdatei auszulesen und in der Reihenfolge wie sie in der Textdatei untereinander stehen, müssen die Farben auf dem Reifen vorkommen. Sobald eine Farbe schon nicht gefunden wurde oder die Reihenfolge nicht übereinstimmt, kann abgebrochen werden.

    Ich hoffe ich habe mich deutlich genug ausgedrückt und wäre für Lösungsvorschläge dankbar.

    Sorry für den langen Text, aber ich muss ja irgendwie zum Ausdruck bringen was mein Vorhaben ist, ich hoffe nur, dass der lange Text nicht die meisten schon abschreckt.

    Edit: Ich habe noch ein zweites Bild (img.png) angehangen. Das Bild ist einmal vertikal gespiegelt deshalb nicht wundern, aber es ist erstellt worden vom ersten Anhang. Rausgefiltert wurde dort jetzt die Farbe grün und so sieht das Binary Image danach aus. Darauf wende ich dann ​HoughLinesP und dort findet er halt mehrere Linien auf einer Linie, packt aber alle in den ​vector<Vec4i> rein.
    Mit mehrere Linien von einer Linie meine ich, der Algorithmus erkennt den Streifen auch nicht als eine Linie sondern mehrere. Mehrere in X Richtung wäre nicht das Problem, da er aber die Linien immer nur mit 1px Breite erkennt, macht er, weil der Farbstreifen dicker als 1px ist, mehrere untereinander. Das bedeutet die Linien, die eigentlich zu einer grünen Linie gehören, haben unterschiedliche y Werte. Diese müsste ich dann zusammenfassen, was, wenn es nur eine grüne Linie wäre kein Problem wäre, ich könnte die Linien iterieren und deren y Werte einfach auf einen durchschnittlichen y Wert aller y Werte setzen. Da es aber in diesem Fall z.B. zwei grüne Linien gibt, sind die Y werte von den Linien natürlich unterschiedlich und am ende würde ich 2 Linien im vector haben wollen.

    Danke im Voraus

    Mit freundlichen Grüßen
    seh
    Bilder
    • vb ready.png

      16,81 MB, 6.898×1.843, 240 mal angesehen
    • img.png

      46,91 kB, 7.664×1.070, 197 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „seh“ ()

    @seh Willkommen im Forum. :thumbup:
    Zunächst die Frage: Was soll der Output sein?
    Die Arbeit im HSV-Raum ist in Ordnung.
    Wichtig ist zunächst, dass Du eine vernünftige Vorverarbeitung des Bildes machst. Da stellt sich die Frage, wie die Bilder konditioniert sind.
    Also:

    seh schrieb:

    Es sind auch schwarze Pixel darin bzw. dunkle Pixel, weshalb die Linienerkennung nur teilweise gut funktioniert.
    Da musst Du Dir einen Filter bauen, der diese Pixel eliminiert.
    Ist die Lücke nur ein oder zwei Pixel breit AndAlso sind die Quer-Sprünge der Zielbereiche auch nur ein oder zwei Pixel, kannst Du einen speziellen Filter bauen, der die Fehlpixel eliminiert.
    Mit Erosion, Dilation und Median-Filterung bei einer geeigneten Filterbreite sollte das zu machen sein.
    Zuerst Farben (Deine Zielfarben) vom Untergrund trennen und dann auf den Zielfarben "rumfiltern", dazu musst Du ein wenig experimentieren, um die Zielbereiche stehen zu lassen.
    Teste Deine Filterkombinationen an sehr vielen unterschiedlichen Bildern, um sicherzustellen, dass viele (alle geht meist nicht) Möglichkeiten abzudecken.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo @RodFromGermany

    Danke für deine Antwort das hat mir schon mal sehr geholfen.
    Um zunächst deine Frage zu beantworten

    RodFromGermany schrieb:

    Was soll der Output sein?


    Im Prinzip geht es nur darum, dass ich nachher irgendwie die Möglichkeit habe, am besten so einfach wie möglich, die Farben erkenne, es muss keine durchgehende Linie von links bis rechts sein, wichtig ist nur, das er, wenn zwei gleichfarbige Linien untereinander liegen, diese auch als 2 Linien erkennt und nicht als eine.
    Das bedeutet zwischen den beiden Linien ist wieder Reifenprofil, aber der Abstand der beiden Linien kann sogar geringer sein, als die Breite der Linie selbst und die Breite ist halt noch variabel, das kommt noch dazu.

    Output, wie genau definierst du das?
    Ich stelle mir das so vor, dass ich am besten nachher einfach nur noch eine Liste (in C++ nutze ich vector) von Vec4i.
    Vec4i ist von OpenCV und ist einfach eine Klasse mit 4 Ganzzahlen. Damit kann ich eine Linie darstellen X1, X2, Y1, Y2.
    Am besten wäre es am Ende, wenn ich für jede Farbe eine Liste habe und dort jeder Eintrag einfach eine farbige Linie darstellt.
    Mir ist klar, das die Breite der Linie dann technisch in der Liste nur 1px entspricht und nicht, wie im Bild mehr Pixel, aber darum geht es auch nicht. Hauptsache in der Liste sind 2 Vec4i Elemente wenn zwei gleichfarbige Linien auf dem Reifen sind.
    Sobald dort zwei Elemente drin sind, weiß ich ja anhand der Y-Koordinate der Linie an ob sie über der anderen oder unter der anderen bzw. den ganzen anderen Linien sind, da ich das dann durch iteriere und alle miteinander vergleichen würde.

    Im Moment bin ich halt soweit, das einige Farben die ich implementiert habe erkannt werden, und dann Linien die gefunden werden in dieser Liste abgespeichert werden.
    Problem ist halt nur, das eine Linie die auf dem Bild ist, als mehrere Linien erkannt wird, da die Linie auf dem Bild ja nich nur 1px breit ist und auch noch dunkle Pixel in der Mitte des Streifens sind welche dann die Linie auch nochmal unterbrechen.

    Da ich hier mit einer Visualisierungssoftware arbeiten muss, hab ich mir erlaubt einen Wrapper von OpenCV herunterzuladen (Emgu) und ich mir gerade eine kleine CSharp App geschrieben habe, mit der ich viel schneller rum experimentieren kann.
    Da probiere ich jetzt erstmal rum, und spiele mit den Parametern für die HoughLines Funktion (Threeshold, Min Line Width, Max Gaps) usw.
    Dadurch versuche ich jetzt schonmal die Anzahl der Linien die gefunden werden zumindest zu verringern.
    Aber irgendwie habe ich das Gefühl, dass selbst das nicht wirklich effizient ist.

    Ich werde mir wohl mal genau anschauen müssen, was bei Erosion, dilation und Median Filterung passiert. Damit kenne ich mich nämlich wie gesagt noch nicht aus und probiere einfach mal aus, was das ganze auf dem Bild eigentlich macht.

    Danke für die Stichworte. :thumbup:
    ich würde dabei von oben nach unten suchen und das für jede Pixelspalte einzeln. Wenn es weiter nach unten nur geringe Differenz zum vorherigen Pixel gibt, so handelt es sich um diesselbe Linie. Die Position der Linie in der jeweiligen Spalte ist der Mittelpunkt zwischen Anfang und Ende der Farbe.
    Das ganze machst du für jede Spalte und sortierst dabei z.B. alles aus, was zu wenig oder zu viel Linien als Ergebnis hat. Danach berechnest du für die übriggebliebenen Linien den Durchschnitt auf der Y-Achse um eine schöne Median-Linie zu erhalten. Dabei dürfte das korrekte Ergebnis am ehesten das sein, das am häufigsten erkannt wurde. Der Algorithmus ist vmtl nicht perfekt, aber dürfte grundsätzlich funktionieren, um Ergebnise entsprechend zu verbessern kann man das Bild dann z.B. auch vorfiltern. Evtl. ein Biliteraler filter
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    seh schrieb:

    Output, wie genau definierst du das?
    Was erwartet Dein Chef von Dir?
    Ein Bild mit bunten Linien, eine Tabelle mit vielen Zahlen, einen singulären Qualitätswert, ...?
    @jvbsl Jou, das kam mir auch inzwischen in den Sinn.
    Wenn man das mit nem H-Raum-Histogramm macht, könnte ich mir vorstellen, dass das ganze hinterher genial einfach ist.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Guten Morgen,

    mein Chef erwartet von mir im Moment einfach nur Teilerfolge. Damit meine ich, dass ich mich mit der Bildverarbeitung und C++ vertraut machen soll und ihm täglich berichte, was ich denn am vergangenen Tag geschafft/gemacht habe. Er erwartet jetzt nicht von heut auf morgen ein voll funktionsfähiges Programm.
    Wir arbeiten hier mit einer Visualisierungs Software die von dem Betrieb hier selbst entwickelt wurde. Diese Software ist so entwickelt worden, dass man Bibliotheken dynamisch laden lassen kann und darin befindet sich dann die Software die ich entwickeln soll. Mit der Visualisierungssoftware kann ich per grafischer Oberfläche meine Bibliothek auch steuern. Grundsätzlich wird in der Software das Reifenbild geladen, und dann die Logik der Bibliothek darauf angewandt. (D.h. das Bild wird an die Bibliothek übergeben und und und). Es wird auch ein HDC übergeben das ein Fenster in der Software selbst ist und das Bild darstellt.

    Mit dem HDC hab ich bisher per GDI als Overlay die gefundenen Linien einfach nochmal nachgezeichnet. Somit konnte ich dann immer die Ergebnisse sehen.
    Wie genau das am Ende funktionieren soll weiß ich noch gar nicht, also ob die Reihenfolgendatei einfach abgearbeitet werden soll und ne Fehlermeldung erscheinen soll das der Reifen falsch ist oder die Streifen nicht erkannt wurden. Oder ob das ganze nachher in eine Datenbank abgespeichert werden soll? Keine Ahnung, aber soweit bin ich ja auch noch nicht, grundsätzlich soll ich "einfach" erstmal die Farbstreifen erkennen und dessen Position, und das möglichst präzise.

    @jvbsl

    Danke auch dir für deine Beteiligung am Thema. Ich bin nicht sicher ob ich das schon vollständig verstanden habe. Also das Bild ist ja relativ dunkel, bis auf die Farbstreifen. Hab ich das jetzt richtig verstanden, dass ich also wenn ich nach grün suche, oben anfangen soll und sobald sich ein Pixel in Y-Richtung schlagartig verändert, wird geprüft ob der nächste Pixel nur noch eine geringe Differenz hat? Wenn ja, ist es noch die selbe Linie und es wird wieder ein Pixel in Y-Richtung weiter geprüft? Was ist aber mit den schwarzen Pixeln die im Farbstreifen selbst noch drin sind? Also ich denke zu verstehen was du meinst, das eine Änderung der Farbe ja immer einen Farbverlauf (Gradient?) hat, dem ist natürlich auch hier so, allerdings sind hier ja leider in der Mitte der Farbstreifen auch mal total dunkle Pixel drin, weil die Farbe an den Stellen nicht flächendeckend genug war. Dann wäre das mit der Differenzprüfung zum vorherigen Pixel ja fehleranfällig weil er dann denkt, hier ist die Linie vorbei und wenn dann 2 Pixel weiter unten das nächste grüne Pixel kommt, meint er, das eine zweite grüne Linie kommt.

    Oder hab ich das jetzt noch nicht ganz verstanden? Ich bin jetzt seit 08:00 Uhr wieder auf der Arbeit und versuche jetzt mal was dabei raus kommt wenn man die einzelnen genannten Filter auf das Bild anwendet. Vielleicht kann ich dadurch diese dunklen Pixel in den Farbstreifen eliminieren.

    Danke :)

    Edit: Ich habe jetzt mal ein wenig mit Erosion, Dilation und Median Filterung rum gespielt und muss doch sagen, dass die Fehlerpixel (dunkle Pixel in dem Farbstreifen) recht gut eliminiert worden sind. Im Anhang befindet sich nochmal ein vorher(segment.png) nachher(after.png) Modell.

    Ich denke, wenn ich die Methode von @jvbsl richtig verstanden habe, würde das nach der Dilation und Median Filterung besser funktionieren, könnte ich mir zumindest vorstellen. Was meint ihr? :)

    Klar, es sind immer noch ein paar Farbabweichungen drin, gerade dort, wo die "Profil Lücke" ist, aber das Ergebnis ist doch schon mal besser als vorher, oder nicht?
    Bilder
    • segment.png

      861,87 kB, 450×1.208, 172 mal angesehen
    • after.png

      409,62 kB, 450×1.208, 197 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „seh“ ()

    seh schrieb:

    oder nicht?
    Die Frage muss Dein Chef beantworten.
    Und: Das, was @jvbsl als Median-Linie bezeichnet, hat nix mit meinem Median-Filter zu tun :!:
    Bildverarbeitung in diesem Sinne ist zunächst hauptsächlich Spielen mit Operatoren (welche, wie oft, in welcher Reihenfolge), um dann den gewünschten Output zu erzielen.
    Ganz wichtiges Problem: Die Bilder von gestern funktionieren alle, die von heute nicht so gut.
    Hier musst Du den Algorithmus robust machen. Wenn Du eine Änderung vornimmst, musst er die alten Bilder genau so gut behandeln wie die neuen.
    Klar, Ziel ist, dass in Zukunft alle Bilder funktionieren. Sagen wir fast alle, denn wenn eine Lampe ausfällt, ist das Bild schwarz.
    Solche elementaren Tests musst Du auch einbauen, dass z.B. ds Bild Deiner Freundin als nicht verarbeitbares Bild erkannt und vom Algo abgelehnt wird.
    Ich würde etwa so vorgehen:
    Bild nach HSV konvertieren,
    Median,
    Helligkeitshistogramm, alle Pixel, die dunkler sind als xx werden auf schwarz gesetzt.
    Übrig sollten dann die bunten Streifen bleiben.
    Von denen machst Du ein Farb-Histogramm, da sollten die einzelnen Farben sauber getrennt sein. Überzeuge Dich davon.
    Nun kannst Du alle Farbpixel einer Farbgruppe (grün, rot, blau, braun) durch ihren Farbmittelwert bei voller Helligkeit ersetzen.
    Nun gehst Du über die einzelnen Pixel-Spalten Deines Bildes (von oben nach) und ermittelst alle Farbkanten, die müssten nun absolut scharf sein und daraus den Mittelpunkt jeder Farbe.
    Sind in einer Spalte keine Farbkanten vorhanden, wird sie einfach ignoriert, das wäre dann eine "Volllücke".
    Nun musst Du nur noch alle Mittelpunkte gleicher Farbe (desselben Streifens, wir haben ja 2 Mal grün) verbinden, und da springst Du, wenn eine Lücke ist, einfach darüber oder ersetzt sie durch den Mittelwert von links und rechts.
    Feddich. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hey,

    ich danke Dir für die vielen Informationen.
    Mein Chef war vor 10 Minuten auch da, und wollte wissen wie der Stand war, und da hab ich ihm einfach mal die vorher-nachher Bilder gezeigt. Er war davon beeindruckt und hätte nicht gedacht, dass das so gut funktioniert ^^

    Er meinte damit lässt sich auf jeden Fall viel besser arbeiten, ich soll aber, aufgrund der Dilation nochmal an Bildern testen wo gleichfarbige Streifen nah beieinander liegen, nicht das die Dilation (welche die Objekte ja auch vergrößert) zwei Linien zu einer machen.

    Die Idee, dunkle Pixel ab einem gewissen Wert auf schwarz zu setzen finde ich interessant, damit kann man mit hoher Wahrscheinlichkeit bei der Klassifizierung auch viele Störfälle eliminieren. Das werd' ich gleich mal einbauen und schauen wie es so funktioniert.

    Danke auch für den Lösungsvorschlag den du beschrieben hast, ich werde das genau so alles mal ausprobieren und schauen wie weit ich komme.
    Ich werde euch die Ergebnisse dann hier mitteilen.

    Grüße
    seh
    @seh Mir gefällt es, wie Du an das Problem herangehst und auch unsere Antworten auf Deine Fragen mit einbeziehst.
    Deswegen ein Hilfreich. :thumbup:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany Ich danke Dir :)

    Ich habe gestern leider nicht mehr so viel geschafft, aber das mit dem Setzen der Pixel auf schwarz, wenn die Helligkeit unter einem bestimmten Wert xx ist, hat bis auf ein paar Stellen ganz gut funktioniert. Als ich mir das Bild angeschaut habe, merkte ich direkt, dass es jetzt viel einfacher aussieht die Farbstreifen vernünftig zu verarbeiten.

    Heute Morgen hab ich mir dann noch mal ein wenig Gedanken darüber gemacht wie ich weiter mache, und hab auch einfach mal blind losgelegt meine HSV-Farbräume die ich für jede Farbe schon einmal angelegt hatte auf das Bild anzuwenden sodass ich dann ein Graustufenbild (Maske), wo dann die Farbe komplett rausgefiltert wurde, erstellt wird.

    Das war dann natürlich wieder etwas unregelmäßig, aber ich hab' mir dann ne kleine Funktion geschrieben, welche die Pixel iteriert und (da jetzt das Bild ja nur noch schwarz-weiß ist) prüfe ich jeden Pixel ob er nicht schwarz ist. Wenn ich in einer Zeile nicht-schwarze Pixel gefunden habe, zähle ich die Anzahl der Pixel die nicht schwarz sind in dieser Zeile und prüfe dann anhand eines Schwellwerts ob die Anzahl der Pixel in dieser Zeile eben über einem bestimmten Wert ist. Sollte dies der Fall sein, werden alle Pixel dieser Zeile auf weiß gesetzt.
    Wenn nicht, werden alle Pixel der Zeile auf schwarz gesetzt (eliminiert die kleinen Fehler die nach der Entfernung aller dunklen Stellen noch existierten).

    Damit hatte ich dann bei den Farben die ich bisher getestet habe eine sehr hohe Erkennungsrate.
    Jetzt bin ich aktuell dabei ein kleines Tool zu schreiben mit Schiebereglern für Minimal und Maximal HSV Werte die, wenn ich die TrackBars bewege, direkt die Farbe aus dem Bild filtert. Damit kann ich dann schnell und präzise die HSV Werte für die restlichen Farben erstellen und testen.

    Bilder müssen warten, ich weiß nicht wieso, aber das Hochladen von Bildern schlägt hier gerade fehl. Das Internet hier ist aktuell generell am Spinnen.

    setBlack.png -> Das Bild nach Dilation + Median Filterung + setzen der Pixel auf schwarz wenn unter einer Helligkeit von xx.
    greenRangePlusFillLinesAlgo.png -> Grünfilterung + mein kleiner Algorithmus der die Linien vervollständigt.

    Jetzt ist es einfach :D

    Grüße
    seh
    Bilder
    • setBlack.png

      35,71 kB, 450×1.208, 171 mal angesehen
    • greenRangePlusFillLinesAlgo.png

      2,51 kB, 450×1.208, 154 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „seh“ ()

    @seh Wenn Du mit Reglern arbeitest, ist es sinnvoll, das zu bearbeitende Bild online darzustellen.
    Da brauchst Du jedenfalls schnelle Algorithmen, mit denen Du im Bild arbeitest: Operator1 -> Darstellung, Operator2 -> Darstellung, ...
    Da Du mit C++ arbeitest, sollte das allerdings kein Problem sein.
    So kannst Du sehr gut ein Gefühl entwickeln, wie ein Operator auf das Bild wirkt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wenns wirklich um Geschwindigkeit geht:
    lies dich etwas zu OpenMP und SIMD ein. Außerdem natürlich alles inlinen, damit kann man auch alles trotzdem architektonisch schön machen, natürlich muss aber der komplette Algo in derselben Library sein, denn aus Shared-Libs kann nicht inlined werden(da inlining bei C++ - nicht wie bei C# - zur Compiletime passiert).

    Und noch mehr kann man dann vmtl. mittels OpenCL/Cuda/OpenGL ComputeShaders/DirectX Compute Shaders erreichen. Denn die GPU ist für solche Sachen da - dabei muss aber möglichst alles mit floating point operations passieren, sind nämlich auf der GPU wesentlich schneller als integer operationen.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    @RodFromGermany und @jvbsl

    Guten Morgen.
    Geschwindigkeitsoptimierung wird wohl später noch ein Thema sein meinte mein Chef. Erstmal liegt die Konzentration möglichst viele Farbstreifen auf möglichst vielen verschiedenen Reifen zu erkennen.

    Ich bin jetzt gerade wieder auf der Arbeit und habe mit meinem Chef gerade noch einmal den Ablauf besprochen. Das was ich jetzt alles in CSharp umgesetzt habe, portiere ich jetzt auf C++ (ich hatte zwischendurch mit Emgu gearbeitet weil ich CSharp besser kann und somit schneller rumprobieren kann).

    Prinzipiell beginnt danach die Feinarbeit. Testen mit den verschiedensten Bildern, Eliminierung von kleinen Fehlern und einen Spezialfall muss ich auch noch beachten.
    Manchmal sind auf den Reifenprofilen fette weiße Aufkleber drauf. Ich hatte überlegt das Bild, zum einen für Performance Schub, in kleine Segmente aufzuteilen und erstmal nur jedes einzelne Segment nach dem anderen zu prüfen, solange bis eins komplett richtig ist. Für den Fall, dass im ersten Segment der fette Aufkleber ist und dort nichts finden würde, geh ich zum nächsten Segment. Spätestens beim dritten Segment sollte der Aufkleber dann zu Ende sein. Falls Farbstreifen mal unklar sind, wegen z.B. der Sprühdichte oder Dreck, wird auch einfach das nächste Segment geprüft.

    Sind halt alles so kleine Spezialfälle, die eintreten können, aber durchaus beachtet werden müssen.
    Aber es geht gut voran. :thumbup:

    seh schrieb:

    fette weiße Aufkleber
    Ob solche Dinger ühaupt drauf sind, kannst Du ggf. mit nem Histogramm schneller überprüfen.
    Farbbild => Monobild, Histogramm, Suche im Histogramm nach einem hellen Maximum, dessen Fläche im Vergleich zur Gesamtfläche auswerten. Wenn größer als [Range], dann sind welche vorhanden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Jaa, so wie du es formuliert hast klingt es eigentlich ganz einfach, ich setz' mich da demnächst mal ran.

    Im Moment habe ich ein paar Bedenken wie ich ein gewissen Problem lösen kann.
    Und zwar ist die Farbe rot im HSV Raum ja etwas komplizierter. OpenCV's Hue Wert geht ja von 0-179 und die Farbe rot ist halt genau an so einer Grenze.
    Der Hue Wert kann zwischen 0-10 und 170 - 179 sein.

    Wie ich das lösen kann ist mir bewusst, ich erstelle einfach zwei Masken die eine von 0-10 und die andere von 170-179. Die beiden Masken werden dann mit 'nem bitwise_or zusammengefügt.

    Da die Software später verkauft werden soll und mein Chef möchte, dass die Farb-Ranges einstellbar sind, muss ich noch einen Dialog einbauen in dem ich eine Min. und Max. Hue, Value und Saturation setzen kann.

    Wo ich jetzt gerade nicht weiter komme ist, wie ich die Oberfläche gestalten soll, damit man z.B. mehrere Farb-Ranges z.B. für die Farbe rot definieren kann.
    Im Prinzip hatte ich an eine Art ComboBox gedacht, wo man erstmal die Farbe auswählen kann die man bearbeiten will, und dann werden (leider aus der Registry) die Farb-Ranges in z.B. eine Listbox geladen. In der Listbox wären dann für die Farbe rot zwei Einträge statt für die anderen Farben nur einer.

    Das ganze klingt für mich allerdings recht kompliziert, ich hab auch noch keine Erfahrung in Win32 GUI Programmierung. Ich kenne mich leider auch nicht so gut mit den Design Richtlinien aus, vielleicht gibt es ja eine bessere Lösung als die, die ich jetzt erläutert habe ?!

    Danke im Voraus

    Grüße
    seh

    seh schrieb:

    Der Hue Wert kann zwischen 0-10 und 170 - 179 sein.
    Dann ist da was nicht ganz richtig.
    Üblicherweise wird H auf einen Winkelbereich von 0° bis 360° umgerechnet, da gibt es einen ganz eleganten Übergang von 359° nach 1° ohne die geringsten Probleme, gugst Du hier.
    Auch wenn Ihr da andere Grenzen habt, lässt sich das per Modulo immer auf einen ordentlichen Bereich transformieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hi @RodFromGermany

    das der Hue-Wert vom HSV Modell normalerweise von 0-360° geht, ist mir durchaus bewusst. Bei OpenCV aber ist es tatsächlich so, dass sie den Hue-Wert von 0-179° implementiert haben, aus dem Grund, damit der Wert in ein Byte rein passt. Genauso wie Saturation und Value nicht von 0-99 sondern von 0-255 geht. Ich hab's mir nicht genau angeschaut, aber so sind die Bereiche bei OpenCV zumindest.

    seh schrieb:

    damit der Wert in ein Byte rein passt.
    Die haben noch die alten Rechner mit einer Verarbeitungsbreite von 8 Bit und 64 KB RAM. :thumbsup: :thumbsup: :thumbsup:
    Mach es richtig mit 32 / 64 Bit und zirkumpolaren Randbedingungen.
    Entweder Du machst da einen Wrapper drum herum oder Bu musst mit Winkeln von [0°, 180°) rechnen.
    Das ist alles kein echtes Problem, nur reine Fleißarbeit.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    oder Bu musst mit Winkeln von [0°, 180°) rechnen.


    Naja, ich denke es wäre ein wenig Overhead jetzt noch irgendwas drum herum zu basteln. Ich bin mir nicht mal sicher, was dann alles gemacht werden müsste. Intern läuft da recht viel mit Matrizen ab. Und zum Beispiel die ​inRange() Funktion, welche ich zum erstellen einer Maske benutze, schreibt nachher in eine 8-Bit Matrix die Maske rein. Das müsste ich doch dann alles selbst machen.

    Ist mir jetzt ehrlich gesagt zu viel, dann mach ich's lieber jetzt erstmal mit den zwei Masken die von 0-10 und von 170-179° gehen.

    seh schrieb:

    erstmal
    wäre es besser, gleich eine ordentliche Lösung zu machen.
    Denke zwei Tage darüber nach und Deine ordentliche Lösung ist eine Woche früher fertig, als die schmudddelige.
    170 bis 190 wird dann intern per Modulo 180 auf 170 bis 179 und 0 bis 10 abgebildet,
    -10 bis 10 wird ebenfalls auf 170 bis 179 und 0 bis 10 abgebildet.
    Alles kein Akt.
    =====
    Bist Du an OpenCV festgenagelt?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!