Zwei Bilder miteinander vergleichen...(Diskussion)



  • Das Stichwort hierbei ist "ScanLine" der Bitmap. Damit liest du eine ganze Pixelzeile des Bildes ein und kannst dann in einer Schleife da durch rasen!

    Das Problem ist denke ich das wenn du ein und das selbe Zuckerkörnchen 10 mal aufnimmst, wahrscheinlich 7 verschiedene Farbwerte dafür bekommst. Das liegt zum einen am Licht zur Zeit der Aufnahme, und anderen äusseren Faktoren. Zum anderen daran was der Sensor der Kamera daraus macht, und dass ist nicht immer die gleiche Farbe.

    Man könnte sich einer Farbpalette mit weniger Farben bedienen, sagen wir 16 Farben für weiss. Es gibt dann API-Funktionen die dir zu einem Color-Wert einen am besten passenden Color-Wert aus dieser Palette liefern. Aber dann hast du immer noch verschiedene "weiss". Man müsste dann evtl einen Algorithmus schreiben, der verschiedene Farbdistanzen berücksichtig etc.

    Die Arbeit mit Farbpaletten ist schon uralt, wird aber noch unterstützt von Windows.

    MfG



  • In inneren Schleifen wilsst Du Ausgaben machen.
    Label2->Caption = IntToStr(Pic2Value);
    Das killt die Performache.
    Gib nur am Ende des Bildes aus, ob die Schraube drin war.
    Wenn Du echt 340x280=95200 mal eine Caption geändert hast in nur 5 Sekunden, dann chapeau an Deinen Rechner.



  • Hallo,

    int02h schrieb:

    Das Stichwort hierbei ist "ScanLine" der Bitmap...

    Ich wollte nun "ScanLine" verwenden und musste lesen, dass diese Funktion wohl nur bei einem TBitmap geht. Da ich den C++Builder2010 nutze habe ich diese Komponente nicht gefunden?!

    Und nu???



  • TBitmap ist eine Klasse, keine Komponente

    Graphics::TBitmap* tbmp = new Graphics::TBitmap();
    


  • ok, ich habe leider nur null Idee, wie ich nun ScanLine auf dieses Objekt anwenden kann 😕

    Schönen Gruß
    Torsten



  • Hallo

    TBitmap hat die Eigenschaft ScanLine, die wie ein Array von Zeilen funktioniert. Steht alles in der Builder-Hilfe.

    bis bald
    akari



  • Wenn deine Vorrichtung im großen Stil eingesetzt werden soll, dann würde ich beides nehmen. Die optische Auswertung und ein starkes Magnet. Wenn jemand eine Schraube oder Stück Glas abbekommt, dann bist du als Entwickler dran.



  • Hallo,
    da ich jetzt ein wenig mit TBitmap experimentiert habe, werde ich den generellen Ablauf ein wenig ändern. Zum jetzigen Vorgehen: Jetzt mache ich ein Bild mit der Cam, speichere es als .bmp auf der HD ab, vergleiche das vorherige mit dem neusten Bild und lasse mir den Unterschied des RGB-Wertes anzeigen. Da die Bilder der Cam ja erst auf der HD gespeichert werden und anschl. miteinander verglichen werden, dauert mir dieses Vorgehen zu lange.

    Der neue Ansatz währe wie folgt: Es wird das aktuelle Bild der Cam in einem TBitmap-Objekt gespeichert und der RGB-Wert dieses Bildes errechnet. Diesen Wert speichere ich in einer VAR. Nun nehme ich das nächste (aktuelle) Bild der Cam und errechne abermals den RGB-Wert. Anschließend vergleiche ich den Wert aus der VAR mit dem aktuellen RGB-Wert.

    Das sollte doch vom Ablauf her schneller gehen, oder?
    Gruß
    Torsten



  • Hallo

    Deine erste Variante ist vor allem deshalb so langsam, weil du auf Festplatte speicherst. Für die reine Berechnung ist das natürlich überflüssig. Hol die Bilder von der Kamera gleich in den Arbeitsspeicher ohne Umwege über die Festplatte.

    Deine zweite Variante zeigt, das du schon selber auf die Idee gekommen bist.

    bis bald
    akari



  • Ich hätte da einen ganz anderen vorschlag der auch auf eine andere Programmiersprache abziehlt.
    Man könnte einen Videostream einrichten und das video in Maximierter From über den Bildschirm sausen lassen quasie ein livebild. So Nun kommt ein einfach gestalteter Autohotkey script zum einsatz nun Scannen wir das Bild an Bestimmten Punkten (damit es schneller geht) nach einen Farbwert mit erhöter Variation ab und wenn etwas aus den rahmen fällt wird alarm in irgenteiner form gegeben von mir aus mit einer MessageBox
    hier mal ein beispiel für einen Bildpunkt
    (Der code ist eig einfach falls dennoch niemand in versteht einfach hier in den Tread reinschreiben)

    SetBatchLines 60    <-<-Das heist er soll 60Zeilen je Sekunde abarbeiten
    loop ,              <-<-Anfang einer unendlichen Schleife
    {
    PixelSearch , Px , Py , 100 , 100 , 100 , 100 , 0xFFFFFF , 20 , fast <-<-Pixelsearch , Egal , Egal , koo,rdi,nat,en, Farbe , Farbvariation , egal
    if Errorlevel  <-<- Wenn scann nicht weis ist
    {
    MsgBox , 0 , Fehler , Ein Fremdkörper ist im Bild , -1 <-<- Mache eine MessageBox	
    }
    }
    


  • genau das ist auch mein Lösungsansatz. Ich filme erst einmal das Bild des rieselnden Zuckers ohne Fremdkörper. Dieser Farbwert (RGB-Wert) wird quasi als Referezwert betrachtet. Man muss aber dann mit sicherheit auch einen gewissen "Rauschwert/Grenzwert" dazu rechnen.
    Wenn man dann also den Rieselzucker filmt, die RGB-Werte ständig ermittelt und mit dem Referenzwert vergleicht und dann eine Verunreinigung (zB Schraube) mit erfasst wird, ändert sich der RGB-Wert ja enorm. Und dann muss das Programm Alarm schlagen.

    Soweit der Plan. Ich werde jetzt erst einmal das ständige lesen, berechnen und vergleichen des Cam-Streams umsetzen....

    Gruß Torsten



  • Hallo,
    ich habe nun einen Weg über das Clipboard gefunden. Leider hakt es an einer Stelle. Und zwar komme ich nicht weiter beim lesen einer VAR vom Typ PByteArray.

    Hier mal mein Code:

    PByteArray z1;
    Graphics::TBitmap *bmp = new Graphics::TBitmap();
    Cap->CopyToClipBoard();
    bmp->LoadFromClipboardFormat(CF_BITMAP, Clipboard()->GetAsHandle(CF_BITMAP), 0);
    
    z1=(PByteArray)bmp->ScanLine [50];
    
    Label1->Caption = z1; //Hier der Fehler ?
    
    Clipboard()->Clear();
    delete bmp;
    

    Wie und womit kann ich denn auf den Wert von z1 zugreifen???

    Danke im vorraus



  • Programmierer, die das Clipboard zur Kompensation eigener Unzulänglichkeiten mißbrauchen, gehören geteert und gefedert.



  • torsten_156 schrieb:

    Wie und womit kann ich denn auf den Wert von z1 zugreifen???

    Dein z1 ist ein Zeiger auf ein Array von Triple-Bytes einer ganzen Pixelzeile (ScanLine) des Bitmap.

    PRGBTriple z1;
       z1  = (PRGBTriple)bmp->ScanLine[50];  // 51. Zeile/Reihe des bmp
       // Beispiel Auswertung eines Pixel dieser Line auf Farbwerte R, G, B
       int r =  z1[0].rgbtRed;   // 1. Pixel Rot-Wert
       int g =  z1[0].rgbtGreen;
       int b =  z1[0].rgbtBlue;
    

    Wenn du alle Pixel dieser einen Zeile auswerten willst(oder das kompletter bmp) nimmst du eine
    Schleife/n.

    audacia schrieb:

    Programmierer, die das Clipboard zur Kompensation eigener Unzulänglichkeiten mißbrauchen, gehören geteert und gefedert.

    😃

    Auf den Clipboardspeicher würde ich auch nicht zugreifen; ich denke mal, das ist fertiger Code aus dem
    Netz. 😉

    mfg
    kpeter



  • Wie kommt man denn auf einen RGB-Wert des Bildes? Jeder Pixel hat einen eigenen RGB-Wert. Ein normales 16mio Farben Foto hat effektiv im Schnitt 120.000 verschiedene Farben. Vielleicht solltest du ersteinmal ein Einzelbild des Zuckers analysieren. Es werden hunderte Farben sein, wenn man nur das Weiß des Zuckers betrachtet. Ich denke du brauchst einen gemittelten Wert der Farbe "Zucker" und einen gemittelten Wert der Farbe "Schraube". Dann brauchst du was womit du intelligent die Farbdistanzen der Farben ermittelst. Werden hierbei gewisse Schwellen überschritten, gibt es Alarm.

    Im Übrigen muss vielleicht so etwas wie ein Elektromagnet die Schraube in Echtzeit herausfiltern, sonst muss man die gesamte Produktion anhalten, was teuer wird etc.

    MfG



  • PRGBTriple z1;
       z1  = (PRGBTriple)bmp->ScanLine[50];  // 51. Zeile/Reihe des bmp
       // Beispiel Auswertung eines Pixel dieser Line auf Farbwerte R, G, B
       int r =  z1[0].rgbtRed;   // 1. Pixel Rot-Wert
       int g =  z1[0].rgbtGreen;
       int b =  z1[0].rgbtBlue;
    

    Vielen Dank dafür!

    audacia schrieb:

    ... ich denke mal, das ist fertiger Code aus dem Netz. 😉

    mfg
    kpeter

    Eben nicht! Das einzige, was ich aus dem Netz habe ist die Klasse und deren Funktionen, die die Ansteuerung der WebCam regeln. Diese Klasse bringt die Funktion mit, das Bild in's Clipboard zu kopieren. Um im ersten Schritt erst mal die einzelnen Werte dieses Bildes zu bekommen, reicht mir das völlig!
    Wenn dieser Schritt dann erledigt ist, werde ich mich anschl. darum kümmern, den Stream direkt auszulesen.

    Schönen Gruß
    Torsten



  • Das Ganze ist aber nur eine Übungsaufgabe o.ä., oder?
    Denn für einen produktiven Einsatz in der Lebensmittelindustrie, bei dem es potentiell um Gesundheitsschäden für Endverbraucher gehen kann, scheint mir das Ganze doch etwas (nicht abwertend gemeint!) unprofessionell.
    Hast du z.B. schon mal kalkuliert, wie schnell der Zucker maximal am Objektiv vorbeiströmen darf, damit du bei den gerade 30 Bildern/s einer Webcam ganz sicher nichts verpasst?



  • Hallo Jansen,

    ich kann Dich beruhigen. Es ist nicht für die Lebensmittelindustrie sondern für die Chemische Industrie 😉
    Hier handelt es sich nicht um eine Übungsaufgabe, sondern schon um die Vorbereitung für den produktiven Einsatz. Dabei geht es auch nicht um Zucker sondern um Verschuppte Harze.
    Wenn ich mit meiner Umsetzung der Lösung und anschl. Testen in einem Technikum vorran komme, sollte es für den produktiven Einsatz in der Fabrik auch nicht bei einer WebCam und Laptop bleiben. Ich möchte erst einmal prüfen, ob meine Idee in die Tat umzusetzen ist. Und wenn ja, wird das Ergebnis einigen hohen Herren vorgestellt und wenn's positiv angekommen ist, wird auch die entsprechende Hardware angeschafft [hoffe ich].

    Schönen Gruß
    Torsten



  • Hi,

    Dann hoffe ich, dass dieses Produkt transparent ist.
    Nach Murphys Gesetz rutscht an der der Kamera/Sichtfenster gegenüberliegenden Rohrwandung eine Schraube M10 Länge 200 mm durch. Wo auch immer die herkommt...



  • Gut zu wissen, dass ich auch weiterhin bedenkenlos Zucker kaufen kann. 🙂

    torsten_156 schrieb:

    [...]wenn's positiv angekommen ist, wird auch die entsprechende Hardware angeschafft [hoffe ich]

    Dann achte jetzt schon streng darauf, in deinem Programm Bedienoberfläche, Kameraansteuerung, Bildanalyse etc. logisch voneinander zu trennen, damit du später nur die relevanten Teile ändern musst. Ausserdem schadet es sicher nicht, sich vorab schonmal über passende Hardware und deren Besonderheiten zu informieren, um dein Programm generell daraufhin vorbereiten zu können.

    kpeter schrieb:

    [...] an der der Kamera/Sichtfenster gegenüberliegenden Rohrwandung [...]

    Man sollte doch hoffen, dass das Material für die Sichtprüfung über eine Art Rieselfläche läuft, oder?


Anmelden zum Antworten