使用OpenCV和Python显示摄像头画面
我一直在尝试用Python写一个简单的程序,利用OpenCV从我的摄像头获取视频流,并在屏幕上显示出来。
我知道我已经完成了一部分,因为窗口已经创建,摄像头的指示灯也亮了,但窗口里就是不显示任何东西。希望有人能告诉我我哪里做错了。
import cv
cv.NamedWindow("w1", cv.CV_WINDOW_AUTOSIZE)
capture = cv.CaptureFromCAM(0)
def repeat():
frame = cv.QueryFrame(capture)
cv.ShowImage("w1", frame)
while True:
repeat()
另外,我注意到我的摄像头有时候会改变它在cv.CaptureFromCAM
中的索引号,有时候我需要输入0、1或2,尽管我只连接了一台摄像头,而且没有拔掉它(我知道,因为只有在我改变索引时,灯才会亮)。有没有办法让Python自动确定正确的索引呢?
6 个回答
8
如果你只有一台摄像头,或者你不在乎哪一台摄像头是正确的,那就用“-1”作为索引。比如在你的例子中,可以这样写:capture = cv.CaptureFromCAM(-1)
。
83
这里有个更新,告诉大家在最近版本的OpenCV中怎么做:
import cv2
cv2.namedWindow("preview")
vc = cv2.VideoCapture(0)
if vc.isOpened(): # try to get the first frame
rval, frame = vc.read()
else:
rval = False
while rval:
cv2.imshow("preview", frame)
rval, frame = vc.read()
key = cv2.waitKey(20)
if key == 27: # exit on ESC
break
cv2.destroyWindow("preview")
vc.release()
在我这边,OpenCV-2.4.2可以正常工作。
42
试着在你的 repeat()
方法的最后加上一行 c = cv.WaitKey(10)
。
这行代码会让程序等待10毫秒,看看用户是否按下了键。即使你根本不打算用到这个按键,也可以加上这行。我觉得可能需要一些延迟,所以 time.sleep(10)
也许可以达到同样的效果。
关于摄像头的索引,你可以这样做:
for i in range(3):
capture = cv.CaptureFromCAM(i)
if capture: break
这段代码会找到第一个“正常工作”的捕捉设备的索引,至少在索引范围0到2内是这样。你的电脑里可能有多个设备被识别为合适的捕捉设备。确认你选对了哪个设备的唯一方法就是手动查看你的灯光。也许可以获取一张图片,然后检查它的属性?
为了在这个过程中添加用户提示,你可以在你的重复循环中绑定一个按键来切换摄像头:
import cv
cv.NamedWindow("w1", cv.CV_WINDOW_AUTOSIZE)
camera_index = 0
capture = cv.CaptureFromCAM(camera_index)
def repeat():
global capture #declare as globals since we are assigning to them now
global camera_index
frame = cv.QueryFrame(capture)
cv.ShowImage("w1", frame)
c = cv.WaitKey(10)
if(c=="n"): #in "n" key is pressed while the popup window is in focus
camera_index += 1 #try the next camera index
capture = cv.CaptureFromCAM(camera_index)
if not capture: #if the next camera index didn't work, reset to 0.
camera_index = 0
capture = cv.CaptureFromCAM(camera_index)
while True:
repeat()
免责声明:我没有测试过这个,所以可能会有bug或者根本不工作,但至少可以给你一个解决方法的思路。