Montag, Januar 27, 2020

Holen Sie Daten von der OpenGL-glReadPixels(mit Pyglet)

Ich bin mit Pyglet(und OpenGL) in Python auf eine Anwendung, die ich versuche zu verwenden, glReadPixels, um die RGBA-Werte für einen Satz von Pixeln. Es ist mein Verständnis, dass OpenGL die Daten zurück, die als gepackte zahlen, denn das ist, wie Sie auf der hardware gespeichert sind. Aber für offensichtliche Gründe, warum ich mag würde, um es in ein normales format für die Arbeit mit. Basierend auf einigen zu Lesen, ich habe es mit dieser: http://dpaste.com/99206/ , jedoch nicht mit einem IndexError. Wie würde ich gehen über das tun dies?

InformationsquelleAutor Alex Gaynor | 2008-12-15

5 Kommentare

  1. 4

    Müssen Sie zuerst ein array vom richtigen Typ sind, dann geben Sie auf glReadPixels:

    a = (GLuint * 1)(0)
    glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_INT, a)

    Um dies zu testen, legen Sie die folgenden in der Pyglet „opengl.py“ Beispiel:

    @window.event
    def on_mouse_press(x, y, button, modifiers):
        a = (GLuint * 1)(0)
        glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_INT, a)
        print a[0]

    Nun sehen Sie die Farbe code für den pixel unter dem Mauszeiger, wenn Sie klicken Sie irgendwo in der app-Fenster.

    • Dies ist ein hervorragendes Beispiel, aber ich hatte mehr Glück definieren a als GLubyte und mit GL_UNSIGNED_BYTE. Wenn Sie diejenigen, die ausgewählte Farbe wird wiederkommen, wie Werte von 0 bis 255, anstatt unverständlich longs.
  2. 1

    Können Sie mithilfe der PIL-Bibliothek, hier ist ein code-snippet, das ich verwenden, um zu erfassen, wie ein Bild:

        buffer = gl.glReadPixels(0, 0, width, height, gl.GL_RGB, 
                                 gl.GL_UNSIGNED_BYTE)
        image = Image.fromstring(mode="RGB", size=(width, height), 
                                 data=buffer)
        image = image.transpose(Image.FLIP_TOP_BOTTOM)

    Ich Schätze, einschließlich der alpha-Kanal sollte ziemlich geradlinig (wahrscheinlich nur den Austausch mit RGB -, RGBA, aber ich habe nicht versucht).

    Edit: ich war nicht bewusst, dass die pyglet OpenGL-API unterscheidet sich von der PyOpenGL ein. Ich denke, man muss, ändern Sie den obigen code verwenden, den Puffer als das siebte argument (entsprechend der weniger pythonic pyglet-Stil).

    • Wenn ich das bekomme ich eine Art Fehlermeldung, dass glReadPixels dauert 7 Argumente, nicht 6.
    • Sind Sie sicher? Ich habe mit diesem code auf verschiedenen Maschinen mit verschiedenen PyOpenGL-Versionen. Vielleicht ist es etwas pyglet spezifischen? Vielleicht passieren die buffer-variable als das siebte argument.
  3. 1

    War ich in der Lage, um den gesamten frame-Puffer mit glReadPixels(...), dann verwendet die PIL zu schreiben, aus einer Datei:

    # Capture image from the OpenGL buffer
    buffer = ( GLubyte * (3*window.width*window.height) )(0)
    glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, buffer)
    
    # Use PIL to convert raw RGB buffer and flip the right way up
    image = Image.fromstring(mode="RGB", size=(window.width, window.height), data=buffer)     
    image = image.transpose(Image.FLIP_TOP_BOTTOM)
    
    # Save image to disk
    image.save('jpap.png')

    War ich nicht interessiert in der alpha, aber ich bin sicher, Sie könnte leicht fügen Sie es in.

    War ich gezwungen zu verwenden glReadPixels(...) statt der Pyglet-code

    pyglet.image.get_buffer_manager().get_color_buffer().save('jpap.png')

    da die Ausgabe mit save(...) war nicht identisch mit dem, was ich sah in das Fenster. (Multisampling-buffer verpasst?)

  4. 0

    Wenn Sie Lesen das snippet, das Sie verlinken, Sie können verstehen, dass die einfachste und die Art und Weise, um die „normalen“ Werte ist nur der Zugriff auf das array in der richtigen Reihenfolge.

    Das snippet sieht aus wie es soll, die Arbeit zu tun. Wenn es nicht, zu Debuggen und zu sehen was das problem ist.

    • Gut, die Daten, die glReadPixels gibt, ist nur ein array mit n Werten, wobei n die Anzahl der Pixel in der region. Ich bin eigentlich nicht sicher, dass das snippet macht keinen Sinn, es ist mehr oder weniger ein Zusammenschluss von Sachen, die ich gelesen habe.
  5. 0

    Auf weitere rezension glaube ich, dass mein original-code basiert auf C-spezifischen code, der funktioniert, weil das array nur ein pointer, also meine mit Zeiger-Arithmetik konnte man an bestimmten bytes, die offensichtlich nicht zu übersetzen, um Python. Hat jemand gewusst wie: extrahieren von Daten mit einer anderen Methode(ich nehme an, es ist nur eine Frage der bit-Verschiebung der Daten).

Kostenlose Online-Tests