洞察使用 python 和 OpenCV 与 VideoCapture 进行多网络摄像头捕获

Posted

技术标签:

【中文标题】洞察使用 python 和 OpenCV 与 VideoCapture 进行多网络摄像头捕获【英文标题】:Insight on Multiple Webcam Capture with python and OpenCV vs VideoCapture 【发布时间】:2013-11-16 18:29:54 【问题描述】:

我正在尝试同时(或几乎同时)从多个网络摄像头捕获图像。我一直在玩 OpenCVVideoCapture 并在 python 中编程。但是有些困惑,希望有人能帮忙解释一下……

首先,我尝试了 VideoCapture(Markus Gritsch 的作品在这里找到:http://videocapture.sourceforge.net/)。 这是一个非常易于使用的python插件。如果我只是想捕捉一个简单的图像。它工作得很好......在大多数情况下。

我的设置是单个 USB 端口上的 USB 集线器中的 2 个便宜的网络摄像头和我笔记本电脑的内置网络摄像头。

我已阅读有关在同一 USB 总线上使用同一型号网络摄像头以及它可能无法正常工作等的所有内容,但我决定试一试。 (我还有一些我必须在很久以前安装的 photobooth 程序,称为“Cyber​​link YouCam”。出于某种原因,这个程序“看起来”像 OpenCV 和 VideoCapture 的相机。

VideoCapture 像这样连接到每个摄像头并从每个摄像头捕获:

Cam0 = Device(devnum=0)
Cam0.saveSnapshot("filename0.jpg")
del Cam0
Cam1 = Device(devnum=1)
Cam1.saveSnapshot("filename1.jpg")
del Cam1

使用 VideoCapture 和我描述的设置,我可以独立地从我系统上的所有摄像头(总共 4 个,包括 YouCam... 0 - 3)进行捕捉

问题是这个程序似乎不能同时连接到多个摄像头...如果我不关闭前一个摄像头实例,它只会冻结,我必须断开连接并重新连接第一个从 USB 重新获得访问权限的网络摄像头。

这行不通:

cam0 = Device(devnum=0)
cam1 = Device(devnum=1)
cam0.saveSnapshot("filename0.jpg")
cam1.saveSnapshot("filename1.jpg")
del cam0
del cam1

Cam0 将打开,但这就是它的结束。冷冻。

VideoCapture 的另一件事是,在便宜的网络摄像头上,有一个很大的延迟(几乎一秒钟),直到图片变为现实......为了成功捕捉,我必须做这样的事情:

Cam1 = Device(devnum=1)
Cam1.saveSnapshot("filename1.jpg") #gets the camera going and saves black image
time.sleep(.75) #delay
Cam1.saveSnapshot("filename1.jpg") #captures the image second time around

有效地保存图像两次...

如果每台相机的图像间隔几毫秒按顺序拍摄,我不会介意

#open connection to cam, take image
#close connection to cam

#connect to next cam, take next image
#close connection to cam

#etc.

但是延迟太多了...我认为延迟是便宜的网络摄像头,但我看到 Open CV 的结果不同,所以一定是 VideoCapture 的错。

一方面,我可以使用 OpenCV 同时打开多个摄像头……但只能是不同类型的摄像头。 (其中一个便宜的摄像头和我的内置摄像头......和/或 Cyber​​link 程序)OpenCV 似乎在同一个 USB 集线器上看到了两个便宜的摄像头(它只打开了一个摄像头。)

capture0 = CaptureFromCAM(0) #this was Cyberlink Program
capture1 = CaptureFromCAM(1) #this was cheapo cam
capture2 = CaptureFromCAM(2) #this was built-in cam
#CaptureFromCAM(3) resulted in error... did not find a 4th "camera"

frame0 = QueryFrame(capure0)
frame1 = QueryFrame(capure1)
frame2 = QueryFrame(capure2)
cv.SaveImage("filename0.jpg",frame0)
cv.SaveImage("filename1.jpg",frame1)
cv.SaveImage("filename2.jpg",frame2)

VideoCapture 可以独立地看到 2 个相似的摄像头,而 OpenCV 则不能。

有人知道为什么会这样吗?这两个包与计算机的交互有何不同,一个可以确定同一个 USB 上的不同摄像头而另一个不能?

其次,OpenCV 立即打开了我的廉价摄像头……没有 0.75 秒的延迟。

再次,我很好奇这两个包(videoCapture 与 OpenCV)与摄像机的通信有何不同?

我最终感兴趣的是能够同时从 2 或 3 个摄像头捕获(或接近它,如果有几毫秒的延迟,那很好)。看起来 OpenCV 将是首选包,但是,我正在尝试更好地了解该软件如何与相机交互。

感谢大家的见解!

J

【问题讨论】:

最后,你能用多个 IDENTICAL 相机拍摄 snapshopt 吗? 很遗憾,我有一段时间没有机会继续从事这个项目了。我计划在月底之前恢复它,当我有一些停机时间时。当我找到一些结果时,我会发布我的结果。 J 看看Python OpenCV streaming from camera - multithreading, timestamps、How to capture multiple camera streams with OpenCV和Video Streaming from IP Camera in Python Using OpenCV cv2.VideoCapture 【参考方案1】:

我可以告诉你一些关于OpenCV 的信息,但不能告诉你VideoCapture。但是,我确实使用 VideoCapture 来获得漂亮的相机名称。

我在 python 中使用 OpenCV 成功地同时与两个摄像头对话。在某些情况下,这两个摄像头是不同的,有时它们是相同的但科学水平,所以也许司机更好。我不能说拥有两个相同的相机不会给您带来问题。

但是,我可以说您使用的是并且可能未维护的相机 API。使用名为 VideoCapture 的新 cv2 命名空间/API 。请参阅以cv2 开头的OpenCV VideoCapture class python 绑定。如果您的 Python 发行版中有新版本的 OpenCV,可以通过 import cv2 访问它。旧的绑定在 cv2.cv 中(另请注意,从 OpenCV 2.4.6 开始,VideoCapture::get(...)::set(...) 的许多重要常量只能在 cv2.cv 中找到,这应该会在下一个版本中修复)

【讨论】:

您好,感谢您的意见(抱歉耽搁了)。我正在使用较新的 CV2。我没有机会重新审视这个项目,因为我最近一直在帮助朋友做其他事情。我将订购几个不同的网络摄像头,看看在接下来的几周内我能产生什么样的结果。 -J【参考方案2】:

更多见解...

我可以连接到两个罗技网络摄像头,并在我的 MacBook Pro(2011 年末)上使用 OpenCV 2.4.7 同时捕捉它们,但不能在旧款 MacBook Pro(2009 年末)上!

具体来说:

MacBook Pro 2011 -- 
WORKS: 2 x SAME MODEL plugged into SEPARATE USB Ports
FAILS: 2 x SAME MDOEL plugged into SAME USB Port (via a hub)
WORKS: 1 x SAME MODEL plugged into HUB and 1 x SAME MODEL plugged into laptop directly

MacBook Pro 2009 --
WORKS: 2 x DIFFERENT MODELS plugged into SEPARATE USB Ports
FAILS: 2 x SAME MANUFACTURER (!) plugged into SEPARATE USB Ports
FAILS: 2 x SAME MODEL

我认为这里唯一真正的消息是一台装有最新 OpenCV 的较新计算机工作...至少对我来说!

在所有情况下,只要我一次只打开一个 USB 摄像头,我就可以成功枚举所有摄像头。

【讨论】:

更多见解 - 在旧机器上,使用相同型号的网络摄像头,我可以从 OpenCV 访问一个,使用 PhotoBooth 访问一个。【参考方案3】:

由于工作和生活的阻碍,我已经有一段时间没有参与这个项目了,像往常一样......

我最近构建了一台运行 linux 的全新计算机,我又开始使用它了 - 尝试从多个摄像头捕获输入。这次我使用的是 4 个不错的 Microsoft 网络摄像头,而不是超级便宜的摄像头……

我再次能够与所有相机进行通信(我什至尝试通过集线器将它们全部放在同一个 USB 控制器上,并且能够独立地与每个相机进行通信)——但不能同时进行。

这对我来说并不重要,因为我不需要同时连接它们,但是当它们第一次通电时,内部快门必须打开并调整,自动对焦必须调整.. .

我正在尝试 Pygame 的相机库,而我的脚本打开相机、抓取帧并保存它所花费的时间不足以让相机自行准备好,因此我捕获的图像要么是暗的(要么是一半黑暗)和失焦。

我使用 OpenCV(我现在要回去尝试)能够同时与摄像机通信(所有 4 个摄像机上的灯同时亮起),我希望这意味着我可以提前“打开它们”,然后根据需要捕获帧。现在我可以看到来自每台摄像机的实时视频(不是同时,但我可以通过更改设备编号来单独测试它们)但不幸的是,因为我把这个项目搁置了一段时间,我忘记了一些代码我需要在不出错的情况下做更多的事情,所以我必须做一些工作。

与此同时,我刚刚在网上找到了这个: http://codeplasma.com/2012/12/03/getting-webcam-images-with-python-and-opencv-2-for-real-this-time/

我还没有尝试过这段代码,但我喜欢这个人添加“丢弃帧”以让相机有时间自行调整的想法。我的目标是让相机连续打开,然后当我按下一个键或其他东西时简单地拍照(捕捉框架)。

J

更多更新:

使用 OpenCV,当每个网络摄像头连接到不同的 USB 控制器(我使用的主板似乎有 8 个而我有 6 个)时,我可以同时连接多达 5 个网络摄像头(4 个 Microsoft 和一个 Logitech) USB 端口,目前)。但是当我在一个 USB 控制器上连接多个摄像头时(即在同一个控制器上或使用集线器的 2 个端口),OpenCV 似乎只能控制每个控制器上的两个摄像头之一。

但是,使用 PyGame 的摄像头模块,我可以在单个 USB 控制器(通过有源集线器连接)上单独连接多达 5 个摄像头,但是我不能同时连接多个摄像头(这不会即使它们在不同的 USB 控制器上也不起作用)。同样,我不需要同时来自所有摄像头的实时信息,但是摄像头需要时间来设置自己,因此无法提前“打开摄像头”,我无法“拍照” "值得。

然后继续……

【讨论】:

【参考方案4】:

我也对此进行了一些修改。我可以确认您一次只能做一台相机。我已经尝试过线程和无数其他的东西,但都失败了。

这是我想出的代码。也许它会帮助某人。我在那里有一堆“测试代码”。欢迎你继续我离开的地方:https://gist.github.com/dovy/4fe2924ea31869def1e8

代码完全可以运行,您只需要安装 cv2。 ;)

【讨论】:

P.S.为大约 25 个网络摄像头拍摄一张照片大约需要 30 秒。 :)【参考方案5】:

我认为这是 USB 带宽问题。没有内置压缩功能的网络摄像头会占用大量带宽。将相机分辨率的宽度 * 高度乘以颜色深度(例如,256 色的 8 位)乘以帧速率,得到每秒的位数(没有任何 USB 帧开销),您会看到单个 USB2 高速(480 兆比特/秒)通道不能传输超过 1 个高清流(1280 * 1024 * 8 * 30 fps ~= 314.6 兆比特/秒)。使用集线器时,该带宽在所有端口之间共享。当驱动程序去打开相机时,它会读取带宽需求,如果USB通道上剩余的带宽不足则拒绝继续。这就是为什么您打开的第一台相机有效,但随后的相机却失败了。您可以选择使用分辨率较低的摄像头、将高分辨率摄像头移至不同的根集线器,或者使用 H264 或 MJPEG 压缩摄像头。

【讨论】:

您好,感谢您的回复。自从

以上是关于洞察使用 python 和 OpenCV 与 VideoCapture 进行多网络摄像头捕获的主要内容,如果未能解决你的问题,请参考以下文章

我们可以使用 Python 创建数据洞察报告吗? [关闭]

使用 H264 编解码器将视频保存在 opencv 中

将 GPU 与 opencv-python 一起使用

python-OpenCV 使用GrabCut来实现图片的前景与后景的分割

python+opencv实现摄像头的调用

Rraspberry Pi 4B python3 安装opencv