[英]OpenCV VideoCapture only updates after 5 read()s
我有一个非常奇怪的错误,几年来一直困扰着我的研究。 我正在使用 OpenCV2 和 Python 从网络摄像头读取图像数据。 但是,图像滞后 5 帧。 换句话说,对 read() 的每次调用都比实时延迟 5 帧。
我一直在使用的一种绷带修复方法是抓取() 4 帧,然后在每次需要更新图像时读取第 5 帧,但这绝对会扼杀我的表现。
这是我用来显示来自网络摄像头的图像的代码
frame = self.getGoodFrame()
if self.DEBUG:
window = cv2.namedWindow("Angles")
imgHSV = cv2.cvtColor(frame, cv2.cv.CV_BGR2HSV)
... Reseach specific code I shouldn't be giving out here ...
... It finds the center of a few bright colors in an image
if self.DEBUG:
debugImage = numpy.zeros((self.CAMERA_HEIGHT, self.CAMERA_WIDTH), numpy.uint8) #blank image
... Then we draw some stuff to the image to be displayed ...
cv2.imshow("Angles", debugImage)
cv2.waitKey(1)
raw_input()
和 getGoodFrame()
def getGoodFrame(self):
MIN_READS_FOR_GOOD_FRAME = 4
for i in xrange(MIN_READS_FOR_GOOD_FRAME):
successful_read = self.capture.grab()
successful_read, frame = self.capture.read()
if not successful_read:
print "Unable to read from webcam, exiting."
return frame
你会注意到我有一个 raw_input() 调用。 这样我就可以通过在控制台中按几次 enter 来查看需要进行多少次读取。 这表明正好有 5 帧的滞后。
我认为这不是硬件问题,我在使用多个网络摄像头和多个 USB 线时遇到过这种情况。 不过,我还没有尝试在另一台机器上重现该错误。
因此,问题与我的硬件缓冲帧的方式有关。 我从来没有完全了解它,但是我发现的解决方案是非常简单的并行化。 我修改了代码以打开线程并不断更新保存当前帧的变量。 然后,当我需要当前帧时,我只是询问当前该变量是什么。
请注意,由于始终存在缓冲,因此仍然落后5个read()调用,但是由于我正在连续进行read()调用,并且它们都在自己的线程上,所以它是最新的。 这是因为我每秒可以调用许多read()调用。 我得到的图像根本没有明显落后于实时性。
我为此编写的Python类如下。 它不是很好的代码,但是可以工作。 为了正确执行此操作,我将(并且将)添加一些优美的方法来退出无限循环。 它将对我有效,并且将我的图像检测代码的速度提高了100倍以上,这对我来说真是太棒了,也很令人兴奋:)
class webcamImageGetter:
def __init__(self):
self.currentFrame = None
self.CAMERA_WIDTH = #webcam width
self.CAMERA_HEIGHT = #webcam height
self.CAMERA_NUM = 0
self.capture = cv2.VideoCapture(0) #Put in correct capture number here
#OpenCV by default gets a half resolution image so we manually set the correct resolution
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,self.CAMERA_WIDTH)
self.capture.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,self.CAMERA_HEIGHT)
#Starts updating the images in a thread
def start(self):
Thread(target=self.updateFrame, args=()).start()
#Continually updates the frame
def updateFrame(self):
while(True):
ret, self.currentFrame = self.capture.read()
while (self.currentFrame == None): #Continually grab frames until we get a good one
ret, frame = self.capture.read()
def getFrame(self):
return self.currentFrame
要使用此功能,请对其进行初始化,然后在实例上调用start。 这样,以后调用getFrame()时,它将具有来自网络摄像头的最新帧。 哇噢!
默认缓冲区设置为 4.0 而不是 1.0。
要解决这个问题:
帽集(38,1)
参考: https ://docs.opencv.org/4.x/d4/d15/group__videoio__flags__base.html#ga41c5cfa7859ae542b71b1d33bbd4d2b4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.