2009-10-16 10 views
5

Tôi có kịch bản PyObjC sau:Làm cách nào để chụp khung iSight bằng Python trong 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) 

Báo cáo chương trình không có lỗi, nhưng ánh sáng màu xanh lá cây iSight của không bao giờ được kích hoạt và gọi lại chụp khung của đại biểu không bao giờ được gọi. Đây là đầu ra tôi nhận được:

$ 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: Xin đừng trả lời Tôi nên thử PySight, tôi có nhưng nó sẽ không hoạt động vì Xcode không thể biên dịch CocoaSequenceGrabber trong 64bit.

Trả lời

3

Vấn đề của bạn ở đây là bạn không có vòng lặp sự kiện. Nếu bạn muốn làm điều này như là một kịch bản độc lập, bạn sẽ phải tìm ra cách tạo một kịch bản. Các PyObjC XCode bản mẫu tự động thiết lập khả năng cho bạn với:

from PyObjCTools import AppHelper 
AppHelper.runEventLoop() 

Đang cố gắng để chèn rằng ở phía trên cùng của kịch bản của bạn, tuy nhiên, cho thấy một cái gì đó bên trong AppHelper (có lẽ NSApplicationMain) hy vọng một file plist để trích xuất các lớp học chính từ. Bạn có thể nhận được rằng bằng cách tạo ra một tập tin setup.py và sử dụng py2app, một cái gì đó giống như ví dụ này từ một 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: Cảm ơn con trỏ! Đó là trải nghiệm đầu tiên của tôi với lập trình Mac OS X và tôi hoàn toàn không biết gì. Tôi đã nhận nó để làm việc gọi 'AppHelper.runConsoleEventLoop()' thay vì ở cuối kịch bản, không cần cho 'Plist'. Bây giờ vấn đề của tôi là nó chiếm toàn bộ luồng chính và không bao giờ trả về. Tôi đã hy vọng để bọc nó độc đáo trong một mô-đun một cách không xâm nhập. –

+0

Bạn có thể sinh ra một sợi và xử lý nó trong chuỗi, có thể. QT không phải là luồng an toàn, nhưng trong bối cảnh này tất cả điều đó có nghĩa là bạn phải làm tất cả các công cụ QT của bạn trong một luồng, mà không nhất thiết phải là chủ đề chính. Bạn cũng có thể nhìn vào bộ đếm thời gian, nhưng tôi nghĩ bạn có lẽ vẫn cần một vòng lặp chính cho điều đó. – Dan

+0

Rõ ràng, nó phải là chủ đề chính. Nếu tôi làm 'Thread (target = AppHelper.runConsoleEventLoop) .start()' thay vào đó, tôi nhận được một loạt các lỗi và không có gì hoạt động: '2009-10-20 12: 58: 32.075 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Đối tượng 0x1018065b0 của lớp NSCFString tự động chạy mà không có hồ bơi tại chỗ - chỉ rò rỉ 2009-10-20 12: 58: 32.078 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Object 0x101821130 của lớp NSCFString autoreleased with no hồ bơi tại chỗ - chỉ rò rỉ 2009-10-20 12: 58: 32.078 Python [2054: 4903] *** __NSAutoreleaseNoPool(): Object 0x101828df0 của lớp NSCFString autorelease' –

2

Bạn nên cung cấp cho một cố gắng để motmot's camiface thư viện từ Andrew Rơm. Nó cũng hoạt động với máy ảnh firewire, nhưng nó cũng hoạt động với thị lực, đó là những gì bạn đang tìm kiếm.

Từ hướng dẫn:

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! cảm ơn cho các liên kết –

+0

bạn có thể thấy một số ví dụ đơn giản trên http://www.incm.cnrs-mrs.fr/LaurentPerrinet/SimpleCellDemo – meduz

+0

đây là thư viện gốc: https://github.com/motmot/libcamiface – dashesy