访问 opencv 回调函数之外的变量

时间:2021-01-02 23:15:37

标签: python opencv variables callback scope

我正在使用 OpenCV 根据其 RGB 值跟踪图像的一部分并使用 cv2.setMouseCallback

这是我的代码:

def track_ground():
    b_min, g_min, r_min = 255, 255, 255
    b_max, g_max, r_max = 0, 0, 0
    
    ##########################################
    # mouse callback function
    def get_pixel(event,x,y,flags,param):

        if event == cv2.EVENT_MOUSEMOVE:
            b, g, r = img[x, y]
            # We are moving around the mouse to find the range of values for rgb
            # of the background; we will use them for thresholding later.

            b_min = min(b, b_min)
            g_min = min(g, g_min)
            r_min = min(r, r_min)
            b_max = max(b, b_max)
            g_max = max(g, g_max)
            r_max = max(r, r_max)

    
    img = cv2.imread('data/my_image.jpg')
    cv2.namedWindow('image')
    cv2.setMouseCallback('image',get_pixel)
    while True:
        cv2.imshow('image',img)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()
    
    ###########################################
    
    print('min:', b_min, g_min, r_min)
    print('max:', b_max, g_max, r_max)
    
    return (b_min, g_min, r_min), (b_max, g_max, r_max)

这个想法是我想获得变量b_ming_minr_minb_max、{{1}的最小值和最大值R、G、B像素}}, g_max 当我在图像的特定部分移动鼠标时。为此,我使用了 'cv2.setMouseCallbackr_maxget_pixel`,它应该在移动鼠标的 x、y 点位置保持 RGB 像素的最小值/最大值。

现在有一个与回调函数之外的变量可访问性相关的错误,它说: and the callback function

我如何访问和修改这些变量?

2 个答案:

答案 0 :(得分:2)

我在函数之外使用了 bgr minmax 变量,并使用 release-test 关键字在 track_groundget_pixel 函数的范围内使用它们。我还将您的显示代码更改为仅显示一次图像,在窗口打开时打印最小最大值,并在窗口上按下“X”时结束 while 循环。

代码:

global

我在这张图片上进行了测试,它似乎有效:enter image description here

答案 1 :(得分:1)

一种解决方案是将 param 参数用于 get_pixel 回调函数,以便将数据传递给主函数 track_ground

import cv2
import numpy as np
from pprint import pprint


# mouse callback function
def get_pixel(event,x,y,flags,param):

    if event == cv2.EVENT_MOUSEMOVE:
        img = param['img']
        b, g, r = img[x, y]
        # We are moving around the mouse to find the range of values for rgb
        # of the background; we will use them for thresholding later.
        
        cv2.circle(img, (x, y), 1, (0, 0, 255), 2)
        
        param['b_min'] = min(b, param['b_min'])
        param['g_min'] = min(g, param['g_min'])
        param['r_min'] = min(r, param['r_min'])
        param['b_max'] = max(b, param['b_max'])
        param['g_max'] = max(g, param['g_max'])
        param['r_max'] = max(r, param['r_max'])
        
        rgb_minmax = param.copy()
        del rgb_minmax['img']
        pprint(rgb_minmax)

def track_ground():
    
    ##########################################

    
    img = cv2.imread('data/my_image.jpg')
    cv2.namedWindow('image')
    param = {
        'img': img,
        'b_min': 255,
        'g_min': 255,
        'r_min': 255,
        'b_max': 0,
        'g_max': 0,
        'r_max': 0
    }
    cv2.setMouseCallback('image',get_pixel, param)
    while True:
        cv2.imshow('image',img)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()
    
    ###########################################
    
    print('min:', param['b_min'], param['g_min'], param['r_min'])
    print('max:', param['b_max'], param['g_max'], param['r_max'])
    
    return param

可能有其他更好的解决方案吗?