Reputation: 43
I'm currently writing a Python (2.7) edge detection script with opencv (3.0) which basically works fine so far.
Now I want to switch between my Laptop camera and a second webcam while the program is running.
So i implemented a trackbar as a switch but i have no idea how to get the information that the trackbar has changed.
The normal getTrackbarPos() isn't enough, i need something like:
if TrackbarHasChanged() -> restart program-> cv2.VideoCapture(changed camera) -> while(true) loop
Thanks in advance
Upvotes: 3
Views: 5322
Reputation: 11420
You are in luck. Actually that behavior already exists in OpenCV trackbar. If you read the documentation of createTrackbar you will see that for python you have:
cv2.createTrackbar(trackbarName, windowName, value, count, onChange) → None
The onChange argument is:
onChange – Pointer to the function to be called every time the slider changes position. This function should be prototyped as void Foo(int,void*); , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only value is updated.
Which basically means what you want to do. Instead of checking the pos every loop, if it has a change do the change.
For the restart the program part it is a little bit tricky. As far as I know (I may be wrong) this runs in another thread, and may get some race condition problem....
Here is some small code (which I cannot test fully, since I don't have a webcam) that creates a trackbar, creates the callback function, changes the camera, and avoid thread problems (I think, you may need to actually use Lock when using cameraToUse and cameraChange, to really be thread-safe). Without camera it runs, however it will always print error in connection. With cameras it may actually work :)
I added a lot of comments, but if you don't get a part feel free to ask in a comment
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()
Upvotes: 5