我的问题:
我正在做我的计算机视觉项目,我用opencv(4.1.2)和python来实现它。
我需要一种更快的方法将阅读帧传递到我的计算机(Ubuntu 18.04 8核i7 3.00GHz内存32 GB)上的图像处理中。cv2.VideoCapture.read()
读取帧(帧大小:720 x1280)将花费大约120~ 140 ms。**这太慢了。**我的处理模块每次运行大约需要40 ms。我们希望25~30 FPS。
以下是目前为止我演示代码:
import cv2
from collections import deque
from time import sleep, time
import threading
class camCapture:
def __init__(self, camID, buffer_size):
self.Frame = deque(maxlen=buffer_size)
self.status = False
self.isstop = False
self.capture = cv2.VideoCapture(camID)
def start(self):
print('camera started!')
t1 = threading.Thread(target=self.queryframe, daemon=True, args=())
t1.start()
def stop(self):
self.isstop = True
print('camera stopped!')
def getframe(self):
print('current buffers : ', len(self.Frame))
return self.Frame.popleft()
def queryframe(self):
while (not self.isstop):
start = time()
self.status, tmp = self.capture.read()
print('read frame processed : ', (time() - start) *1000, 'ms')
self.Frame.append(tmp)
self.capture.release()
cam = camCapture(camID=0, buffer_size=50)
W, H = 1280, 720
cam.capture.set(cv2.CAP_PROP_FRAME_WIDTH, W)
cam.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, H)
# start the reading frame thread
cam.start()
# filling frames
sleep(5)
while True:
frame = cam.getframe() # numpy array shape (720, 1280, 3)
cv2.imshow('video',frame)
sleep( 40 / 1000) # mimic the processing time
if cv2.waitKey(1) == 27:
cv2.destroyAllWindows()
cam.stop()
break
我尝试过:
1.多线程-一个线程只阅读帧,另一个做图像处理的事情。**这不是我想要的。**因为我可以设置一个缓冲区双端队列保存50帧,例如。但帧读取线程的工作速度~帧/130 ms。我的图像处理线程的工作速度~帧/40 ms。然后双端队列刚刚用完。所以我一直在尝试解决方案。但不是我需要的。
1.这个X1 E0 F1 X是我发现的最接近我的问题的讨论。但不幸的是,我尝试了公认的解决方案(讨论下面的两个都有)。
其中一个解决方案(6个大拇指)指出,他可以在他的mac上以1秒的间隔阅读和保存100帧。为什么我的机器无法处理帧读取工作?我错过了什么吗?我的安装使用了conda和pip conda install -c conda-forge opencv
,pip install opencv-python
(是的,我两个都试过了。)
另一个解决方案(1大拇指)使用ffmpeg解决方案。但它似乎与视频文件,但不是相机设备的工作?
1.调整c2.waitKey():该参数仅控制视频显示时的频率。不是解决方案。
然后,我知道我只需要一些关键字跟随。
上面的代码是我目前为止的演示代码,我想要一些方法或指南,使我videoCapture.read()更快。也许是一种方法,使用多线程内的videoCapture对象或其他相机阅读模块。
有什么建议吗?
4条答案
按热度按时间qqrboqgw1#
这来得有点晚,但我想知道这与我的罗技C920高清专业USB相机在Ubuntu 20.04和OpenCV。我试图命令捕捉会话运行全高清@30 FPS,但FPS是波动之间4-5 FPS。
我的相机的捕获格式默认为“YUYV 4:2:2”。无论我如何尝试改变视频捕获设置,OpenCV都没有神奇地改变视频格式以匹配Eidogg.所需的FPS设置。
当我列出我的罗技C920的视频格式时,它显示:
解决方案是手动命令OpenCV捕获设备使用压缩的“MJPG”格式:
vfwfrxfs2#
在我的例子中,我已经这样设置了摄像头(用C++代码):
CAP_PROP_BUFFERSIZE
无关紧要,但CAP_PROP_FPS
必须设置在CAP_PROP_FOURCC
之前。通过这种设置,我的相机fps从5增加到20。
plicqrtu3#
"这是最好的解决方案"
由此
至
我搜索了很多时间,但没有找到最好的解决方案,但这个解决方案的工作速度更快打开cv2视频捕获尝试现在希望对你有用。只是使用
cv2.VideoCapture(0, cv2.CAP_DSHOW)
7xzttuei4#
很长。
我检查了使用以下设置,不知何故,如果你增加帧大小opencv将减少总fps。也许这是一个错误。
1920x1080:每秒画面数:5.0,宽度:1920.0,身高:1080.0,延迟= 150毫秒
https://imgur.com/Vab61cF
1280x720:每秒画面数:10.0,宽度:1280.0,高度:720.0,延迟= 60毫秒
https://imgur.com/QN6tsAO
640x480:每秒画面数:30.0,宽度:640.0,高度:480.0,延迟= 5毫秒
https://imgur.com/RqkWSdK
但是通过使用其他应用程序,如 cheese,我们仍然可以在1920x1080分辨率下获得完整的30fps。请注意,设置CAP_PROP_BUFFERSIZE值也没有帮助。
于是一个问题就出现了:“我们如何克服这一点?"。在这个阶段,你只有两个选择:
1.将帧分辨率降低为640x480
1.使用其他框架
希望这能有所帮助。