Jn_M
Jn_M

Reputation: 43

OpenCV Python Trackbar Callback

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

Answers (1)

api55
api55

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

Related Questions