In Echtzeit Position von Pixeln mit bestimmten Farbwert auslesen

  • Hallo zusammen,
    ich würde gerne eure Meinung wissen.


    Was die Anwendung können soll
    ich möchte gerne die X- und Y-Postion von Pixeln mit einem bestimmten Farbwert ermitteln.
    Diese Positionsdaten möchte ich dann im Lan an einen Rechner übermitteln.


    Python
    Nach einem anfänglichen Test mit Python habe ich schnell gemerkt das Python zu langsam ist.


    C++ OpenCV
    Dann bin ich zu C++ gewechselt. Mit C++ und openCV habe ich die Werte ermittelt.
    Bis jetzt habe ich mit Bildern getestet. Ich habe die Zeit gestoppt und auch hier gemerkt das
    die Geschwindigkeit zu langsam ist. (ca 15 FPS) Und die CPU ist ziemlich ausgelastet.


    Ziel
    Mein Ziel ist es die Werte mit 60-90 FPS direkt live vom Pi Camera Modul auszulesen.
    30 FPS wären auch in Ordnung.


    Auslastung bei Video Aufzeichnung
    Mir ist aufgefallen das wenn ich den Befehl
    raspivid -o (der pfad) -w 960 -h 720 -fps 60
    mit der Konsole starte mir das Bild live angezeigt wird und die CPU nicht wirklich ausgelastet wird.


    Überlegung
    Daher glaube ich das es grundsätzlich möglich sein sollte. Ich will ja nichts im Bild verändern.


    Fragen an euch
    Habt ihr Vorschläge für mich wie ich da am besten ran gehen kann?


    Sollte ich weiter auf c++ und OpenCV setzen?


    Benötige ich für so eine einfache Auswertung überhaupt OpenCV?


    Sollte ich mich auf die Suche nach der Anwendung machen die die Preview erzeugt und diese für meine Zwecke anpassen? Ich hoffe die Anwendung ist Open Source und nicht zu kompliziert.


    Sollte ich direkt bei den Treibern ansetzen? Ich hoffe das die Open Source sind.
    Ich denke das würde richtig kompliziert.


    Oder habe Ihr einen ganz anderen Vorschlag?


    Danke schon mal Berry

    Edited once, last by berrie ().

  • Schönen Vormittag!


    Hast du schon etwas in Erfahrung bringen können ob das möglich ist?
    Ich arbeite gerade an einem ähnlichem Projekt, nur das ich gerne die Position eines Laserstrahles auf einer Oberfläche ermitteln möchte!

  • Hallo Berrie,


    meines Erachtens kannst Du die Aufgabe nur erreichen, indem Du über alle Pixel in horizontaler und über alle Pixel in vertikaler Richtung den Farbcode ausliest.


    Die FPS-Rate hängt von der Auflösung der Bilder ab.


    Ich kann mir aber nicht vorstellen, dass durch andere Sprachen als Assembler zu akzeptablen Verarbeitungsgeschwindigkeiten kommst - wenn Du die Pixel im angezeigten Bild interpretieren möchtest.


    Ich denke, dass man hier wahrscheinlich auch direkt in die Bilddatei gehen müsste und dort die Farben decodieren müsste, um auf akzeptable Geschwindigkeiten zu kommen.


    Fragen:
    1. Wie gross sind die Bilder?
    2. Kommt es Dir auf den exakten Farbcode an oder bist Du an Farbbereichen /- toleanzen interessiert?


    Beste Grüsse


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Edited once, last by Andreas ().

  • Hallo Andreas,
    vielen Dank für die Antwort.
    Das Auslesen wie Du es beschrieben hast mache ich gerade.
    Ich denke anders kann es auch nicht gehen.
    Ich suche nach Pixeln die sehr hell sind. Maximal hellgrau.
    Das Bild kann also auch schwarzweiß sein und ich muss nur einen Kanal beobachten.


    Was mir aufgefallen ist das die CPU bei einer Aufnahme nicht ausgelastet ist.
    Wenn ich aber ein Bild oder Video nach den Pixeln durchsuche (ohne es anzuzeigen) geht die CPU auf 100%.
    Bei Aufnahmen wird das Bild in der Preview angezeigt. Wie schnell die Preview ist kann ich natürlich nicht sagen. Das bedeutet aber auch das für die Anzeige der Farbwert irgendwo ausgelesen wird. Wenn ich also diese Stelle finde dann könnte ich den Code für mich anpassen.


    Ich habe auch schon überlegt das die geringe Auslastung daran liegen kann das die Capture Aufgabe von der Grafikkarte übernommen wird. Wenn die das schneller kann sollte überlegen wie ich das nutzen kann.


    Was die Größe der Bilder angeht.
    So groß wie möglich und so schnell wie möglich.
    Traumhaft wäre eine Größe von 960x720 bei 60 fps oder 960x720 bei 90 fps.


    Ach ja ich möchte die Ergebnisse per TCP IP an einen anderen PC senden.
    Dieser analysiert dann die Daten. Das Raspberry ist nur der Sensor.
    Die Info das das Raspberry ohne grafische Oberfläche laufen kann ist vielleicht auch wichtig.


    Grüße Berrie

  • Hallo dreamshader,
    den Beitrag hatte ich vor einigen Wochen auch gefunden.
    Wenn ich mich richtig erinnere hatte er auch ein Problem mit der Geschwindigkeit.
    Ich werde mir den Beitrag nochmal genauer ansehen.
    Vielen Dank, Grüße Berrie

  • Bitte ... ich wusste doch, dass da was war, was scheinbar einigermassen funktionierte.
    Vielleicht bringt es was, opencv gegen graphicsMagick auszutauschen??
    Ansonsten hast Du schon recht ... die GPU spielt bei den Videos sicher eine grosse Rolle.
    Das war - Mali oder so :s ... - und da gab's auch mal den Ansatz, sie zugreifbar zumachen ... funktionierte afaik nur nicht so recht. Aber das ist schon wieder so lange her ... da ist die Erinnerung schon wieder hinwegdiffundiert :) ... weil's mir damals auch nicht so wichtig war.


    cheers und viel Erfolg,
    wär schön, wenn Du Dich mal zwischendrin melden würdest, wie Du da weiterkommst,
    -ds-


  • Was mir aufgefallen ist das die CPU bei einer Aufnahme nicht ausgelastet ist.
    Wenn ich aber ein Bild oder Video nach den Pixeln durchsuche (ohne es anzuzeigen) geht die CPU auf 100%.


    Die RaspiCam ist direkt mit der GPU verbunden, wohingegen dein Programm von der CPU ausgeführt wird.


    Guck dir mal den Sourcecode von raspivid an, vielleicht bringt dich das weiter ;)

  • Hi Berrie,


    nö ... ich hab' das weder gekannt noch ausprobiert. Wobei das mit dem ausprobieren ... weia :s ... da hab' ich so schnell wohl keine Gelegenheit dazu.
    Klingt aber interessant ... behalt' ich auf alle Fälle im Hinterkopf ( hab' schon mal nen Merker drauf gesetzt).
    Danke jedenfalls für die Info ... ich würd's an Deiner Stelle mal probieren.


    bye,
    -ds-

  • Ich habe heute
    GPU Accelerated Camera Processing On The Raspberry Pi
    installiert und ausprobiert.
    Das Demo Programm läuft. Ich habe mir alle Dateien angesehen. Leider konnte ich keine Schleife finden. Ich werde aber auf jeden Fall noch mal genaue suchen. Es gibt ja noch das ausführlich Programm. Ich bin gespannt.


    Anderer Ansatz
    Ich habe ein Demo Video mit dem Raspberry Kamera Modul aufgezeichnet.
    Das Programm das die Pixel auswertet habe ich auf meinem Laptop laufen lassen. Das Video wird mit bis zu 300 fps gescannt. Bei 720 p sind es noch 140 fps.
    Ach ja, es ist ein i7 quad core Laptop.
    OS Linux Mint in einer virtuellen Maschine.


    Ich habe hier einen Betrag mit dem Titel Verzögerungs freies Streamen (lowest streaming latency) gesehen. Vielleicht ist das ja auch eine Möglichkeit. Es muss aber verzögerungsfrei sein. Die Frage ist nur ob die Bitrate ausreicht. Ich benötige nur Grayscale. 32-64 Grauwerte sollten ausreichen.


    Grüße Berrie

  • Hi berrie,


    ...
    Ich habe hier einen Betrag mit dem Titel Verzögerungs freies Streamen (lowest streaming latency) gesehen. ...
    ...


    ok ... klingt ja ganz vielversprechend :) ...


    Das mit dem Streamen kann ich nicht beurteilen ... lediglich das mit netcat (-> click <-) hab' ich ausprobiert.


    cu und viel Erfolg weiterhin,
    -ds-

  • Kleiner Nachtrag.
    Ich habe den folgenden Code noch nicht ans laufen bekommen.
    http://www.cheerfulprogrammer.…ds/picamgpu/picam_gpu.zip
    Wenn ich das aber richtig sehe werden hauptsächlich GSLG genuzt.
    Ich habe dann mal in der OpenGL Shading Language nachgesehen.
    Es gibt dort eine kurze Info zum Thema Pixel. Siehe weiter Unten.
    OpenGL Shading Language ist so wie ich das verstehe eine eigene Sprache.
    Jetzt stelle ich mir die nächst Frage. Komme ich mit C++ an die Pixel Koordinaten?
    Was meint ihr dazu?
    Kennt sich jemand hier damit ein wenig aus?


    Gruß Berrie

    Reading and Copying Pixels
    Reading Pixels [18.2]
    void ReadPixels(int x, int y, sizei width,
    sizei height, enum format, enum type,
    void *data);
    format: STENCIL_INDEX, RED, GREEN, BLUE, RG, RGB,
    RGBA, BGR, DEPTH_{COMPONENT, STENCIL},
    {RED, GREEN, BLUE, RG, RGB}_INTEGER,
    {RGBA, BGR, BGRA}_INTEGER, BGRA [Table 8.3]
    type: [HALF_]FLOAT, [UNSIGNED_]BYTE,
    [UNSIGNED_]SHORT, [UNSIGNED_]INT,
    FLOAT_32_UNSIGNED_INT_24_8_REV,
    UNSIGNED_{BYTE, SHORT, INT}_* values in
    [Table 8.2]


    void ReadBuffer(enum src);
    src: NONE, {FRONT, BACK}_{LEFT, RIGHT}, FRONT,
    BACK, LEFT, RIGHT, FRONT_AND_BACK,
    COLOR_ATTACHMENTi (i =
    [0, MAX_COLOR_ATTACHMENTS - 1 ])


    Final Conversion [18.2.6]
    void ClampColor(enum target, enum clamp);
    target: CLAMP_READ_COLOR
    clamp: TRUE, FALSE, FIXED_ONLY


    Copying Pixels [18.3]
    void BlitFramebuffer(int srcX0, int srcY0,
    int srcX1, int srcY1, int dstX0, int dstY0,
    int dstX1, int dstY1, bitfield mask,
    enum filter);
    mask: Bitwise OR of
    {COLOR, DEPTH, STENCIL}_BUFFER_BIT or 0
    filter: LINEAR, NEAREST


    void CopyImageSubData(uint srcName,
    enum srcTarget, int srcLevel, int srcX,
    int srcY, int srcZ, uint dstName,
    enum dstTarget, int dstLevel, int dstX,
    int dstY, int dstZ, sizei srcWidth,
    sizei srcHeight, sizei srcDepth);
    srcTarget, dstTarget: see target for BindTexture in
    section [8.1] on this card, plus GL_RENDERTARGET