VTK und GST mit Python

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
passe.partout
User
Beiträge: 11
Registriert: Donnerstag 9. September 2010, 10:33

Hallo,

ich versuche ein Video (mit der webcam über gstreamer weitergereicht) mit vtk darzustellen. Am liebsten hätte ich, dass das Video im Hintergrund abgespielt wird und ich darüber dann irgendwelche VTK-Modelle darüber lege (aka ARToolKit). Zurzeit male ich mit sehr wenig erfolg auf einer Leinwand.

Der Videopuffer ist vom Typ gstBuffer, dass heißt, mit gstBuffer.data bekomme ich einen string. Ich schaffe es aber leider nicht diesen string-puffer irgendwie in vtk zu nutzen, mit dem sequentiellen kopieren (sie updateCamera) ist auch nicht wirklich schön. Lieber wäre es mir, wenn man alles direkt umlegen, dass heißt, ohne zu kopieren, machen könnte...

Anbei ein kleines Minimalbeispiel, dass immer wieder updateCamera aufruft, wenn neue Videodaten zur Verfügung stehen und diese dann auf die Canvas malt (nicht erfolgreich)...

Code: Alles auswählen

import vtk
import pygst
pygst.require("0.10")
import gst


# ist nicht wirklich schön und funktioniert auch nicht, naja, irgendwas wackelt und er kackt nicht ab
def updateCamera(fakesink, buffer, pad):
    global canvasSource
    
    c=0
    
    for x in range(320):
        for y in range(240):
            color = buffer[c:c+3]
            c += 3
            canvasSource.SetDrawColor( ord(color[0]), ord(color[1]), ord(color[2]))
            canvasSource.DrawPoint(x, y)
    
    canvasSource.Update()

conf = "v4l2src device=/dev/video0 ! video/x-raw-rgb,width=320,height=240 ! videorate ! video/x-raw-rgb,framerate=25/2 ! videoscale ! video/x-raw-rgb,width=320,height=240 ! ffmpegcolorspace ! identity name=callback ! fakesink "
player = gst.parse_launch(conf)
player.set_state(gst.STATE_PLAYING)
    
stream = gst.Bin.get_by_name(player, "callback")
stream.props.signal_handoffs = True
stream.connect("handoff", updateCamera, "")

canvasSource = vtk.vtkImageCanvasSource2D();
canvasSource.SetExtent(0, 320, 0, 240, 0, 1);
canvasSource.SetScalarTypeToChar();
canvasSource.SetNumberOfScalarComponents(3);
canvasSource.Update();
cam = canvasSource.GetOutput();

actCam = vtk.vtkImageActor()
actCam.SetInput(cam)

renderer= vtk.vtkRenderer()
renderer.AddActor( actCam );
    
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer( renderer )
renderWindow.SetSize( 600, 600 )

iren = vtk.vtkRenderWindowInteractor();
iren.SetRenderWindow(renderWindow);

style = vtk.vtkInteractorStyleTrackballCamera();
iren.SetInteractorStyle(style);

iren.Initialize();
iren.Start();

player.set_state(gst.STATE_NULL)
passe.partout
User
Beiträge: 11
Registriert: Donnerstag 9. September 2010, 10:33

Na gut, habe es schon dahingehend hinbekommen, dass das Videobild richtig angezeigt wird. Mein Problem ist jetzt (außer dem Segmentation fault, der ab und zu mal auftritt), dass das Kamerabild nur geupdated wird, wenn ich mit der Maus ins Fenster klicke, oder sonst was mache, das ein Event auslöst... Wie Kann ich VTK sagen, dass das Bild neu gerendert werden soll, wenn neue Kameradaten bereitliegen???

Code: Alles auswählen

import vtk
import pygst
pygst.require("0.10")
import gst

import string, random

def updateCamera(fakesink, buffer, pad):
    global cameraImage    
    cameraImage.CopyImportVoidPointer(buffer.data, len(buffer.data))    
    
conf = "v4l2src device=/dev/video0 ! video/x-raw-rgb,width=320,height=240 ! videorate ! video/x-raw-rgb,framerate=25/2 ! videoscale ! video/x-raw-rgb,width=320,height=240 ! ffmpegcolorspace ! identity name=webcam ! fakesink "
player = gst.parse_launch(conf)
player.set_state(gst.STATE_PLAYING)
    
stream = gst.Bin.get_by_name(player, "webcam")
stream.props.signal_handoffs = True
stream.connect("handoff", updateCamera, "")

cameraImage = vtk.vtkImageImport()
cameraImage.SetDataScalarTypeToUnsignedChar()
cameraImage.SetNumberOfScalarComponents(3)
cameraImage.SetDataExtent(0,320-1,0,240-1,0,0)
cameraImage.SetWholeExtent(0,320-1,0,240-1,0,0)

randomBuffer = string.join ([random.choice(string.letters) for i in range((320*240*3+1)/2) ])
cameraImage.CopyImportVoidPointer(randomBuffer, len(randomBuffer)-1)

actCam = vtk.vtkImageActor()
actCam.SetInput(cameraImage.GetOutput())

renderer= vtk.vtkRenderer()
renderer.SetBackground( 0.6, 0.6, 0.8 )
renderer.AddActor( actCam );

renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer( renderer )
renderWindow.SetSize( 600, 600 )

iren = vtk.vtkRenderWindowInteractor();
iren.SetRenderWindow(renderWindow);

style = vtk.vtkInteractorStyleTrackballCamera();
iren.SetInteractorStyle(style);

iren.Initialize();
iren.Start();

player.set_state(gst.STATE_NULL)
Antworten