我目前正在用opencv(3.0)编写一个Python(2.7)边缘检测脚本,到目前为止基本上可以正常工作。
现在我想在程序运行时在我的笔记本电脑相机和第二个网络摄像头之间切换。
所以我将轨道栏实现为交换机,但我不知道如何获取轨迹栏已更改的信息。
正常的getTrackbarPos()还不够,我需要这样的东西:
如果TrackbarHasChanged() - >重启程序 - > cv2.VideoCapture(改变了相机) - > while(true)loop
提前致谢
答案 0 :(得分:1)
你很幸运。实际上,OpenCV轨迹栏中已存在该行为。如果您阅读createTrackbar的文档,您将看到对于python:
cv2.createTrackbar(trackbarName,windowName,value,count,onChange)→无
onChange参数是:
onChange - 指向每次滑块更改位置时要调用的函数的指针。该函数应该原型为void Foo(int,void *); ,其中第一个参数是轨迹栏位置,第二个参数是用户数据(参见下一个参数)。如果回调是NULL指针,则不会调用任何回调,但只更新值。
这基本上意味着你想做什么。而不是检查每个循环的pos,如果它有变化,则进行更改。
重启程序部分有点棘手。据我所知(我可能错了),这在另一个线程中运行,可能会遇到一些竞争条件问题......
这是一些小代码(我无法完全测试,因为我没有网络摄像头)创建了一个轨迹栏,创建了回调函数,更改了相机,并避免了线程问题(我想,你可能当使用cameraToUse和cameraChange时,需要实际使用Lock,才能真正实现线程安全。没有摄像头,它会运行,但是它总会在连接中打印错误。使用相机它实际上可以工作:)
我添加了很多评论,但如果你没有在评论中随意提问
import cv2
import numpy as np
# global variables
amountOfCameras = 3 # how many cameras you want to use
cameraToUse = 0 #initial camera
cameraChange = True #starts true to connect at start up
camera = cv2.VideoCapture() # empty placeholder
# callback function for the tracker, x is the position value
# you may put whatever name in here
def trackerCallback(x):
global cameraToUse
global cameraChange
if cameraToUse != x:
print "I change to this camera", x
cameraToUse = x
cameraChange = True
# function to connect to a camera and replace the videoCapture variable
def connectToCamera():
global cameraChange
global camera
print "Connecting to camera", cameraToUse
camera = cv2.VideoCapture(cameraToUse)
# basic check for connection error
if camera.isOpened():
print "Successfully connected"
else:
print "Error connecting to camera", cameraToUse
cameraChange = False
#initial image with the tracker
img = np.zeros((200,600,3), np.uint8)
cv2.namedWindow('image')
cv2.createTrackbar('Camera','image',0,amountOfCameras-1,trackerCallback)
while(1):
#check if it has to connect to something else
if cameraChange:
connectToCamera()
# if no problems with the current camera, grab a frame
if camera.isOpened():
ret, frame = camera.read()
if ret:
img = frame
# displays the frame, in case of none, displays the previous one
cv2.imshow('image',img)
# if esc button exit
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()