简体   繁体   English

如何使用回调 function 避免全局变量

[英]How can I avoid global variable with callback function

I want to have the label_image() code into a function that is initialized with an image, ie , label_image(image) .我想将label_image()代码放入用图像初始化的 function 中,label_image(image) Right now, if I do not declare the image as global variable, it does not properly update because of the callback function having image as global vs label_image(image) having a local copy of image .现在,如果我没有将图像声明为全局变量,它不会正确更新,因为回调 function 将image作为全局变量,而label_image(image)具有image的本地副本。 Also, despite the callback function click() being initialized inside label_image() , it cannot see the variable image unless it is declared globally.此外,尽管在label_image() click() ) ,但它无法看到变量image ,除非它被全局声明。 I guess my problem would be easily solved if I could pass image to click() which then would be able to update the same copy that label_image(image) received.我想我的问题会很容易解决,如果我可以将image传递给click() ,然后它就能够更新label_image(image)收到的同一个副本。 So far, I didn't find anyway to do so as the callback function expects the 5 parameters event, x, y, flags, param ...到目前为止,我还没有找到这样做的回调 function 需要 5 个参数event, x, y, flags, param ...

def click(event, x, y, flags, param):
        global click_pts, image_storage, image
        if event == cv2.EVENT_LBUTTONDOWN:
            click_pts.append((x, y, 1))
            cv2.circle(image, (x, y), 5, (255, 0, 0), -1)
            image_storage = lshift(image_storage, image)
            cv2.imshow("image", image_storage[-1])
            print('added %(n)s, size %(s)s, type %(t)s' % {'n': (x, y), 's': len(click_pts), 't': 1})
        elif event == cv2.EVENT_RBUTTONDOWN:
            click_pts.append((x, y, 2))
            cv2.circle(image, (x, y), 5, (0, 255, 255), -1)
            image_storage = lshift(image_storage, image)
            cv2.imshow("image", image_storage[-1])
            print('added %(n)s, size %(s)s, type %(t)s' % {'n': (x, y), 's': len(click_pts), 't': 2})


def label_image() -> list:
    global click_pts, image_storage, image
    click_pts = []
    image_storage = np.zeros((10,) + image.shape, np.uint8)
    image_storage[:] = np.ndarray.copy(image)
    cv2.namedWindow('image', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('image', 1400, 1400)
    cv2.setMouseCallback("image", click)

    # Loop until 'q' is pressed
    while True:
        cv2.imshow("image", image_storage[-1])
        key = cv2.waitKey(1) & 0xFF
        if key == ord('q'):
            break
        elif key == ord('b'):
            try:
                print('removed: %(n)s, size %(s)s' % {'n': click_pts[-1], 's': len(click_pts)})
                click_pts.pop()
            except IndexError:
                print('the array is empty')
            image_storage = rshift(image_storage)
            image = np.ndarray.copy(image_storage[-1])
            cv2.imshow("image", image_storage[-1])

    cv2.destroyAllWindows()
    return click_pts

image = cv2.imread('someimage.png')
label_image()

Given that you want to end up calling this:鉴于你想最终调用这个:

def click(image, event, x, y, flags, param):

so that we are passing in image as the first parameter, we can make a partial function which has the image parameter on the front already, leaving the callback code to apply the normal event, x, y, flags, param params just as normal.因此我们将image作为第一个参数传入,我们可以制作一个partial function,它的前面已经有image参数,让回调代码像平常一样应用正常的event, x, y, flags, param参数。

This means making a partial for the callback:这意味着为回调制作partial内容:

def label_image():
    # all the usual stuff elided ...

    partial_click = partial(click, image)  # here image is applied first
    cv2.setMouseCallback("image", partial_click)

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

相关问题 如何在函数中定义全局变量? - How can I define a global variable in a function? 如何在导入的函数中访问全局变量 - How can I access a global variable in a function I'm importing Python:如何避免在通过 function 传递全局变量时对其进行更新? - Python: How do I avoid my global variable from being updated when passing it through a function? 如何从函数中引用全局变量? - How can I reference a global variable from within a function? 如何在不覆盖其他作业的值的情况下从多处理回调中更新全局变量? - how can I update a global variable from a multiprocessing callback without overriding the value for other jobs? 如何在不使用回调 function 的情况下使用输入框定义全局变量? - How define a global variable with an input box without using a callback function? 将二叉树转换为双向链表。 如何避免在此处使用全局变量? - Convert Binary Tree to doubly linked list. How can I avoid using global variable here? 如何在函数中使用 LOCAL VARIABLE,就像其他函数的 GLOBAL VARIABLE 变量 - How can I use LOCAL VARIABLE in function, like a GLOBAL VARIABLE variable for other function 如何避免在此递归函数中使用全局变量并改善代码? - How to avoid using a global variable in this recursion function and improve my code? 如何避免声明全局变量? - How to avoid declaring a global variable?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM