2009-10-16 18 views
5

Mam następujący PyObjC skrypt:Jak mogę przechwytywać ramki iSight w Pythonie w systemie Snow Leopard?

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) 

raportach programu bez błędów, ale iSight za zielone światło nigdy nie jest aktywna i przechwytywania rama zwrotna, której przekazano nigdy nie jest wywoływana. Oto wynik uzyskać:

$ 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: Proszę nie odpowiedzieć powinienem spróbować PySight mam, ale to nie będzie działać, ponieważ Xcode nie można skompilować CocoaSequenceGrabber w 64bit.

Odpowiedz

3

Twój problem polega na tym, że nie masz pętli zdarzeń. Jeśli chcesz zrobić to jako samodzielny skrypt, musisz dowiedzieć się, jak go utworzyć. PyObjC XCode szablony automatycznie ustawić, że się do ciebie z:

from PyObjCTools import AppHelper 
AppHelper.runEventLoop() 

Próbuje wstawić, że w górnej części skryptu, pokazuje jednak, że coś wewnątrz AppHelper (prawdopodobnie NSApplicationMain) spodziewa się, że plik plist wyodrębnić główne klasy od. Można dostać że tworząc plik setup.py i korzystania py2app, coś w tym przykładzie z 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: Dzięki za wskazówki! To moje pierwsze doświadczenie z programowaniem w Mac OS X i byłem absolutnie nieświadomy. Dostałem go do pracy wywołując 'AppHelper.runConsoleEventLoop()' zamiast na końcu skryptu, bez potrzeby 'Plist'. Teraz mój problem polega na tym, że przejmuje główny wątek i nigdy nie wraca. Miałem nadzieję, że ładnie go otoczyłem w module w sposób nieinwazyjny. –

+0

Można odrodzić się z wątku i prawdopodobnie obsługiwać go w wątku. QT nie jest threadafe, ale w tym kontekście wszystko to oznacza, że ​​musisz wykonać wszystkie twoje QT stuff w jednym wątku, który niekoniecznie jest głównym wątkiem. Możesz również spojrzeć na timery, ale myślę, że prawdopodobnie nadal potrzebujesz głównej pętli. – Dan

+0

Podobno musi to być główny wątek. Jeśli zrobię zamiast tego 'Thread (app = AppHelper.runConsoleEventLoop) .start()', otrzymuję masę błędów i nic nie działa: '2009-10-20 12: 58: 32.075 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Obiekt 0x1018065b0 klasy NSCFString autoreleased bez puli na miejscu - po prostu wycieknie 2009-10-20 12: 58: 32.078 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Obiekt 0x101821130 klasy NSCFString autoreleased bez basen na miejscu - po prostu wycieknie 2009-10-20 12: 58: 32.078 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Obiekt 0x101828df0 klasy NSCFString autorelease' –

2

Należy dać spróbować motmot's camiface bibliotekę z Andrew słomy. Współpracuje również z kamerami FireWire, ale działa również z wglądem, którego właśnie szukasz.

z samouczka:

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

fajny! dzięki za link –

+0

można zobaczyć kilka prostych przykładów na http://www.incm.cnrs-mrs.fr/LaurentPerrinet/SimpleCellDemo – meduz

+0

to jest oryginalna biblioteka: https://github.com/motmot/libcamiface – dashesy