简体   繁体   English

使用 python 和 OpenCV 与 VideoCapture 深入了解多个网络摄像头捕获

[英]Insight on Multiple Webcam Capture with python and OpenCV vs VideoCapture

I'm experimenting with trying to capture an image from multiple webcams simultaneously (or near-simultaneously).我正在尝试同时(或几乎同时)从多个网络摄像头捕获图像。 I've been playing with OpenCV and with VideoCapture and programming in python.我一直在玩OpenCVVideoCapture并在 python 中编程。 But have some confusion and hoped someone could help explain things...但是有些困惑,希望有人能帮忙解释一下……

To Start, I tried VideoCapture (Markus Gritsch's work found here: http://videocapture.sourceforge.net/ ).首先,我尝试了 VideoCapture(Markus Gritsch 的作品在这里找到: http ://videocapture.sourceforge.net/)。 This is a very easy to use add-in for python.这是一个非常易于使用的 Python 插件。 If I just wanted to capture a simple image.如果我只是想捕捉一个简单的图像。 It works just fine... for the most part.它工作得很好......在大多数情况下。

My setup is 2 cheapie webcams in a USB hub on a single USB port and my laptop's built-in webcam.我的设置是在单个 USB 端口上的 USB 集线器中的 2 个便宜的网络摄像头和我的笔记本电脑的内置网络摄像头。

I have read all about using the same model webcam on the same USB bus and how it may not work, etc. but decided to give it a go.我已经阅读了关于在同一 USB 总线上使用相同型号网络摄像头以及它可能无法工作等的所有内容,但决定试一试。 (I also have some photobooth program that I must have installed eons ago called "Cyberlink YouCam" For some reason, this program "looks" like a camera to both OpenCV and VideoCapture. (我也有一些 photobooth 程序,我必须在很久以前安装它,称为“Cyber​​link YouCam”出于某种原因,这个程序“看起来”像 OpenCV 和 VideoCapture 的相机。

VideoCapture connects to and captures from each camera like this: VideoCapture 像这样连接到每个摄像头并从每个摄像头捕获:

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

With VideoCapture and the setup I described, I can independently capture from all the cameras on my system (4 total, including the YouCam... 0 - 3)使用 VideoCapture 和我描述的设置,我可以从系统上的所有摄像头独立捕获(总共 4 个,包括 YouCam... 0 - 3)

The problem is that this program does not seem to be able to connect to more than one camera at the same time... if I don't close the previous camera instance, it simply freezes and I have to disconnect and reconnect the first webcam from USB to regain access to it.问题是这个程序似乎不能同时连接到多个摄像头……如果我不关闭前一个摄像头实例,它就会死机,我必须断开并重新连接第一个摄像头从 USB 重新获得对它的访问。

This won't work:这行不通:

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

Cam0 will open, but that is the end of it. Cam0 将打开,但这就是它的结束。 Frozen.冷冻。

Another thing with VideoCapture is that on the cheapo webcams, there is a major delay (almost a second) until the picture comes alive... in order to do a successful capture, I had to do something like this: VideoCapture 的另一件事是,在cheapo 网络摄像头上,有一个很大的延迟(几乎一秒钟),直到图片活跃起来……为了成功捕获,我必须做这样的事情:

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

Effectively saving the image twice...有效地保存图像两次...

I wouldn't have minded if the images from each camera were a few milliseconds apart taken in squence我不会介意每台相机的图像是否相隔几毫秒

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

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

#etc.

But the delay was way too much... I thought the delay was the cheap webcams, but I saw a different result with Open CV so it must be VideoCapture's fault.但是延迟太多了......我认为延迟是廉价的网络摄像头,但我看到 Open CV 的不同结果,所以它一定是 VideoCapture 的错。

For one thing, I COULD open more than one camera at the same time with OpenCV... but only of different types.一方面,我可以使用 OpenCV 同时打开多个相机……但只能打开不同类型的相机。 (One of the cheapo cams and my built-in cam... and / or the Cyberlink program) OpenCV seemed to see the 2 cheapo cams on the same USB hub as one (it only turned on one of the cams.) (其中一个便宜的摄像头和我的内置摄像头......和/或 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)

Whereas VideoCapture could see the 2 similar cameras independently, OpenCV could not. VideoCapture 可以独立看到 2 个相似的摄像头,而 OpenCV 则不能。

Anyone know why that would be?有谁知道为什么会这样? How are the two packages interacting with the computer differently that one can determine different cams on the same USB and the other cannot?这两个包如何以不同的方式与计算机交互,一个可以确定同一个 USB 上的不同凸轮,而另一个则不能?

Secondly, OpenCV opened my cheap cams instantaneously... no .75 second delays there.其次,OpenCV 立即打开了我的廉价摄像头……那里没有 0.75 秒的延迟。

Again, I am curious how the two packages (videoCapture vs OpenCV) communicating with the cameras differently from each other?再次,我很好奇这两个包(videoCapture 与 OpenCV)与相机的通信有何不同?

What I am ultimately interested in doing is being able to capture from 2 or 3 cameras at the same time (or close to it, if there were a few milliseconds delay, that is fine).我最终感兴趣的是能够同时从 2 或 3 个摄像头进行捕获(或接近它,如果有几毫秒的延迟,那很好)。 Looks like OpenCV would be the package of choice, however, I am trying to understand better how the software is interacting with the cameras.看起来 OpenCV 将是首选包,但是,我试图更好地了解软件如何与相机交互。

Thank you all for the insight!谢谢大家的洞察!

J J

I can tell you some information about OpenCV , but not about VideoCapture.我可以告诉你一些关于OpenCV 的信息,但不能告诉你关于 VideoCapture 的信息。 I do, however, use VideoCapture for getting nice camera names.但是,我确实使用 VideoCapture 来获取漂亮的相机名称。

I have used OpenCV in python to successfully talk to two cameras at the same time.我在 python 中使用 OpenCV 成功地同时与两个摄像头对话。 In some cases, the two cameras were different, other times they were the same but scientific level so perhaps the drivers were better.在某些情况下,两个摄像头不同,其他时候它们相同但科学水平,所以也许司机更好。 I can't say that having two identical cameras isn't causing you a problem.我不能说拥有两个相同的相机不会给您带来问题。

However, I can say that you are using the old and possibly unmaintained camera API.但是,我可以说您使用的是旧的且可能未维护的相机 API。 Use the new cv2 namespace/API also called VideoCapture.使用新的cv2命名空间/API,称为 VideoCapture。 See OpenCV VideoCapture class python bindings beginning with cv2 .请参阅以cv2开头的OpenCV VideoCapture 类python 绑定。 If you have a new version of OpenCV in your python distribution, it is accessed via import cv2 .如果您的 Python 发行版中有新版本的 OpenCV,则可以通过import cv2访问它。 The old bindingss are in cv2.cv (also note that as of OpenCV 2.4.6, many of the important constants for VideoCapture::get(...) and ::set(...) are only found in cv2.cv , this is supposed to be fixed in the next version)旧的绑定在cv2.cv (另请注意,从 OpenCV 2.4.6 开始, VideoCapture::get(...)::set(...)许多重要常量仅在cv2.cv找到,这应该在下一个版本中修复)

More insight...更多见解...

I can connect to two Logitech WebCams, and capture from them simultaneously on my MacBook Pro (Late 2011) using OpenCV 2.4.7, but not on older MacBook Pro (Late 2009)!我可以连接到两个罗技网络摄像头,并使用 OpenCV 2.4.7 在我的 MacBook Pro(2011 年末)上同时捕获它们,但不能在较旧的 MacBook Pro(2009 年末)上!

Specifically:具体来说:

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

I think the only real news here is that a newer computer with the latest OpenCV works ... at least for me!我认为这里唯一真正的消息是具有最新 OpenCV 的较新计算机可以工作……至少对我来说是这样!

In ALL CASES, I can successfully enumerate ALL cameras as long as I only have one USB camera open at a time.在所有情况下,只要我一次只打开一个 USB 摄像头,我就可以成功枚举所有摄像头。

it's been a while since I worked on this project thanks to work and life getting in the way, as usual...像往常一样,由于工作和生活的阻碍,我已经有一段时间没有参与这个项目了......

I recently built an all new computer running linux and I am at it again - trying to capture input from multiple cameras.我最近构建了一台运行 linux 的全新计算机,我再次尝试 - 尝试捕获来自多个摄像头的输入。 This time I am using 4 decent Microsoft Webcams rather than super cheap cameras...这次我使用了 4 个不错的 Microsoft 网络摄像头,而不是超级便宜的摄像头……

I am, again, able to communicate with all the cameras (I even tried putting them all on the same USB controller via hub and was able to talk to each one independently) - but not simultaneously.我再次能够与所有摄像机通信(我什至尝试通过集线器将它们全部放在同一个 USB 控制器上,并且能够独立地与每个摄像机通信)——但不能同时进行。

This doesn't matter to me so much, as I don't need simultaneous connection to them, however when they are first powered up, the internal shutters have to open and adjust and the auto-focus has to adjust...这对我来说并不重要,因为我不需要同时连接它们,但是当它们第一次通电时,内部快门必须打开并调整,自动对焦必须调整......

I am trying the camera library of Pygame and the time my script takes to open the camera, grab the frame and save it is not enough time for the cameras to ready-themselves and thus my captures images are either dark (or half dark) and out of focus.我正在尝试 Pygame 的相机库,而我的脚本打开相机、抓取帧并保存它所花费的时间不足以让相机自行准备好,因此我捕获的图像要么是暗的(或半暗的)和失焦。

I was using OpenCV (which I am going back to trying now) was able to communicate with the cameras at the same time (the lights on all 4 cams were on at the same time) which I am HOPING means that I can "Turn them on" in advance and then capture the frames as I need them.我正在使用 OpenCV(我现在要回去尝试)能够同时与相机通信(所有 4 个摄像头上的灯都同时打开),我希望这意味着我可以“打开它们”提前打开”,然后根据需要捕获帧。 Right now I am able to see live video from each camera (not at the same time, but I can test them individually by changing the device number) but unfortunately, since I put this project down for a while, I forgot some of the code I need to do more with it without running into errors so I have to do some work on it.现在我可以看到每个摄像头的实时视频(不是同时,但我可以通过更改设备号来单独测试它们)但不幸的是,由于我把这个项目搁置了一段时间,我忘记了一些代码我需要用它做更多的事情而不会遇到错误,所以我必须做一些工作。

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

I haven't tried this code yet, but I like the idea that this person added "throw away frames" to allow the camera time to adjust itself.我还没有尝试过这个代码,但我喜欢这个人添加“丢弃帧”以允许相机有时间自行调整的想法。 My aim is to have the camera on continuously, and then simply take the photo (capture the frame) when I press a key or something.我的目标是让相机持续开启,然后在我按下某个键或其他东西时简单地拍照(捕获框架)。

J J

A FEW MORE UPDATES:更多更新:

Using OpenCV, I am able to connect to as many as 5 webcams simultaneously (4 Microsoft and one Logitech) when each one is connected on a different USB controller (the motherboard I'm using seems to have 8 and I have 6 USB ports, currently).使用 OpenCV,当每个网络摄像头连接到不同的 USB 控制器时,我可以同时连接多达 5 个网络摄像头(4 个 Microsoft 和一个 Logitech)(我使用的主板似乎有 8 个,而我有 6 个 USB 端口,目前)。 But when I connect more than one cam on a single USB controller (ie 2 ports that are on the same controller or using a hub) OpenCV only seems to control one of the two cameras on each controller.但是当我在一个 USB 控制器上连接多个摄像头时(即同一控制器上的 2 个端口或使用集线器)OpenCV 似乎只能控制每个控制器上的两个摄像头之一。

However, using PyGame's camera module, I am able to individually connect to as many as 5 cameras on a single USB controller (connected with a powered hub) however I can not connect to more than one at the same time (this doesn't work even when they are on different USB controllers).但是,使用 PyGame 的摄像头模块,我可以在单个 USB 控制器上单独连接多达 5 个摄像头(通过有源集线器连接),但是我无法同时连接多个摄像头(这不起作用)即使它们位于不同的 USB 控制器上)。 Again, I don't need a live feed from all the cams at the same time, but the cameras require time to set themselves up so without being able to "turn the cameras on" in advance, I can't "snap a picture" worthwhile.同样,我不需要所有摄像头同时进行实时馈送,但摄像头需要时间进行设置,因此无法提前“打开摄像头”,我无法“拍照” "值得。

and it continues...它继续......

I also tinkered with this a bit.我也稍微修改了一下。 I can confirm that you can only do one camera at a time.我可以确认你一次只能做一台相机。 I've tried threading and a myriad of other things, but all failed.我尝试过线程和无数其他事情,但都失败了。

Here's the code I came up with.这是我想出的代码。 Perhaps it will help someone.也许它会帮助某人。 I have a bunch of "test code" in there.我在那里有一堆“测试代码”。 You're welcome to keep going where I left off: https://gist.github.com/dovy/4fe2924ea31869def1e8欢迎你继续我离开的地方: https : //gist.github.com/dovy/4fe2924ea31869def1e8

The code is fully working, you just have to get cv2 installed.代码完全有效,您只需要安装 cv2。 ;) ;)

I think this is a USB bandwidth issue.我认为这是 USB 带宽问题。 Webcams without built in compression use an enormous amount of bandwidth.没有内置压缩的网络摄像头使用大量带宽。 Multiply the width * height of the resolution of the camera by the color depth (for example, 8 bits for 256 colors) by the frame rate to get the number of bits per second (without any USB framing overhead) and you'll see that a single USB2 high-speed (480 megabit/sec) channel can't carry more than 1 HD stream (1280 * 1024 * 8 * 30 fps ~= 314.6 megabits/sec).将相机分辨率的宽度 * 高度乘以颜色深度(例如,256 色为 8 位)乘以帧速率以获得每秒位数(没有任何 USB 帧开销),您将看到单个 USB2 高速(480 兆位/秒)通道不能承载超过 1 个高清流(1280 * 1024 * 8 * 30 fps ~= 314.6 兆位/秒)。 When using a hub, that bandwidth is shared among all the ports.使用集线器时,该带宽在所有端口之间共享。 When the driver goes to open the camera, it will read the bandwidth requirement and refuse to continue if the remaining bandwidth on the USB channel is insufficient.当驱动去打开摄像头时,会读取带宽要求,如果USB通道剩余带宽不足,则拒绝继续。 That's why the first camera you open works, but the subsequent ones fail.这就是为什么您打开的第一台相机可以工作,但随后的相机却失败的原因。 Your choices are to use a lower-resolution camera, move the hi-res camera to a different root hub, or use an H264 or MJPEG compressed camera.您的选择是使用较低分辨率的摄像头、将高分辨率摄像头移至不同的根集线器,或者使用 H264 或 MJPEG 压缩摄像头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM