2009-10-16 13 views
5

Ich habe folgendes PyObjC Skript:Wie kann ich iSight Frames mit Python in Snow Leopard erfassen?

from Foundation import NSObject 
import QTKit 
error = None 
capture_session = QTKit.QTCaptureSession.alloc().init() 
print 'capture_session', capture_session 
device = QTKit.QTCaptureDevice.defaultInputDeviceWithMediaType_(QTKit.QTMediaTypeVideo) 
print 'device', device, type(device) 
success = device.open_(error) 
print 'device open success', success, error 
if not success: 
    raise Exception(error) 
capture_device_input = QTKit.QTCaptureDeviceInput.alloc().initWithDevice_(device) 
print 'capture_device_input', capture_device_input, capture_device_input.device() 
success = capture_session.addInput_error_(capture_device_input, error) 
print 'session add input success', success, error 
if not success: 
    raise Exception(error) 
capture_decompressed_video_output = QTKit.QTCaptureDecompressedVideoOutput.alloc().init() 
print 'capture_decompressed_video_output', capture_decompressed_video_output 
class Delegate(NSObject): 
    def captureOutput_didOutputVideoFrame_withSampleBuffer_fromConnection_(self, captureOutput, videoFrame, sampleBuffer, connection): 
     print videoFrame, sampleBuffer, connection 
delegate = Delegate.alloc().init() 
print 'delegate', delegate 
capture_decompressed_video_output.setDelegate_(delegate) 
print 'output delegate:', capture_decompressed_video_output.delegate() 
success = capture_session.addOutput_error_(capture_decompressed_video_output, error) 
print 'capture session add output success', success, error 
if not success: 
    raise Exception(error) 
print 'about to run session', capture_session, 'with inputs', capture_session.inputs(), 'and outputs', capture_session.outputs() 
capture_session.startRunning() 
print 'capture session is running?', capture_session.isRunning() 
import time 
time.sleep(10) 

meldet das Programm keine Fehler, aber iSight grüne Licht wird nie aktiviert und die Frame Capture Rückruf des Delegierten nie aufgerufen. Hier ist die Ausgabe erhalte ich:

$ python prueba.py 
capture_session <QTCaptureSession: 0x1006c16f0> 
device Built-in iSight <objective-c class QTCaptureDALDevice at 0x7fff70366aa8> 
device open success (True, None) None 
capture_device_input <QTCaptureDeviceInput: 0x1002ae010> Built-in iSight 
session add input success (True, None) None 
capture_decompressed_video_output <QTCaptureDecompressedVideoOutput: 0x104239f10> 
delegate <Delegate: 0x10423af50> 
output delegate: <Delegate: 0x10423af50> 
capture session add output success (True, None) None 
about to run session <QTCaptureSession: 0x1006c16f0> with inputs (
    "<QTCaptureDeviceInput: 0x1002ae010>" 
) and outputs (
    "<QTCaptureDecompressedVideoOutput: 0x104239f10>" 
) 
capture session is running? True 

PS: Bitte antworten Sie nicht, dass ich sollte PySight versuchen, ich habe, aber es wird nicht funktionieren, weil Xcode nicht CocoaSequenceGrabber in 64bit kompilieren.

Antwort

3

Ihr Problem hier ist, dass Sie keine Ereignisschleife haben. Wenn Sie dies als eigenständiges Skript ausführen möchten, müssen Sie herausfinden, wie Sie ein Skript erstellen. Die PyObjC XCode-Vorlagen automatisch, dass für Sie eingerichtet mit:

from PyObjCTools import AppHelper 
AppHelper.runEventLoop() 

Der Versuch, dass am Anfang des Skripts einfügen, zeigt jedoch, dass sich etwas in AppHelper (wahrscheinlich NSApplicationMain) erwartet eine plist-Datei die Hauptklasse zu extrahieren von. Sie können das erhalten, indem eine setup.py Datei Erstellen und Verwenden von py2app, so etwas wie dieses Beispiel aus einem PyObjc talk:

from distutils.core import setup 
import py2app 
plist = dict(
    NSPrincipalClass='SillyBalls', 
) 
setup(
    plugin=['SillyBalls.py'], 
    data_files=['English.lproj'], 
    options=dict(py2app=dict(
     extension='.saver', 
     plist=plist, 
    )), 
) 
+1

@ Dan: Danke für den Zeiger! Es ist meine erste Erfahrung mit Mac OS X-Programmierung und ich war absolut ahnungslos. Ich habe es geschafft, 'AppHelper.runConsoleEventLoop()' stattdessen am Ende des Skripts aufzurufen, ohne 'Plist' zu benötigen. Jetzt ist mein Problem, dass es den Hauptthread übernimmt und nie zurückkehrt. Ich hatte gehofft, es schön in ein Modul auf nicht-intrusive Art und Weise zu verpacken. –

+0

Sie könnten wahrscheinlich einen Thread spawnen und damit innerhalb des Threads umgehen. QT ist nicht threadsicher, aber in diesem Kontext bedeutet es nur, dass Sie alle Ihre QT-Sachen in einem Thread machen müssen, was nicht unbedingt der Hauptthread ist. Sie könnten auch nach Timern suchen, aber ich denke, Sie brauchen wahrscheinlich noch eine Hauptschleife dafür. – Dan

+0

Anscheinend muss es der Hauptfaden sein. Wenn ich 'Thread (target = appHelper.runConsoleEventLoop) .start()' stattdessen mache, bekomme ich eine Reihe von Fehlern und nichts funktioniert: '2009-10-20 12: 58: 32.075 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Objekt 0x1018065b0 der Klasse NSCFString automatisch freigegeben ohne Pool an der richtigen Stelle - nur undicht 2009-10-20 12: 58: 32.078 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Objekt 0x101821130 der Klasse NSCFString Autoreleased mit Nein Pool an Ort und Stelle - nur undicht 2009-10-20 12: 58: 32.078 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Objekt 0x101828df0 der Klasse NSCFString Autorelease' –

2

Sie sollten einen Versuch zu motmot's camiface Bibliothek von Andrew Straw geben. Es funktioniert auch mit FireWire-Kameras, aber es funktioniert auch mit der Isight, die Sie suchen.

aus dem Tutorial:

import motmot.cam_iface.cam_iface_ctypes as cam_iface 
import numpy as np 

mode_num = 0 
device_num = 0 
num_buffers = 32 

cam = cam_iface.Camera(device_num,num_buffers,mode_num) 
cam.start_camera() 
frame = np.asarray(cam.grab_next_frame_blocking()) 
print 'grabbed frame with shape %s'%(frame.shape,) 
+0

cool! Danke für den Link –

+0

Sie können einige einfache Beispiele auf http://www.incm.cnrs-mrs.fr/LaurentPerrinet/SimpleCellDemo sehen – meduz

+0

Dies ist die ursprüngliche Bibliothek: https://github.com/motmot/libcamiface – dashesy