[英]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.