简体   繁体   English

OpenCV Python跟踪栏回调

[英]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. 我目前正在用opencv(3.0)编写Python(2.7)边缘检测脚本,到目前为止到目前为止工作正常。

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: 普通的getTrackbarPos()是不够的,我需要这样的东西:

if TrackbarHasChanged() -> restart program-> cv2.VideoCapture(changed camera) -> while(true) loop 如果TrackbarHasChanged()->重新启动程序-> cv2.VideoCapture(更改的摄像头)-> while(true)循环

Thanks in advance 提前致谢

You are in luck. 你真幸运。 Actually that behavior already exists in OpenCV trackbar. 实际上,该行为已经存在于OpenCV跟踪栏中。 If you read the documentation of createTrackbar you will see that for python you have: 如果您阅读createTrackbar的文档,则将看到python的内容:

cv2.createTrackbar(trackbarName, windowName, value, count, onChange) → None cv2.createTrackbar(trackbarName,windowName,value,count,onChange)→无

The onChange argument is: onChange参数为:

onChange – Pointer to the function to be called every time the slider changes position. onChange –指向每次滑块更改位置时要调用的函数的指针。 This function should be prototyped as void Foo(int,void*); 此函数的原型应为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. 如果回调是NULL指针,则不调用任何回调,而仅更新值。

Which basically means what you want to do. 这基本上意味着您想要做什么。 Instead of checking the pos every loop, if it has a change do the change. 如果有变化,则不要检查pos每个循环,而要进行更改。

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). 这是一些小代码(由于没有网络摄像头,所以我无法完全测试),可以创建轨迹栏,创建回调函数,更改摄像头并避免线程问题(我认为,您可能需要实际使用Lock当使用cameraToUse和cameraChange时,实际上是线程安全的)。 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()

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

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