Python3,cv2.setMouseCallback()和cv2.MouseCallback()参数void * userdata

时间:2020-10-04 18:15:05

标签: python opencv

我的python3程序使用OpenCV4(cv2)将一系列蒙版应用于图像。总的来说,我最初将字符串myMask设置为字符串“ none”。我想将此变量传递到我的鼠标事件处理程序中。每个事件处理程序都绑定到一个窗口,该窗口显示黑白蒙版图像之一,并带有一个以...,void *用户数据结尾的参数字符串。事件处理程序响应EVENT_LBUTTONDOWN。然后,选定的事件处理程序将用户数据参数更改为唯一字符串。我希望main中的变量myMask反映上一个鼠标事件处理程序中所做的更改。不幸的是,myMask的主体从未改变。为什么?任何帮助将不胜感激。这是OpenCV的两个摘录以及部分代码:

§MouseCallback typedef void(* cv :: MouseCallback)(int事件,int x,int y,int标志,void * userdata) #include

鼠标事件的回调函数。参见cv :: setMouseCallback。

参数 cv :: MouseEventTypes常量之一的事件。 x鼠标事件的x坐标。 y鼠标事件的y坐标。 标记cv :: MouseEventFlags常量之一。 userdata可选参数。

§setMouseCallback() void cv :: setMouseCallback(const String&winname, MouseCallback onMouse, 无效*用户数据= 0 )
#include

设置指定窗口的鼠标处理程序。

参数 winname窗口名称。 鼠标事件的onMouse回调函数。有关如何指定和使用回调的信息,请参见OpenCV示例。 userdata传递给回调的可选参数。

# BW MouseCallback funcs
myMask = 'none'  # Mask to apply
# One Callback func per window
# BW none Callback
def mouseHandler( event, x, y, flags, userdata ):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        userdata = 'none'
# BW halfBlack Callback
def mouseHandlerHB( event, x, y, flags, userdata ):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        userdata = 'halfBlack'
# BW centreWhite Callback
def mouseHandlerCW( event, x, y, flags, userdata ):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        userdata = 'centreWhite'
# BW bitAnd Callback
def mouseHandlerBA( event, x, y, flags, userdata ):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        userdata = 'bitAnd'
# BW bitOr Callback
def mouseHandlerBO( event, x, y, flags, userdata ):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        userdata = 'bitOr'
# BW bitXor Callback
def mouseHandlerBX( event, x, y, flags, userdata ):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        userdata  = 'bitXor'
# BW setMouseCallbacks, tie Callback func to a window
cv2.setMouseCallback( 'piCamR', mouseHandler, myMask )
cv2.setMouseCallback( 'halfBlack', mouseHandlerHB, myMask )
cv2.setMouseCallback( 'centreWhite', mouseHandlerCW, myMask )
cv2.setMouseCallback( 'bitAnd', mouseHandlerBA, myMask )
cv2.setMouseCallback( 'bitOr', mouseHandlerBO, myMask )
cv2.setMouseCallback( 'bitXor', mouseHandlerBX, myMask )

while True:

    # Grab a frame
    ret, frame1 = cam.read()
    print(myMask)
    # BW Apply mask?
    if myMask != 'none':
        if myMask == 'halfBlack':
            frame1 = cv2.bitwise_and( frame1, frame1, mask = halfBlack )
        elif myMask == 'centreWhite':
            frame1 = cv2.bitwise_and( frame1, frame1, mask = centreWhite )
        elif myMask == 'bitAnd':
            frame1 = cv2.bitwise_and( frame1, frame1, mask = bitAnd )
        elif myMask == 'bitOr':
            frame1 = cv2.bitwise_and( frame1, frame1, mask = bitOr )
        else:  # myMask == bitXor
            frame1 = cv2.bitwise_and( frame1, frame1, mask = bitXor )
    # Show frame and position
    cv2.imshow( 'piCamR', frame1)

1 个答案:

答案 0 :(得分:0)

您正在尝试修改全局变量,这有两种可能(我将在下面为1个处理程序编写代码段,而您只需要复制):

  1. 始终修改相同的全局变量:
myMask = 'none'
def mouseHandler(event, x, y, flags):  # in this case, no need for userdata
  global myMask  # this is important
  if event == 1:
    myMask = 'none'
cv2.setMouseCallback('piCamR', mouseHandler)
  1. 通过名称修改全局变量:
myMask = 'none'
def mouseHandler(event, x, y, flags, userdata: str):  # userdata would be a string
  if event == 1:
    globals()[userdata] = 'none'
cv2.setMouseCallback('piCamR', mouseHandler, 'myMask')  # pass the variable name as str
  1. 使用遮罩传递对象:
class MyMasks:
  def __init__(self):
    self.myMask = 'none'

def mouseHandler(event, x, y, flags, userdata: MyMasks):  # userdata would be an instance of MyMasks
    if event == 1:
        userdata.myMask = 'none'

mymasks = MyMasks()  # instantiate your masks
cv2.setMouseCallback('piCamR', mouseHandler, mymasks)  # pass the object