Próbuję uchwycić pojedynczą klatkę z kamery iSight wbudowanej w Jabłko MacBook Pro przy użyciu Python (wersja 2.7 lub 2.6) i PyObjC (wersja 2.2).Jak przechwytywać ramki z Apple iSight za pomocą Python i PyObjC?
Jako punkt wyjścia, użyłem this old StackOverflow pytanie. Aby sprawdzić, czy ma to sens, odwołałem się do przykładu Apple's MyRecorder, który wydaje się być oparty na. Niestety mój skrypt nie działa.
Moje wielkie pytania:
- Am I inicjalizacji aparat poprawnie?
- Czy poprawnie uruchamiam pętlę zdarzeń?
- Czy istnieje jakakolwiek inna konfiguracja miałem zrobić?
W poniższym skrypcie przykładowym zamierzona operacja polega na tym, że po wywołaniu funkcji startImageCapture() powinienem rozpocząć drukowanie wiadomości "Mam ramkę ..." z CaptureDelegate. Jednak lampka aparatu nigdy się nie włącza, a wywołanie zwrotne uczestnika nie jest nigdy wykonywane.
Ponadto, nie ma żadnych uszkodzeń podczas startImageCapture(), wszystkie funkcje twierdzą, że się uda, i to z powodzeniem wyszukuje urządzenie iSight. Analizowanie obiektu sesji w pdb pokazuje, że ma on poprawne obiekty wejściowe i wyjściowe, dane wyjściowe mają przypisanego delegata, urządzenie nie jest używane przez inne procesy, a sesja jest oznaczana jako działająca po wywołaniu funkcji startRunning().
Oto kod:
#!/usr/bin/env python2.7
import sys
import os
import time
import objc
import QTKit
import AppKit
from Foundation import NSObject
from Foundation import NSTimer
from PyObjCTools import AppHelper
objc.setVerbose(True)
class CaptureDelegate(NSObject):
def captureOutput_didOutputVideoFrame_withSampleBuffer_fromConnection_(self, captureOutput,
videoFrame, sampleBuffer,
connection):
# This should get called for every captured frame
print "Got a frame: %s" % videoFrame
class QuitClass(NSObject):
def quitMainLoop_(self, aTimer):
# Just stop the main loop.
print "Quitting main loop."
AppHelper.stopEventLoop()
def startImageCapture():
error = None
# Create a QT Capture session
session = QTKit.QTCaptureSession.alloc().init()
# Find iSight device and open it
dev = QTKit.QTCaptureDevice.defaultInputDeviceWithMediaType_(QTKit.QTMediaTypeVideo)
print "Device: %s" % dev
if not dev.open_(error):
print "Couldn't open capture device."
return
# Create an input instance with the device we found and add to session
input = QTKit.QTCaptureDeviceInput.alloc().initWithDevice_(dev)
if not session.addInput_error_(input, error):
print "Couldn't add input device."
return
# Create an output instance with a delegate for callbacks and add to session
output = QTKit.QTCaptureDecompressedVideoOutput.alloc().init()
delegate = CaptureDelegate.alloc().init()
output.setDelegate_(delegate)
if not session.addOutput_error_(output, error):
print "Failed to add output delegate."
return
# Start the capture
print "Initiating capture..."
session.startRunning()
def main():
# Open camera and start capturing frames
startImageCapture()
# Setup a timer to quit in 10 seconds (hack for now)
quitInst = QuitClass.alloc().init()
NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(10.0,
quitInst,
'quitMainLoop:',
None,
False)
# Start Cocoa's main event loop
AppHelper.runConsoleEventLoop(installInterrupt=True)
print "After event loop"
if __name__ == "__main__":
main()
Dzięki za wszelką pomoc można zapewnić!
Cool man, btw należy oznaczyć własną akceptację jako "accept" :) –
Ten skrypt działa świetnie, ale kończy się niepowodzeniem podczas zapisywania pliku bajtowego. Powinieneś zmienić otwarty ("filename", "w"), aby otworzyć ("filename", "wb"), aby otworzyć plik w trybie bajtowym, to działa. – andli