我在使用python读取相机的帧缓冲区时遇到问题。摄像头(Xenics)通过USB连接,摄像头附带一个dll。我使用ctypes访问这个dll。我使用的代码主要受lantz的python模块(lantz_drivers_xenics)的启发。
dll提供了函数XC_CopyFrameBuffer
,我使用它将帧缓冲区复制到numpy数组。
虽然原则上采集工作正常,但问题是以中等或高速连续读取帧缓冲区。
相机附带的编译软件能够以24 fps的速度读出相机。在我的程序中,我想以每秒5到25帧的速度读取帧缓冲区。但是,我无法达到这个值,因为调用XC_CopyFrameBuffer
函数所需的时间在0到~0.5秒之间变化;通常很低,但是大约每三帧就有0.5秒。
我真正的程序更复杂,使用线程并处理acqired图像。但我已经将代码简化为一个最小的示例,它再现了问题,并附上了它。它的文本和图形输出如下所示。我的问题是:
这是我使用的代码:
import time
import ctypes
import threading
import numpy as np
from numpy.ctypeslib import ndpointer
calibration_file = r"C:\Path\to\some\calibrationfile.xca"
dll = "C:\\Programme\\X-Control\\xcamera.dll"
lib = ctypes.WinDLL(dll) #for xcamera we need ctypes.WinDLL
exposure_time = 300 #microseconds (us)
readlock = threading.Lock()
#add types
lib.XC_OpenCamera.argtypes = [ctypes.c_uint]
lib.XC_CloseCamera.argtypes = [ctypes.c_uint]
lib.XC_IsInitialised.argtypes = [ctypes.c_uint]
lib.XC_LoadFromFile.argtypes = [ctypes.c_uint, ctypes.c_char_p]
lib.XC_LoadCalibrationPack.argtypes = [ctypes.c_uint, ctypes.c_char_p]
lib.XC_SetGainCamera.argtypes = [ctypes.c_uint, ctypes.c_double]
lib.XC_SetIntegrationTime.argtypes = [ctypes.c_uint, ctypes.c_ulong]
lib.XC_SetFan.argtypes = [ctypes.c_uint, ctypes.c_bool]
lib.XC_StartCapture.argtypes = [ctypes.c_uint]
lib.XC_StopCapture.argtypes = [ctypes.c_uint]
lib.XC_GetFrameSizeInBytes.argtypes = [ctypes.c_uint]
lib.XC_CloseCamera.restype = ctypes.c_void_p
lib.XC_StopCapture.restype = ctypes.c_void_p
xcamera_id = lib.XC_OpenCamera(0)
#lib.XC_LoadFromFile(xcamera_id, self.config_file)
lib.XC_LoadCalibrationPack(xcamera_id, calibration_file)
height = lib.XC_GetHeight(xcamera_id)
width = lib.XC_GetWidth(xcamera_id)
shape = (height, width)
lib.XC_CopyFrameBuffer.argtypes = [ctypes.c_uint, ndpointer(dtype=np.uint16, shape=shape),ctypes.c_uint]
frame_size = lib.XC_GetFrameSizeInBytes(xcamera_id)
fbuffer = np.zeros(shape=shape, dtype=np.uint16)
lib.XC_SetIntegrationTime(xcamera_id, exposure_time)
lib.XC_SetFan(xcamera_id, True)
lib.XC_StartCapture(xcamera_id)
times = []
for i in range(150):
time.sleep( exposure_time/1000000. ) # 1./25
if readlock.acquire() :
start_time = time.time()
(lib.XC_CopyFrameBuffer(xcamera_id, fbuffer, frame_size) )
#time.sleep(0.0002)
now = time.time()
readlock.release()
print "Frame {nr}\ttime: {time}".format(time=now-start_time, nr=i)
times.append(now-start_time)
else:
time.sleep(0.001)
print "Try again" #This gets never printed, so readlock works fine.
###### CLOSING ###########
lib.XC_StopCapture(xcamera_id)
lib.XC_SetFan(xcamera_id, False)
lib.XC_CloseCamera(xcamera_id)
###### Plot ###########
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(121)
ax.imshow(fbuffer, interpolation="none")
ax2 = fig.add_subplot(122)
ax2.plot(times)
plt.savefig("testing/readout.png")
plt.show()
典型的输出如下所示,其中time是复制帧缓冲区所需的时间。
^{pr2}$绘制的图形是这样的(图像看起来就像它应该的那样)。右图显示每帧的时间(以秒为单位)
评论:
time.sleep(x)
可以增加读取0.5秒的帧数。睡眠时间越长,帧读取的时间就越长。在time.sleep( exposure_time/1000000. )
提供空帧。在readlock.acquire()
无关。在
目前没有回答
相关问题 更多 >
编程相关推荐